【问题标题】:2d point clustering二维点聚类
【发布时间】:2010-10-14 21:16:42
【问题描述】:

给定: 给定二维平面上的一组 N 个点(x 和 y 坐标),以及每个点对应的一组 N 个半径。我们将一个点的圆盘称为以该点为中心并以其半径为中心的圆盘。

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

我需要一种算法来有效地计算这个(最好不要求助于复杂的空间散列技术,如 kd-trees)。我可以满足 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)
);

这不是家庭作业。我需要它作为矩阵算法的一部分,用于对复数进行聚类。

【问题讨论】:

    标签: algorithm geometry


    【解决方案1】:

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

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

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

    • 2a) 如果是,则开始一个小组,然后继续处理所有其他点,看看他们是否适合这个小组(基于您当前的点),如果他们适合,将它们从未分配的组进入这个新组。
    • 2ab) 完成当前点后,转到添加到组中的每个点并检查未分配组中的所有点。
    • 2b) 但是,如果没有点与当前点的半径标准匹配,则丢弃它。

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

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

    【讨论】:

    • 在第 2ab 步中,您是否不必继续查看所有添加的点并查看其余未分配的点,直到没有分配新的点?
    • @VictorLiu:我不这么认为。使用此方法,一旦您建立了第 1 组(并移至第 2 组),第 1 组将包含所有符合条件的点,并且将永远属于该组。定义组 1 时,每次向其中添加一个点时,都会扫描所有其他点以查看它们现在是否可能在组中。比如说,一旦第 1 组成立,您就不需要加入第 1 组和第 2 组。
    【解决方案2】:

    基于局部搜索和劳埃德算法相结合的k-means聚类

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

    k-means、k-median、k-medoids、treecluster、自组织图、clustercentroids、clusterdistance http://bonsai.hgc.jp/~mdehoon/software/cluster/cluster.pdf

    【讨论】:

    • k-means 不是一个选项。我想要上面描述的精确包含指标。
    【解决方案3】:

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

    【讨论】:

    • 我不认为我的意思是集群。您可以想象,如果所有半径都相同,您可以遍历所有对并确定这些对是否应该在一个集群中。这定义了集群关系图的关联矩阵。之后,您只需要找到图形的连通分量(我不是在寻找派系)。我相信这一切都是多项式时间。
    • 好的,这有点帮助,但我仍然不是 100% 清楚你在寻找什么。我主要想知道你想如何限制集群的大小或数量,即是什么阻止我总是声明所有点都在同一个集群中(假设它是完全连接的)。
    • 好的,用几何图形描绘这个。我在平面上有一堆点,每个点都有一个指定的半径,所以实际上我在平面上放置了一堆圆盘。我想找到所有正在接触的圆盘组;簇是它们的圆盘重叠以在平面中形成更大的非圆形区域(可能带有孔)的点。集群的大小或数量没有限制;如果半径都为零,则没有簇。如果半径都很大,那么只有一个簇。
    • 哦,我明白了,这是一个范围搜索。通过简单地迭代每对点,显然有一个 O(n^2) 算法。如果你想更快,你必须使用更复杂的数据结构(kd-trees)。
    • 如果条件是光盘接触,那么匹配标准不是不对称的——test(A,B) 总是等于 test(B,A)。如果条件是圆盘的中心在另一个圆盘的半径内,则匹配标准可以是不对称的。我认为这就是您在上面所说的“非互惠”。那么,您想要哪个标准?对称标准还是不对称标准?
    【解决方案4】:

    听起来很明显的 O(n^2) 算法是创建一个以点为顶点的图形,然后如果满足您给出的条件,则连接两个点。然后你读取图表的连接组件,丢弃单例。此外,您为聚类提供的条件对我来说听起来是对称的。我错过了什么吗?

    【讨论】:

    • 我希望在 O(1) 空间中做到这一点,但做显而易见的事情可能会更直接。集群条件是对称的,但对于双循环实现,则不是。
    【解决方案5】:

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

    U 上的关系 ~ : (p,R) ~ (q,S) p 位于 q 的圆盘或 q 位于 p 的圆盘 |p-q|

    显然是自反和对称的,因此它的传递闭包(~,比如说)是一种等价关系。 ~ 下的等价类将是(单例或)集群。

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

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

    【讨论】:

      猜你喜欢
      • 2017-08-16
      • 2021-12-21
      • 1970-01-01
      • 2019-04-28
      • 2011-12-30
      • 2018-04-24
      • 2020-10-07
      • 1970-01-01
      • 2016-08-24
      相关资源
      最近更新 更多