将多个矩形“修复”为较少数量的矩形的算法?


14

在此处输入图片说明

假设我有一个不同形状和颜色的矩形网格,我想减少(合理地接近最佳值就可以了,不需要最佳值)代表相同颜色布局的矩形数。

上图是一个非常简化的情况,矩形之间的空白仅用于可视化-它们实际上是紧密包装的。

可以帮助我做到这一点的方法或算法名称(对Google满意)是什么?


3
您能告诉我们这些矩形的来源吗?它们趋向于(大致)与任何基础网格对齐,还是共享一些公共构造块,或某个最小的“原子”矩形?它们可以旋转吗?在大多数情况下,这看起来像是一个棘手的问题,但是如果我们可以在您的特定情况下利用某些约束或共性,可能会变得更加棘手。
DMGregory

有一个正方形的底层网格(如棋盘格),每个矩形与这些正方形共享边界。即,您可以使用整数来描述每个矩形的顶部/底部/左侧/右侧。因此,它们不能以不可除以90度的角度旋转。同样,NxM网格完全填充有矩形-没有未覆盖的网格位置。
xaxxon

我只是想避免看起来像上面示例的情况(从着色的角度来看),但是它由大量的1x1矩形组成,当我可以处理很多空间时,我正在处理每个矩形通话次数更少。
xaxxon

我猜是“只是从某处开始,并继续在一个维度上尝试越来越大的矩形(垂直说),直到您遇到一个彩色边框,然后再扩大另一个维度(水平)直到您碰到一个边界。然后首先水平尝试然后也许只尝试正方形(对角线增长),但是不确定是否简单地选择上述三种可能性中的最大者是正确的方法
xaxxon

如果最终减少了矩形的数量,可以拆分现有矩形吗?还是应该只合并算法?另外,总计数是否唯一的标准,还是您喜欢方形而不是细长的条形/较大的矩形而不是较小的条形?
DMGregory

Answers:


15

首先,我们可以将源矩形转换为基础网格中的单元格,以使输入更均匀。(有效地光栅化问题)

这将使我们找到在直接使用源矩形时可能并不明显的优化,尤其是在涉及拆分多个源矩形以不同方式重组它们时。

将矩形转换为网格单元并返回的示例

接下来,我们可以使用深度优先搜索或洪水填充算法找到相同颜色的连通区域。我们可以孤立地考虑每个连接的区域(一个多米诺骨牌)-我们对其他区域所做的任何操作都不需要影响这个区域。

实际上,我们想找到一种将这种多米诺骨肉切成矩形的方法(不幸的是,我能找到的大多数文献都是关于相反的问题:将矩形切成多米诺骨肉!这使得寻找线索变得棘手...)

一种简单的方法是将相邻正方形的水平行组合成细长的矩形。然后,我们可以与上一行进行比较,并结合运行开始和结束是否匹配-在完成每个运行/行时,或者在考虑将每个单元添加到当前运行时。

将多米诺骨球分解为水平段,然后垂直合并

我还不知道这种方法达到最佳效果的程度。当尚未考虑的行与迄今为止看到的行不同时,似乎会遇到一些麻烦:

具有3个矩形解的情况的示例,其中上述方法得出4

检测运行/矩形何时被上/下运行精确地覆盖,然后将其拆分并合并将解决此特定情况,但我尚未探讨问题的普遍性。

我还研究了沿着多米诺骨牌的周边行走并在遇到凹角时将其横切的方法,但是这种方法对我来说似乎更容易出错。要获得最佳结果,似乎需要对连接两个凹角的切口进行优先排序,并且包含凹陷的形状需要特殊处理,因此行扫描方法似乎具有简单性优势。

我正在寻找的另一种方法是采用在第一行中找到的第一个运行并将其尽可能地向下延伸。然后在剩下的第一行中进行第一轮奔跑...虽然这在倒T形上被绊倒了,所以也不是最优的。

我觉得可能存在使用动态编程来找到最佳分割的方法,但是我还没有找到。


谢谢你的回答!该解决方案看起来足够快,我可以沿几个不同的方向运行,并选择最合适的方向-水平从左到右,水平从右到左,然后再以垂直方式进行。
xaxxon

2
麻烦的是我们可以构造形状,从而从各个扫描方向误导算法。这些可能不太可能真正显示出来,但仍然使我感到烦恼。我认为这是一个简单的解决方法...每次运行中都要注意一点,在运行中期是否有凹角。然后,如果随后的运行恰好在这一点上结束,我们将回溯以上运行,并垂直拆分它们。我还没有整理出全部细节。
DMGregory

1
另外,我不确定为什么要进行洪水填充步骤。当从网格正数到细长的矩形时,您可以简单地遍历网格的整个行或列(无论采用哪种方式)来创建这些1xN矩形。不需要知道多义胺吧?
xaxxon

没错,注水不是必要步骤。我将其包括在内是为了证明在后续步骤中一次只关注一个彩色区域是合理的,但是您可以轻松地将行扫描方法应用于交错的多个彩色区域。但是,基于周长的方法需要一次处理一种形状的周长。
DMGregory
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.