有5 * 5立方体拼图名为快乐立方体问题,对于给定的垫子,需要制作立方体。 http://www.mathematische-basteleien.de/cube_its.htm#top
就像6个蓝色垫子一样 -
从以下垫子中,需要派生一个立方体 -
这种方式还有3个解决方案。 就像第一只小熊一样
对于这样的问题,我能想象的最简单的方法是基于递归,对于每个立方体,我有6个位置,并且对于每个位置,我将尝试检查所有其他配合,哪个适合,我将再次递归地再次解决。就像找到每个立方体的所有排列,然后找到哪个最适合。所以动态编程方法。
但是我在递归中犯了很多错误,所以有没有更好的方法可以用来解决它?
我从提供的每个垫子或图表中制作了矩阵,然后我每隔90次顺时针旋转它们4次,然后逆时针旋转。我翻转数组并做同样的事情,现在对于上面的每一次迭代,我都要重复其他立方体的步骤,所以再次递归。
0 0 1 0 1
1 1 1 1 1
0 1 1 1 0
1 1 1 1 1
0 1 0 1 1
-------------
0 1 0 1 0
1 1 1 1 0
0 1 1 1 1
1 1 1 1 0
1 1 0 1 1
-------------
1 1 0 1 1
0 1 1 1 1
1 1 1 1 0
0 1 1 1 1
0 1 0 1 0
-------------
1 0 1 0 0
1 1 1 1 1
0 1 1 1 0
1 1 1 1 1
1 1 0 1 0
-------------
1st - block is the Diagram
2nd - rotate clock wise
3rd - rotate anti clockwise
4th - flip
仍在努力理清逻辑。
答案 0 :(得分:2)
我无法相信这一点,但实际上我在2009年写了一套脚本来解决这个问题的蛮力解决方案,对于简单的立方体案例。我只是把代码放在Github上:https://github.com/niklasb/3d-puzzle
不幸的是,文档是德语的,因为这是我的团队理解的唯一语言,但源代码注释是英文的。特别是,请查看文件puzzle_lib.rb
。
这种方法确实只是一种简单的回溯算法,我认为这是一种方法。我不能说它是 easy ,据我记得三维方面有点挑战性。我实现了一个优化:预先找到所有对称性,只尝试一个片段的每个唯一方向。这个想法是,这些作品的特征越多,放置碎片的选择就越少,所以我们可以提前修剪。在许多对称的情况下,可能存在很多可能性,我们只想检查那些对称的唯一对称。
基本上算法的工作原理如下:首先,将固定顺序分配给立方体的边,例如,将它们编号为0到5。然后执行以下算法:
def check_slots():
for each edge e:
if slot adjacent to e are filled:
if the 1-0 patterns of the piece edges (excluding the corners)
have XOR != 0:
return false
if the corners are not "consistent":
return false
return true
def backtrack(slot_idx, pieces_left):
if slot_idx == 6:
# finished, we found a solution, output it or whatever
return
for each piece in pieces_left:
for each orientation o of piece:
fill slot slot_idx with piece in orientation o
if check_slots():
backtrack(slot_idx + 1, pieces_left \ {piece})
empty slot slot_idx
角落的一致性有点棘手:角落必须由相邻的一个部分填充,或者必须可以从尚未填充的槽中进入,即不会被已经分配的部分切断。
当然你可以忽略掉一些或所有的一致性检查,只检查最后,因为只有8 ^ 6 * 6!整体可能的配置。如果你有超过6件,早期修剪就变得更加重要。