查找覆盖给定直线简单多边形的最小矩形集

时间:2014-03-31 18:36:07

标签: algorithm rectangles

对于碰撞检测,我想使用尽可能少的矩形将位图转换为一组矩形。标题中描述了对该问题的更正式描述。一个例子:

programmer art

对于多种解决方案的断路器,如果所有矩形组合所覆盖的总面积最大化,我更喜欢它。例如,上图中的蓝色矩形可能会更小,但这可能是一个不太理想的解决方案。

此问题是否有更常见的名称?有文献吗?或者是一种提供最佳解决方案的简单算法?

3 个答案:

答案 0 :(得分:3)

这个问题可能是NP难的,但是如果你想为非硬度降低的实例提供最高质量的解决方案,那么运行integer programming求解器是值得一试的。即使运行时间是一个问题,也可以将黄金标准进行比较。

从本质上讲,您尝试解决一个名为set cover的问题的特殊情况。这就是set cover可以表示为整数程序的方式。

minimize sum_{white rectangles R} x_R
subject to
for all white points p, sum_{white rectangles R such that p in R} x_R >= 1
for all white rectangles R, x_R in {0, 1}

您所要做的就是编写代码来构造与其输入相对应的此整数程序的特定实例,调用求解器,获取结果,然后再使用最佳矩形数进行一次优化({{1已知。

k

如果实例很大,那么您可能需要进行一些预处理(解算器通常也可以执行此操作,但是他们必须使用算法来解决更普遍的问题,这可能效率不高)。首先,仅使用最大的白色矩形,即不包含在较大的白色矩形中。可能存在用于枚举它们的聪明算法,但是您应该首先实现天真的算法并对整个系统进行基准测试。其次,只使用一些要点。特别是,如果p和q是不同的点,并且p属于q所属的每个最大矩形,则跟踪p是多余的。

答案 1 :(得分:2)

我建议只是从一个尚未被矩形覆盖的外部角落开始,然后贪婪地增长那个矩形。重复直到所有内容都被覆盖。我不认为这会为您提供您在全球范围内寻找的打破平局属性(因为您可能有多种方法可以选择如何贪婪地增长每个矩形),但它确实是在本地进行的。

答案 2 :(得分:0)

我设法以一种足够好的方式解决问题 - 但它可能不是最佳的。

  1. 使用位图的尺寸制作2D数组。对于位图中的每个像素,黑色构成相应的元素WALL,否则为EMPTY_SPACE。

  2. 扫描阵列从左到右,从上到下扫描第一个EMPTY_SPACE。保存此坐标。

  3. 创建一个区域1的矩形,其中topleft坐标设置为2处的坐标,向下和向右延伸1。

  4. 只要矩形不覆盖任何墙壁,水平地将矩形向左和向右延伸。

  5. 只要它不覆盖任何墙壁,就会上下垂直延伸矩形。

  6. 将矩形覆盖的任何元素标记为COVERED_SPACE,并将矩形添加到矩形集中。

  7. 如果仍然有一个包含EMPTY_SPACE的元素,请转到2,否则你就完成了。