【问题标题】:Clustering 2d integer coordinates into sets of at most N points将二维整数坐标聚类为最多 N 个点的集合
【发布时间】:2011-12-30 01:01:57
【问题描述】:

我在一个相对较小的二维网格上有许多点,它在两个维度上都环绕。坐标只能是整数。我需要将它们分成最多 N 个靠近在一起的点的集合,其中 N 将是一个很小的截止点,我怀疑最多 10 个。

我正在为游戏设计一个 AI,并且我 99% 确定在所有游戏片段上使用极小极大可以让我获得大约 1 步的可用预测,如果这样的话。但是远距离的棋子应该不会相互影响,直到我们通过大量的移动向前看,所以我想一次将游戏划分为N个子游戏的多个子游戏。但是,我需要确保一次选择合理的 N 件,即靠近在一起的件。

我不在乎异常值是自己留下还是与距离最短的集群混为一谈。分解大于 N 的自然集群是不可避免的,只需要在某种程度上是合理的。因为这是在响应时间有限的游戏 AI 中使用的,所以我正在寻找尽可能快的算法,并愿意在准确性与性能之间进行权衡。

有人对算法进行调整有什么建议吗? K-means 和亲戚似乎不合适,因为我不知道我想找到多少个集群,但我对我想要多大的集群有一个限制。我已经看到一些证据表明通过将点捕捉到网格来近似解决方案可以帮助一些聚类算法,所以我希望整数坐标可以使问题更容易。基于层次距离的聚类将很容易适应环绕坐标,因为我只是插入了不同的距离函数,并且也相对容易限制聚类的大小。我还有什么其他的想法吗?

我对算法比对库更感兴趣,尽管欢迎有关于其工作原理的良好文档的库。

编辑:我最初在为Fall 2011 AI Challenge 编写条目时提出了这个问题,遗憾的是我从未完成。我链接到的页面对游戏有相当简短的高层次描述。

两个关键点是:

  1. 每个玩家都有潜在的大量蚂蚁
  2. 每只蚂蚁每转一圈,向北、向南、向东或向西移动 1 个方格;这意味着游戏的分支因子为 O(4ants)。

在比赛中,每个机器人的回合也有严格的时间限制。我曾想过通过使用极小极大来接近游戏(回合实际上是同时的,但作为一种启发式,我认为这还可以),但我担心如果我考虑整个游戏,就没有时间向前看很多动作立刻。但是由于每只蚂蚁每回合只移动一格,因此两只蚂蚁不能通过最短路径相隔 N 个空间,因此可能会相互干扰,直到我们向前看 N/2 次移动。

因此,我正在寻找的解决方案是一次选择较小的蚂蚁组并分别选择每个组的最小最大蚂蚁的好方法。我曾希望这能让我在不损失太多准确性的情况下更深入地搜索移动树。但显然,使用非常昂贵的聚类算法作为一种节省时间的启发式算法是没有意义的!

我仍然对这个问题的答案很感兴趣,尽管我可以从这些技术中学到的东西比这次特定的比赛更多,因为它已经结束了!感谢到目前为止的所有答案。

【问题讨论】:

  • 网格有多大? 10“关闭”是否意味着所有相邻或有间隙,例如围棋板上的组?
  • 网格不同。我相信它多达数百个。接近我的意思是理想地彼此接近,而不是与不在分区中的部分接近。如果板上只有 10 块,一个隔板可以覆盖整个板。但如果有 20 个团块,则必须分成两组,每组 10 个;不应该有一个包含一些丛和一些更远的部分的组。
  • 我认为你应该发布更多关于游戏规则以及棋子如何相互作用的细节。您首先需要创建这些组的假设可能是不正确的。
  • 有多少只蚂蚁?进行O(n^2) 设置听起来还不错,如果它将第二步从O(4^n) 减少到O(4^sqrt(n)) 左右。
  • @ThomasAhle 蚂蚁的数量在技术上是无限的。比赛主页ants.aichallenge.org有一个随机游戏的flash可视化;我刚刚看到的那只蚂蚁接近 300 只。

标签: algorithm cluster-analysis


【解决方案1】:

在您的网格上构建一个图 G=(V, E) 并将其划分。 由于您对算法而不是库感兴趣,因此这是最近的一篇论文:

Daniel Delling、Andrew V. Goldberg、Ilya Razenshteyn 和 Renato F. Werneck。图分区与自然割。第 25 届国际并行和分布式处理研讨会 (IPDPS’11)。 IEEE计算机 社会,2011。[PDF]

来自正文:

图划分问题的目标是找到一个最小成本划分P,使得每个单元的大小都以U为界。

所以你将设置 U=10。

