我有一个大小为n
的2D数组,代表3D空间中的n
个点数,{1}}用于XYZ(例如position[][]
为position[0][0]
, X
为Y,position[0][1]
为点0的Z坐标。
我需要做的是对点进行群集,以便拥有position[0][2]
个大小为n/k
的群集,以便每个群集都包含最近的k
点在3D空间中。例如,如果k
和n=100
,我希望有20个5点的簇,它们是空间中最近的邻居。
我怎样才能实现这一目标? (我需要伪代码。对于最好用Java的代码片段)
到目前为止,我所做的是基于每个组件的简单排序。但这确实 NOT 给了我最近的邻居。
k=5
)position[0][0]
)position[0][1]
)
position[0][2]
我认为我的问题与使用kd-trees 的最近邻搜索略有不同,因为每次迭代中的邻居不应与其他迭代重叠。我想我们可能需要将它作为一个组件使用,但这是怎么回事。
答案 0 :(得分:1)
一开始你没有八叉树,而是点数列表,而不是:
float position[n][3];
因此,为了简化群集和八叉树创建,您可以使用3D点密度贴图。它类似于创建直方图:
计算积分O(n)
所以处理所有点并确定最小和最大坐标。
创建密度图O(max(m^3,n))
因此,将使用过的空间(bbox)划分为一些3D体素网格(使用您想要/需要的分辨率),可以像以下一样进行密度映射:
int map[m][m][m]`
用零清除它。
for (int x=0;x<m;x++)
for (int y=0;y<m;y++)
for (int z=0;z<m;z++)
map[x][y][z]=0;
然后处理所有点从x,y,z
确定其单元格位置并递增它。
for (int i=0;i<n;i++)
{
int x=(m-1)*(position[i][0]-xmin)/(xmax-xmin);
int y=(m-1)*(position[i][1]-ymin)/(ymax-ymin);
int z=(m-1)*(position[i][2]-zmin)/(zmax-zmin);
map[x][y][z]++;
// here you can add point i into octree belonging to leaf representing this cell
}
这将为您提供低密度密度图。单元格map[x][y][z]
中的数字越大,其中的点越多,这意味着群集就在那里,您也可以将点移动到八叉树中的该群集。
对于具有足够点的单元格,可以递归地重复此操作。要使您的八叉树创建密度图2x2x2
并递归地拆分每个单元格,直到其计数较小,则阈值或单元格大小太小。
有关详细信息,请参阅类似的 QAs
答案 1 :(得分:0)
你不是什么聚类。根据你的说法,我认为你想要将你的N点划分为N / k组,每组有k个点,同时保持每个簇中的点在3D空间中最接近。
想想一个简单的例子,如果你想在一维上做同样的事情,也就是说,只是对数字进行排序,第一个k点进入集群1,第二个k指向集群2,依此类推。 / p>
然后返回3D空间问题,答案是一样的。首先找到具有最小x轴,y轴和z轴的点,总共将其最接近的k-1点放入簇1中。然后对于最小点,找到最小x轴,y轴和z-轴点和k-1最近点未聚集到群集2中,依此类推。
上面的过程会得到你的结果,但这在实践中可能没有意义,也许集群算法如k-means可以帮助你。