2d点聚类

时间:2010-10-14 21:16:43

标签: algorithm geometry

给定:给定2D平面中的一组N个点(x和y坐标),以及对应于每个点的一组N个半径。我们将参考一个点的光盘,因为光盘以其半径为中心点。

问题:对点进行聚类。点簇使得每个点EITHER落入簇中至少一个其他点的盘内,或者簇中的至少一个其它点落入其盘内。单点集群不算作集群。

我需要一种算法来有效地计算它(最好不要求助于复杂的空间哈希技术,如kd树)。我可以满足O(N ^ 2)运行时间但绝对不超过O(N ^ 3)。我觉得这应该很简单但是我已经陷入了我的聚类条件的非互惠性质。

本质上,我希望填写C函数原型:

int cluster_points(
    size_t n,
    point_t *pt, // length n list of points
    double *radius, // length n list of radii for each point
    int *cluster, // length n list of cluster indexes; -1 if not clustered
    size_t *ncluster // number of clusters (number of distinct non -1 entries in cluster)
);

这不是作业。我需要这个作为矩阵算法的一部分来聚类复数。

5 个答案:

答案 0 :(得分:10)

蛮力解决方案只有O(N 2 ),所以它应该适合你。

1)从未分配群组中的所有点开始。

2)选择一个点并查看未分配组中的所有其他点,看看是否符合您描述的半径标准。

  • 2a)如果是,请启动一个群组,继续使用所有其他点,看看它们是否适合此群组(根据您当前的点数),如果它们适合,请移动他们从未分配的小组进入这个新小组。
  • 2ab)完成当前点后,转到添加到组中的每个点并检查未分配组中的所有点。
  • 2b)但是,如果没有点符合当前点的半径标准,则丢弃它。

3)最后,您将按照您的标准对点进行分组,并且不会进行N *(N / 2)次检查。

顺便说一句,你所描述的并不是“聚类”通常所指的,所以我认为这会让人们离开这里。使聚类成为难题的原因在于,两个相邻点是否将被分配给同一聚类的问题由数据集中的所有其他点确定。在你的情况下,它(基本上)只由两点的属性决定,所以在你的情况下,你可以只检查它们。

答案 1 :(得分:3)

k-means聚类基于局部搜索和Lloyd算法的组合

http://www.cs.umd.edu/~mount/Projects/KMeans/
(程序在GNU通用公共许可证的条件下分发。)

k-means,k-medians,k-medoids,treecluster,自组织映射,clustercentroids,clusterdistance http://bonsai.hgc.jp/~mdehoon/software/cluster/cluster.pdf

答案 2 :(得分:2)

即使您获得了先验的簇数,群集也是NP-Hard问题,因此您可能放弃获取多项式运行时间。有许多技术可以做到这一点,文献主要在机器学习社区中找到,k-means可能是最容易理解和实现的算法。

答案 3 :(得分:2)

听起来明显的O(n ^ 2)算法是创建一个以点为顶点的图形,然后在满足条件时连接两个点。然后你读掉图表的连通组件,丢弃单身人士。此外,您为聚类声明的条件对我来说是对称的。我错过了什么吗?

答案 4 :(得分:2)

你有一对U(p,R)的集合,其中p是一个点,R是它的半径。

关于U的关系:(p,R)〜(q,S)< => p位于q的盘中或q位于p的盘中< => | P-Q | < = max(R,S)

显然是反身和对称的,所以它的传递闭包(〜,比如说)是等价关系。 〜下的等价类将是(单例或)聚类。

我相信有一些标准算法来计算像上面这样的关系的传递闭包的等价类。例如,这在“数字食谱”中关于排序的章节中进行了讨论,他们说他们的例程基于Knuth。

(很抱歉不提供链接,但简短的搜索没有找到正确的内容)。