【讨论】:

    【解决方案2】:

    中值切割算法在 2D 中实现起来非常简单,在这里可以很好地工作。您的异常值最终会以 1 为一组,您可以丢弃或其他什么。

    要求进一步解释: 中值切割是一种量化算法,但所有量化算法都是特殊情况的聚类算法。在这种情况下,算法非常简单:找到包含所有点的最小边界框,沿最长边分割框(并缩小以适应点),重复直到达到目标框数。

    A more detailed description and coded example

    Wiki on color quantization has some good visuals and links

    【讨论】:

    • 因简单性和指向现有算法而获得奖励。没有明确满足“最多 N 个点的集合”的要求,但可以对其进行调整。
    • 想在这里解释一下算法,或者至少提供一些参考吗?
    • @IvoFlipse 添加了简要说明和一些链接
    【解决方案3】:

    您可以计算最小生成树并删除最长的边。然后你可以计算k-means。移除另一个长边并计算 k-means。冲洗并重复,直到 N=10。我相信这个算法被命名为单链接 k-means 并且集群类似于 voronoi 图:

    “单链k-clustering算法......正是Kruskal算法......相当于找到一个MST并删除k-1个最昂贵的边。”

    请参见此处的示例:https://stats.stackexchange.com/questions/1475/visualization-software-for-clustering

    【讨论】:

      【解决方案4】:

      由于您正在编写一个游戏,其中(我假设)每个集群之间只有恒定数量的棋子移动,您可以利用 在线 算法来获得恒定的更新时间。

      我相信,不将自己锁定在多个集群中的特性称为非平稳

      本文结合了上述两个属性的良好算法:Improving the Robustness of 'Online Agglomerative Clustering Method' Based on Kernel-Induce Distance Measures(您也可以在其他地方找到它)。

      这是a nice video showing 正在工作的算法:

      【讨论】:

      • 好像不符合每簇点数上限的要求。
      • 不,可能不是一个明确的上限,但如果你调整参数,如果更多的点实际上不是相互重叠,你应该能够低于任何 N。
      【解决方案5】:

      考虑您只需要两个集群的情况。如果你运行k-means,那么你会得到两个点,两个簇之间的划分是一个与两个簇中心之间的线正交的平面。您可以通过将点向下投影到直线上然后将其在直线上的位置与阈值进行比较来找出它所在的集群(例如,从两个集群中心和点中的任何一个获取直线和向量之间的点积)。

      对于两个集群,这意味着您可以通过移动阈值来调整集群的大小。您可以沿连接两个聚类中心的线对距离上的点进行排序,然后很容易地沿线移动阈值,用聚类的整齐程度来权衡分割的不等式。

      您可能没有 k=2,但您可以分层运行,方法是分成两个集群,然后再细分集群。

      (评论后)

      我不擅长图片,但这里有一些相关的代数。

      使用 k-means,我们根据点与聚类中心的距离来划分点,因此对于一个点 Xi 和两个中心 Ai 和 Bi,我们可能会感兴趣

      SUM_i (Xi - Ai)^2 - SUM_i(Xi - Bi)^2

      这是 SUM_i Ai^2 - SUM_i Bi^2 + 2 SUM_i (Bi - Ai)Xi

      因此,根据 K + 2(B - A).X 的符号将一个点分配给任一簇 - 一个常数加上指向该点的向量与连接两个簇圆的向量之间的点积。在二维中,平面上最终在一个聚类中的点与平面上最终在另一个聚类中的点之间的分界线是垂直于两个聚类中心之间的线的线。我的建议是,为了控制划分后的点数,您计算 (B - A).X 为每个点 X,然后选择一个阈值,将一个集群中的所有点与另一个集群中的所有点分开簇。这相当于在两个聚类中心之间的线上上下滑动分界线,同时保持与它们之间的线垂直。

      一旦你有了点积 Yi,其中 Yi = SUM_j (Bj - Aj) Xij,衡量一个聚类的紧密程度的指标是 SUM_i (Yi - Ym)^2,其中 Ym 是簇。我建议您使用两个集群的这些值的总和来判断您的拆分有多好。要将一个点移入或移出集群并获得新的平方和,而无需从头开始重新计算所有内容,请注意 SUM_i (Si + T)^2 = SUM_i Si^2 + 2T SUM_i Si + T^2,所以如果你跟踪总和和平方和,当您向每个组件添加或减去一个值时,您可以计算出平方和会发生什么,因为当您向其添加或删除一个点时,集群的平均值会发生变化。

      【讨论】:

      • @modowella:你想如何细分集群?减半?
      • 在每个阶段,我都会看看可能的拆分有多好,然后选择最合理的拆分。如果 N=10 并且我有 100 分,我可能会检查 10/90、20/80、.. 80/20、90/100,也许还有一些接近这些的点,例如 11/89。衡量分割有多好的一种方法可能是沿着集群中心线从每个点到分割中心的平方距离之和。我没有任何理论来支持这一点,所以你最好在真实数据上尝试多种可能性,看看是否有特别好的或坏的。
      • @modowella:它看起来像一个树图算法。也许是 r 树?
      • 我不认为与 r-trees 的比较特别有用,因为 r-trees 是为最近邻搜索之类的事情而设计的,这里不需要。它让我想起了一些 en.wikipedia.org/wiki/Decision_tree_learning 算法,但它们往往不是基于 k-means 构建的。使用 k-means 或其他重新分割算法的分裂聚类本身就是一种已知的方法,尽管不是特别流行的方法。
      • 非常感谢您的快速回复。我不是指 r-tree,而是 kd-tree。这个度量是线性的吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 2010-11-10
      • 2021-10-21
      • 2019-04-14
      • 2016-04-10
      相关资源
      最近更新 更多