Algorithm 使用递归编程用L形三块瓷砖填充n*m块矩阵的方法的数量

Algorithm 使用递归编程用L形三块瓷砖填充n*m块矩阵的方法的数量,algorithm,recursion,matrix,Algorithm,Recursion,Matrix,我正在寻找一种解决这个问题的方法,你必须填写n*m(n,m有一个技巧适用于许多递归枚举问题。无论你喜欢哪种方式,定义一个确定性过程,从非空部分解中删除一部分。然后递归枚举以相反的方向工作,从空解中构建可能的解,但每次一块,同一块必须是通过确定性程序移除的那块 如果在开始枚举之前验证电路板大小可以被3整除,则时间限制应该没有任何问题。我使用算法plus解决了这个问题。我的解决方案不是特别快,解决9x12网格需要一分钟左右的时间,但对于您的问题中的8x8网格应该足够了(在9x9上大约需要一秒钟)。7

我正在寻找一种解决这个问题的方法,你必须填写n*m(n,m有一个技巧适用于许多递归枚举问题。无论你喜欢哪种方式,定义一个确定性过程,从非空部分解中删除一部分。然后递归枚举以相反的方向工作,从空解中构建可能的解,但每次一块,同一块必须是通过确定性程序移除的那块

如果在开始枚举之前验证电路板大小可以被3整除,则时间限制应该没有任何问题。

我使用算法plus解决了这个问题。我的解决方案不是特别快,解决9x12网格需要一分钟左右的时间,但对于您的问题中的8x8网格应该足够了(在9x9上大约需要一秒钟)。7x7和8x8网格没有解决方案,因为它们不能被triomino大小3整除

策略是从网格的一个角落开始,一个单元一个单元地移动,尝试在合法的情况下放置每个块,从而有条不紊地探索解决方案空间

如果区块的放置是合法的,但在网格中产生了无法填充的气穴,则移除区块;我们提前知道,这种状态将没有解决方案,并且可以放弃探索其子级。例如,在3x6网格上

abb.c.
。
亚BCC。
......
这是无法解决的

一旦达到所有单元格都已填充的状态,我们可以向其父状态报告1个解决方案的计数。以下是已解决3x6网格的示例:

aaccee
abcdef
bbddff
如果每个可能的区块都已放置在某个位置,则回溯,向沿途的父状态报告解决方案计数,并探索尚未勘探的任何状态

在记忆方面,如果瓷砖的排列方式使其覆盖完全相同的坐标,则将任意两个网格状态称为等效。例如:

aacc。。
阿布德。。
bbdd。。

aacc。。
bacd。。
bbdd。。
即使这两个状态是通过不同的磁砖放置达到的,也被认为是等效的。这两个状态具有相同的子结构,因此计算一个状态的解的数量就足够了;将此添加到备忘录中,如果我们再次达到该状态,我们可以简单地报告备忘录中的解的数量,而不是重新计算一切

我的计划报告了3x6网格上的8个解决方案:

正如我所提到的,我的Python解决方案速度不快,也没有经过优化。在不到一秒钟的时间内解决一个9x12网格是可能的。除了大型优化之外,还有一些基本的东西我在我的实现中忽略了。例如,我为每个瓷砖放置复制了整个网格;在单个网格上添加/删除瓷砖将是一个简单的改进。我还id不会检查网格中无法解决的间隙,这可以在动画中看到


解决问题后,一定要四处寻找人们想出的一些令人兴奋的解决方案。我不想透露比这更多的东西!

你有关于这种方法的更多细节吗?听起来不错interesting@ThomasAhle无同构穷举生成Brendan D.McKay:我不想给出比这更多的东西!所以,有更多的than如前所述?@jiten OP的问题是“我不一定要寻找完整的答案,只是一个如何处理的提示。”所以我没有提供完整的代码,只提供了一个高级算法。搜索演练/提示/解决方案,或者如果你需要更多关于这个问题的信息。