我的算法对于聚类很简单,它就是这样。GPU中的对象聚类
第一个对象被所有其他对象组成,它们之间的距离越低X. 然后我们转到第二个对象,如果没有包含在第一个组中,我们对其他对象运行相同的算法不包括在第一组, 等等......
我想在GPU中使用片段着色器做这个算法。 首先,我将所有位置设置为RGBA浮动纹理。为每个像素设置位置(x,y) - z和w现在是空闲的。然后我使用着色器绘制结果纹理我的计算结果。最后,我将读取结果纹理的像素并执行我的代码。
尝试了很多代码的变化,并且为了执行我的算法绘制了多个阶段,但我对时间表现并不满意。
问题是, 有没有办法让一个人跑过纹理来执行我的愿望(单绘制阶段)?
我最新的尝试是这样的算法 - 我的片段着色器
precision highp float;
uniform sampler2D locs;
varying vec2 coord;
uniform float clusterDistance;
const float textureSize = 64.;
void main()
{
// Getting my location
vec4 currData = texture2D(locs, coord);
float offsetPix = 1./textureSize/2.;
vec2 coordIdx = (coord - offsetPix) * textureSize;
// Getting the index of my location
float myIdx = coordIdx.y * textureSize + coordIdx.x;
int clusterIdx = 0;
float clusterNum = 0.;
// Running over all the other locations until me and finding the first close object to me
for (float i=0.;i<textureSize*textureSize;++i)
{
clusterNum = i +1.;
// Which mean that we didn't find any closed object to me so we stop
if (i == myIdx)
{
break;
}
else
{
vec2 pntLoc = vec2(mod(i, textureSize), floor(i/textureSize))/textureSize+offsetPix;
vec4 pnt = texture2D(locs, pntLoc);
if (distance(currData.xy, pnt.xy) <= clusterDistance)
{
break;
}
}
}
// Print the result
gl_FragColor = vec4(currData.x, currData.y, clusterNum, 1.);
}
但这里的问题是,结果可能会导致链集群。例如。如果我们的数据是{0,0},{4,0},{8,0},并且组的最大距离是4,那么我们的数据是第一个数据库。然后第一个数据库关闭到第二个数据库。然后第三个接近第二个但不是第一个。根据我的算法,它返回的是第二个索引,尽管第二个索引不在图片中,因为它是按第一个对象分组的,而第一个是距离的参考对象。
在写入结果纹理时可以读取结果纹理吗?
这将解决我的问题,因为那样比较距离时,我可以检查结果的Z值..
有关从外观上的突破的良好信息。不知道。对于我知道的其他问题。这种情况是否存在适合GPU的不同算法。关于K-means,我已经考虑过了,但我的客户希望根据距离而不是群体数量来建立群集。 (如果我正确理解K-means) –
K-means的确使用距离作为基础,但它也需要你定义起始质心(聚类中心,你可以随机选择一个数据点)。还有其他的算法,但我必须承认,我不认识他们。 编辑:你可能想看看[this](https://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set),尤其是引言。 –