如果我有一个任意大小的相等大小的正方形网格(它们之间没有间距),我需要知道一种有效的方法将它们减少为最小数量的矩形,例如每个星号代表一个正方形,然后可以缩小为一个大矩形:
*****
*****
*****
虽然这可以减少到两个矩形:
*** ***
***** => **(1) ***(2)
***** ** ***
*** ***
一个明显的解决方案是收集每行中的相邻方块,然后收集相同的相邻行。对于我的第二个例子,这将找到三个矩形,这不是最佳的。
*** (1)
***** (2)
*****
*** (3)
我想知道是否有更成功和更有效的算法来做到这一点。
答案 0 :(得分:2)
我有一种直觉,认为这个问题很复杂......例如考虑
*
***
****
***
*
最佳解决方案是4
B
BCC
AAAB
BDD
B
但是我没有找到一种简单的方法来预见A应该在最后一个方格之前停止。在最优解中,A,C和D是非最大矩形,并且只有B是最大的。事情可能变得更加复杂,例如:
*
***
****
***
*
*****
* *
* *
最佳解决方案
B
BCC
AAAB
BDD
B
EEEEE
F G
F G
其中只有E是最大的。另外看起来很容易构建任意大的问题,在最优解决方案中,除了一个矩形之外的所有矩形都是非最大的。 当然这并不意味着IMO没有简单的解决方案存在......就像我说这是一种直觉,但是如果需要绝对最小值,IMO任何有最大矩形的解决方案都会遇到问题。
对于一个有点类似但又不同的问题(我正在寻找一个非必要的不相交光盘的最小覆盖)我使用了一种缓慢的贪婪方法总是在解决方案中添加包含的光盘并覆盖大部分尚未覆盖的光盘广场。 对于你的问题,我可能会看到它是如何工作的,每次都添加最大的包含矩形......正如上面的例子所示,这通常不是最佳解决方案。
答案 1 :(得分:0)
如果已经有一个算法,我不知道我的头脑,所以我做了一个:
Find(xmin,ymin)(xmax,ymax),即现有方块的x和y坐标的最小值和最大值。这定义了一个包围所有正方形的单个边界矩形。
在边界矩形内查找并连接直线凹角。
回答评论:好的,所以如果我们沿着网格线连接所有凹形周边角落,逐渐去除(标记)周边矩形,我们在上面的困难例子中得到以下结论:
A
XBB
CCCX
XDD
X
EFFFG
I J
I J
正如已经指出的那样,是次优的。当可能有多种方式时,有一些决定可以成对地连接凹面。选择产生最少数量新矩形的那个。 (见最低X下的F)。
当分割完成后,我们现在添加另一个扩展(合并)现有矩形的阶段。至关重要的是,只允许这样的合并不会减少任何现有的矩形。将最上面的X更改为B将是一个不允许的更改,因为Xs矩形已经减少。此条件保证仅在朝向最小矩形数的方向上进行更改。在上面的例子中继续这个过程,我们得到:
X
XBB
CCCX
XDD
X
FFFFF
I J
I J
在这个示例中,这恰好是最优的,但通常您可能必须使用这些操作进行状态空间搜索才能找到全局最小值。