Algorithm 3x3网格解谜(JS)
我有一张分成3x3网格的图像。网格由数组表示。每一列或每一行都可以旋转。例如,最上面一行Algorithm 3x3网格解谜(JS),algorithm,grid,Algorithm,Grid,我有一张分成3x3网格的图像。网格由数组表示。每一列或每一行都可以旋转。例如,最上面一行[1,2,3]可以变成[3,1,2]等 阵列需要以以下方式结束: [1,2,3] [4,5,6] [7,8,9] 从以下几点开始: [5,3,9] [7,1,4] [8,6,2] 它总是可以解的,所以不需要检查 我尝试了一种长期的方法,寻找“1”,然后向左移动到正确的位置,依此类推2,3,。。。但最终会永远绕圈子 任何帮助都将不胜感激,即使你能给我一个起点/参考。。。我似乎想不透这一点。你的问题是,改变一
[1,2,3]
可以变成[3,1,2]
等
阵列需要以以下方式结束:
[1,2,3]
[4,5,6]
[7,8,9]
从以下几点开始:
[5,3,9]
[7,1,4]
[8,6,2]
它总是可以解的,所以不需要检查
我尝试了一种长期的方法,寻找“1”,然后向左移动到正确的位置,依此类推2,3,。。。但最终会永远绕圈子
任何帮助都将不胜感激,即使你能给我一个起点/参考。。。我似乎想不透这一点。你的问题是,改变一个值的动作会搞乱其他值。我怀疑有了足够的集合论,你就可以得出一个精确的解,但这里有一个启发法,它更有可能奏效 首先,请注意,如果一行中的每一个数字都属于该行,那么它要么很容易求解,要么交换了一些值。例如,[2,3,1]是微不足道的,而[3,2,1]是交换的 因此,比将1置于左上角“更容易”的目标是将所有行置于该状态。我们该怎么做?让我们看看专栏 如果列中每行包含一个数字,那么我们的状态与上面的类似(移位使数字位于正确的行中很简单,或者交换) 因此,我的建议是:
for column in columns:
if column is not one value from each row:
pick a value from column that is from a duplicate row
rotate that row
for column in columns:
as well as possible, shift until each value is in correct row
for row in rows:
as well as possible, shift until each value is in correct column
现在,这并不能保证起作用,尽管它将趋于接近,并且可以解决一些“几乎正确”的安排
因此,我接下来要做的是将其放入一个循环中,并在每次运行时记录状态的“散列”(例如,包含逐行读取的值的字符串)。然后在每次调用时,如果我检测到(通过检查散列是否是我们已经看到的散列)状态已经发生(因此我们重复我们自己),我将调用一个“随机洗牌”来混合事情
因此,我们的想法是,一旦我们接近,我们就有机会工作,当它陷入一个循环时,我们就会采取洗牌的方式
正如我所说,我相信有更聪明的方法可以做到这一点,但如果我绝望了,在谷歌上找不到任何东西,那就是我会尝试的启发式方法。。。我甚至不确定上述说法是否正确,但更普遍的策略是:
- 确定能够解决非常接近的解决方案的东西(从某种意义上说,找出谜题的“线性”位置)
- 试着重复一遍
- 重复时洗牌
这就是我在这里要说的。由于网格是3x3,您不仅可以找到解决方案,还可以找到解决问题的最小移动次数 为此,您需要使用 将每个配置表示为9个元素的线性阵列。每次移动后,您都会到达不同的配置。由于数组本质上是1-9之间的数字排列,因此只有9!=可能有362880种不同的配置
如果将每个配置看作一个节点,并将每个移动看作是一个边,我们可以在O(n)中探索整个图,其中n是配置的数目。我们需要确保,我们不会重新解决之前已经看到的配置,因此您需要一个已访问的阵列,该阵列将访问的每个配置标记为它所看到的
当您到达“已解决”配置时,您可以使用“父”数组追溯所采取的移动,该数组存储您来自的配置 还要注意的是,如果是4x4网格,问题会非常棘手,因为n等于(4x4)!=16! = 2.09227899 × 10^13. 但是对于像这样的小问题,你可以很快找到解决方案 编辑: TL;博士:- 保证能用,而且速度很快。362880对于今天的计算机来说是一个相当小的数字
- 它将找到最短的移动顺序