【问题标题】:Space partitioning algorithm空间划分算法
【发布时间】:2011-06-24 01:48:42
【问题描述】:

我有一组包含在矩形内的点。我想根据点密度将矩形拆分为子矩形(给出多个子矩形或所需的密度,以最简单的为准)。

分区不必精确(几乎任何比常规网格更好的近似值),但算法必须处理大量点 - 大约。 2亿。然而,所需的子矩形数量要少得多(大约 1000 个)。

有谁知道任何可以帮助我完成这项特定任务的算法?

【问题讨论】:

  • 你想要(大约)每个子矩形中相同数量的点吗?我认为你有,但并不完全清楚。
  • 是的,我希望每个子区域的点数相同。
  • 如果不限制矩形的形式,问题是一维的,你只需要切割一个点数相同的线段(点的x坐标)。在我看来,您忘记了一些“拓扑”限制
  • 是的,贝利撒留,你是对的。我希望矩形在空间上彼此靠近,因此将初始矩形切成垂直或水平条纹不是我想要的。
  • 你想要一个不均匀的网格,还是只是一组互斥的覆盖矩形?

标签: algorithm space-partitioning


【解决方案1】:

只是为了理解问题。 以下是粗制滥造,表现不佳,但我想知道结果是不是你想要的>

假设>矩形的个数是偶数
假设>点分布明显2D(一行没有大的积累)

程序>
在任一轴上平分 n/2 次,从每个先前确定的矩形的一端循环到另一端,计算“通过”点并在每次迭代中存储通过点的数量。计数后,将矩形按每个循环中计数的点一分为二。

这是你想要达到的目标吗?

【讨论】:

  • 是的,完全正确。那将是完美的。我正在考虑最初创建一个矩阵(1000x1000 左右)并在每个单元格中存储点数。然后我可以使用你的二分算法。
【解决方案2】:

我想我会从以下内容开始,这与@belisarius 已经提出的内容很接近。如果您有任何其他要求,例如更喜欢“接近方形”的矩形而不是“又长又薄”的矩形,则需要修改这种幼稚的方法。为简单起见,我假设这些点大致是随机分布的。

  1. 用一条平行于矩形短边并正好穿过中点的线将初始矩形一分为二。
  2. 计算两个半矩形中的点数。如果它们相等(足够),则转到第 4 步。否则,转到第 3 步。
  3. 根据半矩形之间的点分布情况,移动线以使事物再次变平。因此,如果第一次切割将点分割为 1/3、2/3,则将线的一半移动到矩形的较重的一半。转至第 2 步。(小心不要被困在此处,以不断递减的步长移动线,先向一个方向移动,然后再向另一个方向移动。)
  4. 现在,在第 1 步将每个半矩形传递给此函数的递归调用。

我希望这足以很好地概述提案。它有局限性:它会产生一些等于 2 的幂的矩形,所以如果这还不够好,请调整它。我已经递归地表达了它,但它是并行化的理想选择。每次拆分创建两个任务,每个任务拆分一个矩形并再创建两个任务。

如果您不喜欢这种方法,也许您可​​以从一个常规网格开始,其中包含您想要的矩形数量的倍数(可能是 10 到 100 个)。计算每个小矩形中的点数。然后开始将小矩形粘合在一起,直到较小的矩形包含(大约)正确数量的点。或者,如果它足够好地满足您的要求,您可以将其用作离散化方法并将其与我的第一种方法集成,但仅将切割线放置在小矩形的边界上。这可能会快得多,因为您只需计算每个小矩形中的点一次。

我还没有真正考虑过其中任何一个的运行时间;我更喜欢前一种方法,因为我进行了大量并行编程并且拥有大量处理器。

【讨论】:

  • 再想一想,总结两个答案,切割薄片矩形等价于一维问题。所以,如果你有 N 个点和 r 个矩形,只需考虑点的 x 坐标,然后在每个分区中求和 N/r 个点
【解决方案3】:

我想你是在追求标准的 Kd 树或二进制空间分区树。 (你可以在维基百科上查到。)

由于您有很多点,您可能希望仅大致划分前几个级别。在这种情况下,您应该从 200M 个点中随机抽取一个样本(可能是其中的 200k 个),然后在子样本的中点(沿着较长的轴)拆分整个数据集。如果您实际上是随机选择点,那么您错过大量需要细分的点的概率大约为零。

现在你有两个问题,每个问题大约 100M 点。沿着较长的轴划分每个。重复直到您停止抽取子样本并沿整个数据集进行拆分。十次广度优先迭代后,您将完成。

如果您有不同的问题 - 您必须提供沿 X 和 Y 轴的刻度线并尽可能沿这些刻度线填充网格,而不是对 Kd 树进行不规则分解 - 获取您的子样本的点并找到沿每个轴的 0/32、1/32、...、32/32 百分位数。在那里画出你的网格线,然后用你的点填充生成的 1024 元素网格。

【讨论】:

  • 也许我错过了 kd-trees 的点,但它们似乎没有像问题所述那样创建带有点在矩形内的矩形。第二条评论说他正在寻找矩形内相同数量的点。该参考资料包含许多我认为可能有用的其他参考资料。
  • @Grembo - 这是一个小的实现细节,可以切换到 between 点而不是 on 点。
  • KD-Tree 确实也是我的第一个反应,起初我犹豫了,因为集合很大,但抽样方法缓解了这个问题。
【解决方案4】:

【讨论】:

  • -1:R-tree 不是一种算法,它是一种数据结构,您没有提出填充 R-tree 的算法。
  • @HPM,如果你看看我识别的页面,搜索标题算法,你会很满意。
【解决方案5】:

好问题。

我认为您需要研究的领域是“计算几何”和“k 分区”问题。有一个链接可以帮助您入门 here

您可能会发现问题本身是 NP 难的,这意味着一个好的近似算法是您将得到的最好的。

【讨论】:

  • 发帖人要求对点进行均分,而不是最小化或最大化交互。后者可以是 NP 难的(例如图最大切割);前者是O(n log n)
【解决方案6】:

K-means clusteringVoronoi diagram 是否适合您要解决的问题?

【讨论】:

    【解决方案7】:

    看起来像Cluster analysis

    【讨论】:

    • 一般来说你是对的——这是一个聚类分析问题。但这是一个非常不寻常的问题,所以我认为集群分析工具箱中的现成方法不会有用。我只对矩形感兴趣 - 不是任何簇,我有很多对象,我不太关心精度。
    【解决方案8】:

    QuadTree 有用吗?

    四叉树是一种树数据结构,其中每个内部节点正好有四个子节点。四叉树最常用于通过递归地将二维空间细分为四个象限或区域来划分二维空间。这些区域可以是正方形或矩形,或者可以具有任意形状。这种数据结构在 1974 年被 Raphael Finkel 和 J.L. Bentley 命名为四叉树。类似的划分也称为 Q-tree。所有形式的四叉树都有一些共同特征:

    • 它们将空间分解为可适应的细胞
    • 每个单元(或桶)都有一个最大容量。当达到最大容量时,桶会分裂
    • 树目录遵循四叉树的空间分解

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      相关资源
      最近更新 更多