例如,假设我们有一个有界的2D网格,我们想用相同大小的方形图块覆盖。我们拥有无限数量的瓷砖,这些瓷砖属于规定数量的类型。每种类型的图块都指定印在该图块上的字母。在每个边缘旁边打印字母,并且只有在其相邻边缘上具有匹配字母的贴片可以在网格上彼此相邻放置。瓷砖可以旋转。
考虑到网格和图块类型定义的大小,排列图块的最快方法是什么,以便满足上述约束并覆盖整个/大部分网格? 注意我的用例适用于大型网格(每个维度约20个)和中等大量解决方案(与Eternity II不同)。
到目前为止,我已经尝试了DFS从中心开始并选择填充区域周围的位置,这些位置允许最少的可能性和回溯,以防无法取得进展。这仅适用于具有一种或两种类型的简单方案。随之而来的是更多和太多的回溯。
这是一个简单的例子,显示输入和最终输出:
答案 0 :(得分:5)
这是一个难题。
Eternity 2是这种形式的拼图,有16乘16平方网格。
尽管获得了200万美元的奖金,但几年内没有人找到解决方案。
论文"Jigsaw Puzzles, Edge Matching, and Polyomino Packing: Connections and Complexity" by Erik D. Demaine, Martin L. Demaine表明这种类型的谜题是NP完全的。
答案 1 :(得分:1)
考虑到使用方形网格的这种问题,我会尝试所有可能列的强力列表,然后是所有行的动态编程解决方案。这将找到解决方案的数量,并且可以使用一些额外的工作来生成所有解决方案。
但是,如果您的行n
长且m
个字母带有k
个图块,那么所有可能列的强力列表最多可能为mn
生成它所需的最多m4k
个瓦片组合/旋转的边缘。然后,从一列的右边缘到下一个列的右边缘的过渡可能具有最多m2n
种可能性。这些数字通常不是最坏的情况,但这些数据结构的大小将是该技术可行性的上限。
当然,如果这些数据结构太大而不可行,那么您描述的递归算法将太慢而无法枚举所有解决方案。但是如果有足够的话,即使这种方法不可行,它仍然可以快速运行。
当然,如果您有多行而不是列,则需要在此技术中反转行和列的角色。