我正在编写一个程序,需要快速检查一个连续的空间区域是否可由四联骨牌(任何类型,任何方向)填充。我的第一个尝试是简单地检查方块的数量是否可被4整除。但是,这种情况仍然会出现:
正如你所看到的,尽管这些区域各有8个方格,但它们不可能用四联体进行平铺。
我一直在思考,我不知道该怎么办。在我看来,“枢纽”正方形或通往两个以上“隧道”的正方形是关键。在上面的示例中很容易,因为您可以快速计算每个此类隧道中的空间 - 第一个示例中的3,1和3,以及第二个中的3,1,1和2 - 并确定无法继续由于每个隧道需要连接到集线器方块以适应tetromino,这对所有隧道都不会发生。但是,您可以使用更复杂的示例:
...简单的计数技术不起作用。 (至少,就我所知。)而这就更不用说具有极少数轮毂方块的更多开放空间。另外,我没有任何证据证明中心方块是唯一的技巧。据我所知,可能还有很多其他不可能的案例。
某种搜索算法(A *?)是解决此问题的最佳选择吗?我非常关注数百甚至数千个方块的性能。该算法需要非常高效,因为它将用于实时平铺(或多或少),并在浏览器中使用。
答案 0 :(得分:1)
[编辑28/10/2014:正如pix所注意到的,这种方法从不尝试使用T-tetromino,所以它更可能给出一个不正确的“No”答案,而不是我想的......] 强>
这不能保证任意形状的解决方案,但它在大多数情况下都能快速有效地工作。
想象一个graph,其中每个白色方块都有一个顶点,当且仅当它们相应的白色方块相邻时,两个顶点之间有一条边。 (因此,每个顶点最多可以触摸4个边。)此图中的perfect matching是边的子集,因此每个顶点都恰好接触子集中的一个边。换句话说,它是一种配对相邻顶点的方式 - 或者换句话说,是白色方块的多米诺骨牌。稍后我将解释如何找到一个随意的完美匹配;现在,让我们假设它可以完成。
然后,从这个多米诺骨牌拼贴开始,我们可以重复匹配过程,将多米诺骨牌粘合在一起进入tetrominos!第二次唯一的区别是,不是每个白色方块有一个顶点,而是每个多米诺骨牌有一个顶点;因为我们必须在两个多米诺相邻时添加一条边,一个顶点现在可以有多达6个边。
第一步(多米诺骨牌)步骤不能失败:如果存在给定形状的多米诺骨牌,则会找到一个。然而,第二步(将多米诺骨牌混合成tetrominos)有可能失败,因为它必须与已经决定的多米诺骨牌平铺一起工作,这可能会限制其选择。这是一个示例,显示相同形状的不同多米诺骨牌如何能够或破坏tetromino拼贴:
AABCDD --> XXXYYY Success :)
BC XY
AABBDD --> Failure.
CC
为了生成多米诺骨牌的随机模式,可以给图中的边缘赋予随机权重,并且可以求解最大加权匹配问题。权重应该在[1,V /(V-2))的范围内,以保证通过使一些顶点不成对而永远不可能获得更高的分数。该图实际上是二分的,因为它不包含奇数长度周期,这意味着用于最大加权二分匹配问题的更快的O(V ^ 2 * E)算法可用于该步骤。 (对于第二个匹配问题,情况并非如此:一个多米诺骨牌可以触及另外两个相互接触的多米诺骨牌。)
如果第二步未能找到一套完整的tetrominos,那么要么无法解决*,要么可以使用不同的多米诺骨牌解决方案。您可以尝试随机重新加权用于查找多米诺骨牌的图形,然后重新运行第一步。或者,不是从头开始重新加权,而是可以增加有问题的多米诺骨牌的权重,然后再试一次。
*对于边长均匀的普通方形,我们知道解决方案总是可行的:只需填充2x2方形tetrominos。