【问题标题】:Algorithm to find the minimum number of rectangles covering certain elements in a 2d array [duplicate]找到覆盖二维数组中某些元素的最小矩形数量的算法[重复]
【发布时间】:2011-12-26 21:15:52
【问题描述】:

简化,我要解决以下问题:

你有一个用 0 和 1 填充的二维数组。找到最小数量的矩形,使得它们覆盖所有 1。矩形不应重叠。

函数签名可能如下所示: List<Rectangle> FindCoveringRectangles(bool[,] array)

我已经有一个“足够好”的解决方案,但并不总是找到最小数量的矩形。我想知道是否有一些众所周知的高效算法可以用来解决这个问题?

例子:

输入数组:

..........
.1.....11.
.......11.
...111....
...111....
...111....
....1111..
....1111..
......11..
..........

(为了便于阅读,用点替换 0)

可能会产生以下矩形:

(2,2,2,2),
(2,8,3,9),
(4,4,6,6),
(7,5,8,8),
(9,7,9,8)

(上、左、下、右),从 1 开始

可以有不止一种解决方案,但一种就足够了。

【问题讨论】:

  • 如果您告诉我们您的近似算法,也许我们可以在最坏的情况下帮助改进它。
  • 你想优化什么?矩形的最小数量始终为 1。
  • 这个问题在Karnaugh maps的上下文中很好的解决了。
  • @ThomasAhle:卡诺图具有更高维度(8x8、16x16 等)和更多变量。虽然精确的 Quine-McCluskey 方法是 NP 难的,但 Espresso 启发式应该会给出很好的结果。由于对该主题的了解有限,我无法提供完整的细节,但我知道卡诺图被广泛使用并且与手头的主题非常相似。
  • @ThomasMcLeod:你只覆盖那些。

标签: algorithm


【解决方案1】:

这是一个匹配问题,很容易证明是 NP-hard。不过似乎有一个非常快速的解决方案!

使用 bfs flood-fill 可以找到每个连接的组件,O(n)。因此 wlog 我们可以假设我们只需要填充一个连接区域。

如果该区域没有洞,您可以使用this paper(或here on google scholar)中描述的算法。

提出了一种O(n log log n)算法,用于对简单直线多边形进行最小矩形分割。对于任何简单的直线多边形 P,顶点-边可见对是可以通过完全位于 P 内部的水平或垂直线段连接的顶点和边。表明,如果找到顶点-边可见对,从简单直线多边形的弦导出的二部图的最大匹配和最大独立集可以在线性时间内找到,而无需构造二部图。使用该算法,可以在O(n)时间内求解凸直线多边形和垂直(水平)凸直线多边形的最小分割问题

所提到的一些论文也涵盖了有孔区域的情况。虽然这些运行在 O(n^(3/2)logn) 中,但它们仍然很好。

或者,您可能会做的一件事是解决没有孔的问题,解决每个孔的问题,然后减去。虽然这可能不会给出最佳解决方案,但会保持运行时。

您也可以尝试将形状拆分为不同的拓扑部分,但这可能会在孔的数量上呈指数增长。

第三,您可以尝试针对更一般的情况调整建议的算法,但这可能很难。

【讨论】:

  • 谢谢,摘要听起来很有希望。将不得不等到我回来工作,直到我可以下载整篇文章:(
  • 是的,很遗憾我在其他任何地方都没有找到这篇论文。 - 这是更简单但 O(n^2) 的原始方法:sciencedirect.com/science/article/pii/0734189X84901397 - 这是支持孔的 O(n^3/2logn) 方法:epubs.siam.org/sicomp/resource/1/smjcat/v15/i2/p478_s1
  • 这些技术都以某种方式将多边形分成水平和垂直部分。这些被放入连接到它们的交叉点的图中。结果证明该图是二分的,因此我们可以快速找到“最大独立集”。 (使用股票算法的 O(n^2))。
  • 感谢其他链接。几天前,当我搜索第一篇论文的免费副本时,我已经找到了最后一篇。不是很详细,但至少它通过给我一些东西的名称/定义来扩展我的词汇量。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 2021-03-03
  • 2014-05-25
相关资源
最近更新 更多