今天晚上我试图解决一个木质拼图,所以我想知道哪种方法可以找到解决这类问题的最佳方法。
目的是将一组固体(如三维中的俄罗斯方块)组合在一起,以可行的方式形成一个形状,考虑到只有在它们适合的情况下才能将碎片连接或滑入结构的事实。运动类型(忽略旋转,仅旋转90°)。
检查this图片以了解我的意思。
答案 0 :(得分:4)
在我最新的CS课程中,我们制作了一个通用的拼图解算器,通过在C ++中将状态表示为对象来工作。每个对象都有一个方法来比较它所代表的状态和另一个状态。这用于记忆,以确定是否已经看到状态。每个状态还具有生成可从该状态直接到达的状态的方法(即,旋转块,放置块,移位块)。求解器通过维持状态队列,从队列前面弹出一个状态,检查它是否是所需状态(即解谜)来工作。如果没有,则检查memoization(我们使用散列集)以查看是否已经看到状态。如果不是,则生成从当前状态可到达的状态并将其附加到队列的后部。一个空的队列标志着一个无法解决的难题。
概念化类似于3D的东西会很难,但这是计算机化拼图解决的基本方法。
答案 1 :(得分:2)
似乎是三维polyomino打包问题的一个更容易的子集。该主题有各种scholarly papers。
答案 2 :(得分:1)
因为这是一个或多或少的小问题,因为对于计算机而言,可能存在少量组合,我会尝试简单的搜索算法。 我的意思是algorithm检查每个可能的配置,然后从这个配置的结果继续,直到它结束于最终配置,在你的情况下是立方体。
问题是编写一个能够执行从一个状态到另一个状态的所有状态检查和转换的程序。因为您必须查看配置是否物理上可行。
答案 3 :(得分:1)
如果您想要处理的拼图是您链接的照片中的拼图,那么在您找到自己的方式之前,只搜索可能的解决方案树可能是可行的。
如果每个拼图块都是多个立方体贴在他们的脸上,而我是通过将每个拼图装入一个更大的立方体来解决拼图,每个边缘作为拼贴立方体4次,那么我将按照以下步骤进行:
声明每件作品的任意立方体作为其原点。观察每个拼图有24种可能的旋转,原始立方体的每个可能面朝上的一个方向,在该位置绕垂直轴旋转4次。
尝试通过查找产生相同最终作品的可能方向来剔除搜索空间,如果给定旋转,然后将原始立方体转换为该块的任何其他立方体,则会产生完全相同的占用体积作为先前考虑的轮换,从未来的考虑中剔除轮换。
从包里取出一块。如果包里没有碎片,那么这是一个解决方案。循环通过溶液体积的每个单元,以及每个单元的拉出件的每次旋转。如果作品完全位于搜索量内,并且不与任何其他部分重叠,请进入此段落。否则,继续进行下一次旋转,或者如果没有更多旋转,则进入下一个单元格,或者如果没有更多单元格,则返回没有解决方案。
如果最后一段没有解决方案,那么拼图就无法解决了。