什么是解决拼图的有效算法?

时间:2009-09-28 19:56:06

标签: algorithm

昨天我刚刚玩Jigshaw Puzzle,不知何故想知道解决它的算法是什么。

作为人类,我遵循的步骤:

  1. 将所有部件分成3个部分,单个扁平边缘,双个扁平边缘,完全没有边缘。
  2. 将平边条件分开,因为它们是图像的角落
  3. 将单个边缘片分开,因为它们会形成图像的4个末端边缘
  4. 最后,没有边缘的碎片会形成图像的内部。
  5. 匹配颜色和图像片段以将片段放在一起。
  6. 我想知道什么是有效解决这个难题的有效算法,以及什么数据结构将提供最佳的有效解决方案。

    感谢。

5 个答案:

答案 0 :(得分:8)

解决这样的问题可能看似复杂,特别是如果没有对谜题的大小和复杂性施加任何限制。

这是我对编写程序来解决这样一个难题的想法。

有四个关键信息可以单独使用,也可以作为解决拼图游戏的线索:

  1. 每个部分的形状信息(它们的边缘如何显示)
  2. 每个部件的颜色信息(相邻部件通常具有平滑过渡)
  3. 每件的方向信息(平坦和角落边缘可能位于其中)
  4. 整体尺寸和件数提供了拼图的一般尺寸
  5. 那么程序将提供什么样的信息 - 让我们假设每个拼图都是一个小的矩形图像,其透明度信息用于识别拼图块中代表非矩形边缘的部分。

    由此可以相对容易地识别出四个角落(在典型的拼图中)。这些将具有两个具有平面轮廓的边缘(参见下面的等高线图)。

    接下来,我将构建有关拼图块四个边缘每个形状的信息。此信息可用于构建adjacency matrix,指示哪些部分组合在一起。

    现在我们可以修剪这个邻接矩阵,以识别那些在相邻配置中具有平滑颜色过渡的片段。这有点棘手,因为它需要一定程度的模糊匹配 - 因为不是每个像素到像素的边界都必然会有平滑的颜色过渡。

    使用最初确定的四个角落,我们现在应该能够重建拼图中所有棋子的尺寸和位置。

    用于表示边缘形状的方便数据结构可以是等高线图 - 基本上是一组整数,表示从图像的相对侧到该四个侧面中的每一侧中的最后一个非透明像素的距离的增量增量。拼图块。匹配的碎片应该有镜像轮廓图。

答案 1 :(得分:4)

确保扫描一件作品的男/女部分 - 这会将搜索量减半。

答案 2 :(得分:3)

假设你不打算进入任何计算机视觉的东西,那么在搜索整个问题空间时会有非常小的变化,即尝试每个部分直到一个适合并重复。如果你知道它不合适,那么主要的优化就是不要在同一个地方尝试相同的部分。侧面/角落部分构成相对较少的部分,可能无法在任何主要优化中考虑。

数据结构可能类似于哈希矩阵,您可以快速检查是否已经尝试过某个位置。

包括计算机视觉在内的简单优化是在对每个位置进行分类后,根据平均颜色与相邻位置的匹配程度进行分类。

这当然不在我的头顶。

答案 3 :(得分:2)

我不认为人的方式会对实现有所帮助 - 计算机可以每秒多次查看所有部分,并且通过将部分分类为角落,边缘和内部,我看不到(大)胜利碎片,特别是因为只有三个类别,它们的大小各不相同。

给定一组所有部分的图像,我会尝试为每个部分或边缘导出一个简单的描述符。描述符必须包含有关粗糙形状和部分颜色的信息,分别是四条边。给出1000件拼图,有4000个边缘,总是两个必须相等(忽略拼图的边界)。因此,描述符必须能够区分需要至少11位的2000条边。

将一个部分分成一个3 x 3的检查板模式,每个边缘有三种颜色 - 每个通道有8个比特,我们已经有72个比特。我首先倾向于建议降低颜色分辨率,但这似乎不是一个好主意 - 例如蓝天可能真的受益于高色彩分辨率。请注意,计算颜色可能需要将棋子与背景分开,并尝试将边缘与水平轴和垂直轴对齐。

在蓝天等非常均匀的区域,颜色信息可能不足以找到好的匹配,并且需要额外的几何信息。我会尝试用curvature或派生的度量来描述边缘的形状。也许每边采样10到20个点。这可能再次依赖于背景分离和边缘对齐。

最后,计算机可以轻松完成 - 比较所有边对描述符并找到最佳匹配。这个过程可能应该控制成更局部而不是简单的最佳匹配,因为当你找到一个角落时(正确的英文单词?我的意思是L形的三个部分。)你有两个边缘约束要找到的部分和如果找不到好的匹配(表示之前发生的错误或难以拼图),可以提前追溯。

答案 4 :(得分:1)

通过这个我想到了一个有趣的解决方案,通过一系列步骤增加成本来解决它。

  1. 将所有拼图分成两组。测试它们是否合在一起。如果没有,尝试一下以前从未见过的另一件作品。如果是这样,将集合放入正确的堆中。重复,直到所有两组都找到匹配。

  2. 从正确的桩中组合成两组,形成一组两个,即{{1,2},{5,6}}。看看来自一组两个中的至少一个拼图块是否与来自另一组两个中的至少另一个拼图块相匹配。如果没有,请尝试以前没见过的另外两套。如果是这样的话,将两组以正确的方向组合成一组四个,找到的组合在一起,并将组合的组合成正确的堆。重复,直到找到所有四个组。

  3. 重复这些步骤,直到设置n / 2与set n / 2结合的最终问题。

  4. 不正确的计算时间是多少。