【问题标题】:How to break a geometry into blocks?如何将几何体分解成块?
【发布时间】:2015-06-03 22:21:13
【问题描述】:

我确定已经有一些算法可以满足我的需要,但我不确定 Google 需要什么短语,或者算法类别是什么。

这是我的问题:我有一个由多个接触块(超实验室)组成的多面体,即。 e.边缘是轴对齐的,边缘之间的角度是 90°。多面体内部可能有孔。

我想把这个凹多面体分解成尽可能少的凸矩形轴对齐的整个块(如果原始多面体是凸的并且没有孔,那么它已经是这样一个块,因此,解决方案)。为了说明,我制作了一些 2-D 图像(但我需要 3-D 的解决方案,最好是 N-D):

我有这个几何形状:

一个可能的块分解是这样的:

但我想要的是这个(尽可能少的块):

我的印象是精确算法可能过于昂贵(这个问题是 NP 难的吗?),所以近似算法是合适的。

一个可能使问题更容易的细节,以便可以有一个更合适/专门的算法是所有边的大小都是某个固定值的倍数(您可能认为所有边的大小都是整数,或者几何由均匀的小方块或体素组成。

背景:这是 PDE 域的结构化网格离散化。

什么算法可以解决这个问题?我应该使用哪类算法 搜索?

【问题讨论】:

  • 是否知道给定形状的边缘是否与 X 和 Y 轴对齐?
  • 是的,是的。我在那里写的方式是:“......边缘是轴对齐的......”你错过了吗?不清楚吗?
  • 这里有一个非常相似的问题没有答案,但是它确实提到了各种方法。 stackoverflow.com/questions/17749067/…
  • 您输入的格式是什么?填充单元格列表? CSG树? BSP树?还有什么?
  • 不完全是这样,但你可能会说它是体素中心的列表。所有体素大小相同。

标签: algorithm computational-geometry partitioning


【解决方案1】:

更新:在您对该答案投赞成票之前,我想指出我的回答有点离题。原始海报有一个关于分解具有轴对齐面的多面体的问题。鉴于这种多面体,问题是将其分解为凸部分。问题在于 3D,可能是 nD。我的答案是关于一般多面体的分解。因此,当我给出给定实现的答案时,该答案适用于多面体轴对齐的特殊情况,但可能存在轴对齐多面体的更好实现。当我的回答说通用多面体的问题是 NP 完全的时,可能存在针对轴对齐多面体的特殊情况的多项式解决方案。我不知道。

现在这是我的(稍微偏离主题的)答案,位于水平线下方...


CGAL C++ library 有一个算法,给定一个二维多边形,可以计算该多边形的最优凸分解。该方法在the part 2D Polygon Partitioning of the manual 中提到。该方法名为CGAL::optimal_convex_partition_2。我引用手册:

此函数提供了Greene's dynamic programming algorithm for optimal partitioning[2] 的实现。该算法在最坏情况下需要 O(n4) 时间和 O(n3) 空间。

bibliography of that CGAL chapter中,文章[2]为:

[2] 丹尼尔·H·格林。将多边形分解为凸部分。在 Franco P. Preparata,编辑,计算几何Adv.的第 1 卷。计算。 Res.,第 235-259 页。 JAI 出版社,康涅狄格州格林威治,1983 年。

这似乎正是您正在寻找的。​​p>

请注意,CGAL 手册的同一章还提到了一个近似值,因此不是最优的,它在 O(n) 中运行:CGAL::approx_convex_partition_2

编辑,关于 3D 案例:

在 3D 中,CGAL 有another chapter about Convex Decomposition of Polyhedra。本章的第二段说“这个问题已知是 NP-hard [1]”。参考 [1] 是:

[1] 伯纳德·查泽勒。多面体的凸分区:下界和最坏情况的最优算法。 SIAM J. Comput., 13:488–507, 1984.

CGAL 有一个方法CGAL::convex_decomposition_3 计算非最优分解。

【讨论】:

  • @CortAmmon No. 在 CGAL 中有 another chapter about Convex Decomposition of Polyhedra 在 3D 中。第二段说“这个问题已知是 NP-hard”。
  • @CortAmmon 我已经修改了我的回答来谈论 3D 案例。 dD 也是 NP 难的,CGAL 不提供任何非最优实现。
  • 我喜欢这个答案,但我对分解的限制不仅仅是“凸”分解,我需要轴对齐的超板。所以,在实际意义上,这个答案可能会有所帮助,但我需要研究并尝试修改算法以符合限制(感谢参考)。从理论上讲,恐怕复杂性并不立即明显,因为我的问题受到更多限制,因此可能更容易计算。
  • 好吧,我同意我的回答有点离题。我没有仔细阅读这个问题。
【解决方案2】:

我感觉你的问题是 NP 难的。我建议第一步可能是将图形沿所有超平面分解为子矩形。因此,在您的示例中,将有三个超平面(线)和四个生成的矩形。那么问题就变成了将矩形重新组合成更大的矩形以最小化矩形的最终数量。也许是 0-1 整数规划?

【讨论】:

  • 我认为像这样分解它,然后将其转换为 Z3 的问题将是一个不错的起点。如果幸运的话,Z3 的工作速度很快,您不必考虑如何搜索选择空间。你也更有信心没有错过任何一个案例,并找到了一个次优的解决方案。
  • 已知问题在 2D 中是 O(n^4),在 3D 中是 NP-hard。看我的回答:stackoverflow.com/a/30643519/1728537
  • 正如我在另一条评论中所说的,我不相信“普通”凸分解的同样复杂性适用于我的问题,因为我的问题更受限制。
【解决方案3】:

我认为动态编程可能是你的朋友。

我看到的第一步是将多面体划分为一个简单的块集合,以便每个可能的面都可用(即,将其切成尽可能小的块)。这应该是微不足道的,因为一切都是轴对齐的盒子,所以类似 k-tree 的解决方案就足够了。

这似乎是合理的,因为我可以看看它的成本。这样做的代价是我“忘记”了 hyperslab 的原始配置,选择用一组新的 hyperslab 替换它。这可能使我误入歧途的唯一方法是原始配置是否可以为解决方案提供一些东西。鉴于您想要所有配置的“最佳”解决方案,我们必须假设原始结构不是很有帮助。我不知道是否可以证明这些原始信息是无用的,但我将在这个答案中做出这个假设。

该问题现在已简化为类似于约束生成森林问题的图问题。我认为查看问题最自然的方法是将其视为图形着色问题(只要您可以避免将其与更著名的图形着色问题混淆,即尝试在没有相同颜色共享的两种状态的情况下为地图着色边框)。我有一个节点图(小块),我希望为每个节点分配一种颜色(最终将是覆盖该块的“hyperslab”)。我有一个约束,我必须在 hyperslab 形状中分配颜色。

现在一个关键的观察是,不必考虑所有可能性。以我们想要看到的最终彩色图为例。我们可以通过将跨分区的任何超平板分成两部分来以任何我们喜欢的方式对该图进行分区。然而,并不是每个分区都是有意义的。唯一有意义的分区是轴对齐切割,它总是将一个超板分成两个超板(与如果切割不是轴对齐可能出现的任何更复杂的形状相反)。

现在这个削减与我们真正想要解决的问题相反。切割实际上是我们在第一步中所做的事情。虽然我们想找到最佳的合并算法,但要撤消这些削减。然而,这显示了我们将在动态编程中使用的一个关键特征:唯一重要的合并特征是在切割的暴露表面上。一旦我们找到形成中心区域的最佳方式,它通常不会在算法中发挥作用。

让我们从构建超平板空间的集合开始,它不仅可以定义普通超平板,还可以定义任何超平板配置,例如带有孔的超平板。每个超空间记录:

  • 其中包含的叶 hyperslab 的数量(这是我们最终要尽量减少的数量)
  • hyperslabs 的内部配置。
  • 超平板空间的表面图,可用于合并。

然后我们定义一个“合并”规则,将两个或多个相邻的超平板空间合二为一:

  • Hyperslab-spaces 只能组合成新的 hyperslab-spaces(因此您需要组合足够多的部分来创建新的 hyperslab,而不是一些更奇特的形状)
  • 只需通过比较表面即可完成合并。如果存在具有匹配维度的特征,则将它们合并(因为很容易证明,如果特征匹配,合并 hyperslabs 总是比不合并更好)

现在这足以解决暴力问题。解决方案肯定是 NP 完全的。但是,我们可以添加一条额外的规则,它将显着降低此成本:“如果一个超平板空间覆盖相同的空间,并且在其表面上具有完全相同的特征,则认为它们比另一个‘更好’。在这种情况下,一个内部的 hyperslab 更少是更好的选择。”

现在这里的想法是,在算法的早期,您必须跟踪各种组合,以防万一它们最有用。然而,随着合并算法使事物变得越来越大,内部细节暴露在超平板空间表面上的可能性将变得越来越小。考虑

+===+===+===+---+---+---+---+
|   :   : A | X :   :   :   :
+---+---+---+---+---+---+---+
|   :   : B | Y :   :   :   :
+---+---+---+---+---+---+---+
|   :   :   |   :   :   :   :
+===+===+===+   +---+---+---+

看看左边的方框,我冒昧地用更粗的线条标记了它。在将盒子与世界其他地方合并时,AB:XY 表面是最重要的。因此,只有少数几种合并模式可以出现在这个表面上

  • 不能合并
  • A:X 允许合并,但 B:Y 不允许
  • B:Y 允许合并,但 A:X 不允许
  • A:X 和 B:Y 都允许合并(两个独立的合并)
  • 我们可以合并一个更大的正方形 AB:XY

有很多方法可以覆盖 3x3 方格(至少几十个)。但是,我们只需要记住实现每个合并过程的最佳方法。因此,一旦我们在动态规划中达到这一点,我们就可以忘记所有其他可能发生的组合,而只关注实现每组表面特征的最佳方法。

事实上,这为一个简单的贪心算法设置了问题,该算法探索哪种合并为减少超平板的数量提供了最佳承诺,始终记住实现给定表面特征集的最佳方法。当算法完成合并后,最终的 hyperslab-space 包含的内容就是最优布局。

我不知道它是否可证明,但我的直觉认为这将是一个 O(n^d) 算法,其中 d 是维数。我认为最坏的解决方案是一组超平板,当它们放在一起时,就形成了一个大的超平板。在这种情况下,我相信该算法最终会逆向 k-tree 算法。同样,没有给出任何证据……这只是我的直觉。

【讨论】:

    【解决方案4】:

    您可以尝试约束 delaunay 三角剖分。它给出的三角形很少。

    【讨论】:

    • 除了三角形不是凸矩形轴对齐的整块。
    【解决方案5】:

    你能确定每一行的方程式吗? 如果是这样,也许你可以得到这些线之间的交点(点)。然后,如果您选择一个轴,并开始寻找一个具有两个以上点的值(共享该值),那么您应该“画”一条线。 (在扫描开始时会有零个点,然后是两个(您的第一对),当您找到两个以上的点时,您将能够确定哪些点属于第一个多边形,哪些属于第二个多边形。

    例如,如果你有这些行:

    垂直(红色):

    x = 0, x = 2, x = 5

    水平线(黄色):

    y = 0, y = 2, y = 3, y = 5

    然后你开始扫过X轴,你会得到p1和p2,(我们知道它们属于哪个线方程)然后你会得到p3,p4,p5和p6!因此,您可以在此处检查哪些点共享同一条 p1 和 p2 线。在这种情况下 p4 和 p5。所以你的第一个新多边形是 p1,p2,p4,p5。 现在我们保存“新”点对 (p3, p6) 并继续扫描直到下一个点。这里我们有 p7、p8、p9 和 p10,寻找与先前点(p3 和 p6)共享线的点,我们得到 p7 和 p10。这些是您的第二个多边形的点。

    当我们重复 Y 轴的练习时,我们将得到两个点 (p3,p7),然后只有三个点 (p1,p2,p8) !在这种情况下,我们应该在新发现点的同一行中使用最远点(p8)。

    由于我们使用的是线方程和二维或更多维的点,因此过程应该非常相似

    ps,对不起我的英语:S

    我希望这会有所帮助:)

    【讨论】:

    • 看来这个程序不能保证我会得到尽可能少的块数......
    • 嗯,如果你选择线条较少的轴,在这种情况下是垂直线。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 2014-07-20
    • 2013-11-16
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多