cra*_*410 12 java puzzle algorithm
谁能建议如何使用计算机程序解决Log Pile木制拼图?
请参阅此处以查看拼图:http://www.puzzlethis.co.uk/products/madcow/the_log_pile.htm
图片只显示了一些部分.全套10件配置如下,其中1代表一个钉,-1代表一个孔,0代表一个钉和一个孔.
-1,1,0,-1,0
1,0,1,0,0
1,-1,1,0,0
-1,
-1,0,0 ,-1 -1,1,0,1 ,0
0,1,0,0,1
1,0,-1,0,-1
0,-1,0,1,0
0,0,-1,1,-1
1,0,-1, 0,0
这些部件可以互锁成两层,每层5件,顶层与底层成90度,如上面的链接所示.
我已经使用Java自己创建了这个问题的解决方案,但我觉得这是一个笨拙的解决方案,我有兴趣看到一些更复杂的解决方案.您可以随意提出一般方法或以您选择的语言提供工作计划.
我的方法是使用上面的数字表示法来创建一个"日志"数组.然后我使用组合/置换生成器来尝试所有可能的Logs排列,直到找到所有交叉点等于零的解(即Peg to Hole,Hole to Peg或Blank to Blank).我使用了一些加速来检测给定排列的第一个失败的交叉点并继续下一个排列.
我希望你发现这和我一样有趣.
谢谢,克雷格.
这个问题似乎是布尔可满足性问题的一种形式.如果是,最着名的方法是蛮力.
但是有一些对称性,问题的一些属性可以让你减少你需要尝试的解决方案的数量.例如 -
根据 Jay Elston 的建议,我将使用以下伪代码来实现它:
Read in the pieces
Annotate each piece with its number of pegs and holes
Generate all possible base layers (10 over 5 = 252, selecting 5 from the set),
so that sum(above, pegs) == sum(below, holes) and sum(below, pegs) == sum(above, holes)
For each base layer, (5! = 120 of them, permuting the 'below' pieces)
compute 'rotated pieces' for the base layer
if one-to-one match between top layer and rotated base-layer pieces,
report successful solution
Run Code Online (Sandbox Code Playgroud)
对于给定的基层,“旋转件”是您需要覆盖它的理想件。通过计算这些片段并将它们与顶层片段匹配,您可以使用 O(N log N) 排序将旋转片段与真实顶层进行匹配,而不是与所有 N 进行匹配!可能的顶层安排。另外,在第一次不匹配时,您可以提前退出。
编写高效算法的关键是尽早修剪搜索并利用任何对称性。例如,如果您认为拼图是对称的,则可以将运行时间减少一半,因此您可以任意将一块分配到底层:这样您将只有 4 个基础层中的 9 个需要探索。