问题标签 [sliding-tile-puzzle]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 用Java解决n-puzzle
我正在尝试实现一个程序来解决n-puzzle 问题。
我用 Java 编写了一个简单的实现,它的问题状态由表示图块的矩阵表征。我还能够自动生成给出起始状态的所有状态图。然后,在图表上,我可以做一个 BFS 来找到目标状态的路径。
但问题是我的内存不足,我什至无法创建整个图表。我尝试使用 2x2 瓷砖,它可以工作。还有一些 3x3(这取决于起始状态和图中的节点数)。但总的来说这种方式是不适合的。
所以我尝试在运行时生成节点,同时搜索。它可以工作,但速度很慢(有时几分钟后它仍然没有结束,我终止了程序)。
顺便说一句:我只给出可解决的配置作为起始状态,并且我不创建重复的状态。
所以,我无法创建图表。这导致了我的主要问题:我必须实现 A* 算法并且我需要路径成本(即每个节点到起始状态的距离),但我认为我无法在运行时计算它。我需要整个图表,对吗?因为 A* 没有遵循图的 BFS 探索,所以我不知道如何估计每个节点的距离。因此,我不知道如何执行 A* 搜索。
有什么建议吗?
编辑
State:
Solver:
基本上这就是我所做的:
-有一个. 元素 ( ) 是根据 排序的,它计算, 其中是路径成本,是启发式(错位图块的数量)。
- 我给出了起始配置并寻找所有的后继者。
- 如果一个后继者还没有被访问过(即如果它不在全局集合中),我将它添加到队列中,并将当前状态设置为其父级和路径成本。
- 出列并重复。
我认为它应该起作用,因为:
- 我保留所有访问过的状态,所以我没有循环。Solver
solve
SortedSet
States
Comparator1
f(n) = g(n) + h(n)
g(n)
h(n)
States
States
parent's path + 1
- 另外,不会有任何无用的优势,因为我会立即存储当前节点的后继节点。例如:如果从 AI 可以到 B 和 C,并且从 BI 也可以到 C,就不会有边 B->C(因为每条边的路径成本为 1,并且 A->B 比 A 便宜->B->C)。
- 每次我选择用最小值扩展路径时f(n)
,根据 A*。
但它不起作用。或者至少,几分钟后它仍然找不到解决方案(我认为在这种情况下需要很多时间)。
如果我在执行 A* 之前尝试创建树结构,我会用完构建它的内存。
编辑 2
这是我的启发式函数:
如果我使用一个简单的贪心算法,它们都可以工作(使用曼哈顿距离真的很快(大约 500 次迭代才能找到解决方案),而错位瓷砖的数量大约需要 10k 次迭代)。如果我使用 A*(也评估路径成本),它真的很慢。
比较器是这样的:
编辑 3
有一点错误。我修复了它,现在 A* 可以工作了。或者至少,对于 3x3,如果仅通过 700 次迭代就可以找到最佳解决方案。对于 4x4,它仍然太慢。我将尝试使用 IDA*,但有一个问题:使用 A* 需要多长时间才能找到解决方案?分钟?小时?我离开它10分钟,它并没有结束。
java - 曼哈顿距离 A*
我正在使用 A* 搜索算法并使用曼哈顿距离作为启发式来实现 NxN 难题求解器,但我遇到了一个奇怪的错误(?),我无法理解。
考虑这些谜题(0 元素是空格):(
初始)
1 0 2
7 5 4
8 6 3
(目标)
1 2 3
4 5 6
7 8 0
从初始状态达到解决方案的最小移动次数是 11。但是,我的求解器在 17 次移动中达到目标。
这就是问题所在 - 我的谜题求解器主要以正确(最少)的移动数解决可解决的谜题,但对于这个特定的谜题,我的求解器超出了最小移动数,我认为我已经将问题确定为计算错误在这种特殊情况下的曼哈顿距离。
在此链接中,您可以看到我的求解器在做什么(在右侧)以及一个久经考验的求解器在做什么(Brian Borowski 的优秀求解器,可在此处获得)。
在第一步中,Brian 的求解器立即选择将元素 5 向上推的解决方案,但我的求解器有其他想法,并且在堆栈跟踪(在链接上给出)上,我的求解器选择将 2 推到左侧的解决方案(因为该板的曼哈顿距离越小,板子在优先队列的前面)。我看不出问题出在哪里,也不能怪我的曼哈顿距离计算,因为它正确地解决了许多其他 3x3 难题。
以下是我计算给定 Board 的曼哈顿距离的方法:
如果您有任何见解或想法,我将不胜感激。
如果需要任何其他代码,我会立即发布。
artificial-intelligence - n 谜题解中的空白位置是否会影响有效谜题集?
我的 n-puzzle 求解器有问题。以为它有效,但事实证明它正在解决无法解决的难题。我试图追踪它,但这是很多追踪,到目前为止我没有看到任何作弊行为。我想我了解确定溶解度的算法,并且我的实现与网络上一些示例的奇/偶校验一致......也就是说,当我计算给定瓷砖之后小于的瓷砖数量时它,对于每个图块,然后添加空白图块的行索引,我得到的奇数或偶数与其他人得到的相同。
于是,我产生了一个念头。在我的 8 谜题模型中,我的解决方案状态是:
而不是
或者
就像在其他一些配方中一样。这会影响哪些谜题是可解的,哪些不是吗?
谢谢!
z。
python - Python中的无限循环和递归
我正在实施迭代深化深度优先搜索,以找到解决8 难题的解决方案。我对自己找到实际的搜索路径不感兴趣,而只是计算程序运行需要多长时间。(我还没有实现定时功能)。
但是,我在尝试实现实际搜索功能时遇到了一些问题(向下滚动查看)。我粘贴了到目前为止所有的代码,所以如果你复制并粘贴它,你也可以运行它。这可能是描述我遇到的问题的最佳方式......我只是不明白为什么我在递归期间会出现无限循环,例如在拼图 2(p2)的测试中,第一次扩展应该产生一个解决方案。我认为这可能与未在其中一行代码前面添加“Return”有关(下面对此进行了评论)。当我添加返回时,我可以通过拼图 2 的测试,但是像拼图 3 这样更复杂的东西失败了,因为现在代码似乎只扩展了最左边的分支......
一直在这几个小时,放弃希望。如果您能指出我的错误,我将非常感谢您对此有另一种看法。谢谢!
function - 在 Prolog 中使用最佳优先搜索解决 8 个难题
正如标题所说,我必须制作一个 prolog 程序,使用最佳优先搜索解决 8 个难题,我是 Prolog 和 AI 的新手,所以我很难过。
现在我所拥有的是移动规则:
(我知道使用列表有一种更简单的方法,但这对我有用)
我在互联网上找到的最好的第一个代码:http ://www.cs.unm.edu/~luger/ai-final/code/PROLOG.best.html
但是在最好的第一个代码中,有一个不运行的启发式函数:
我假设因为它没有在任何地方定义,我需要自己定义它,因为启发式会根据问题而改变。
所以我坚持使用“不合适的瓷砖”启发式来解决 8 谜题,因为它听起来比曼哈顿距离或其他任何东西更容易编码。但现在我被困在如何编程上,我到处搜索如何比较列表和如何添加变量,我有点做了这个,我不知道这是否可行:
我的想法是它搜索开始列表的每个元素并将其与目标列表进行比较,然后如果它们不同,则将 1 添加到 H,即 H 表示不合适的瓷砖数量。
对于我还定义了“在同一个地方的瓷砖规则”:
但当然我得到一个“错误:启发式/3:参数没有充分实例化”,我认为这意味着我从未初始化 H.
我不知道其余代码实际上是如何工作的,尽管我知道最好的第一个算法就像广度优先,但它根据启发式对队列进行排序,而不是仅仅添加它。
我的问题是: - 我是在正确的轨道上,还是我完全看错了那里的“启发式”功能是什么意思?- 如何初始化 H?- 我的“启发式”函数代码在语法上是否正确?
很抱歉发了这么长的帖子,但规则确实说我应该提供大量信息。我希望你能帮助我,感谢任何帮助,所以如果你知道这样做的任何其他方式,请随时发布它们,我是菜鸟。
提前致谢。
c - 有限的 DFS、幻灯片拼图应用、寻路
我正在编写简单的幻灯片拼图(Loyd)求解器。我想解决尺寸为 3 x 3 及以上的任何给定的可解决拼图配置。但是我陷入了递归的实现。我有树和堆栈。
堆栈具有静态大小。现在我有方法,正在寻找解决方案。但我不知道如何实现递归以及如何存储创建的节点并查找路径。到目前为止,我得到了:
那么我应该做什么,例如。y = 0,所以我无法创建新的左侧配置。我需要回去。但是当我这样做时,我陷入了无限循环。请注意,我想解决任何大小大于 2 的谜题。
这是我在堆栈中搜索重复项的函数:
任何人都可以帮忙吗?感谢您的时间。:)
prolog - 8-puzzle 在 prolog 中有一个使用曼哈顿距离的解决方案
8-puzzle 将由一个 3x3 的列表位置列表表示,其中空框将由值 9 表示,如下所示: [[9,1,3],[5,2,6],[4, 7,8]]
可能解:8 拼图的初始位置只有一半是可解的。有一个公式可以让您从一开始就知道您是否可以解决难题。要确定是否可以解决一个 8 难题,对于每个包含值 N 的方格,计算当前单元格之后有多少小于 N 的数字。以初始状态为例:
- 1 没有小于的数字 = 0
- 空 (9) - 必须随后 3,5,2,6,4,7,8 = 7
- 3 有 = 1 到 2
- 5 随后到 2,4 = 2
- 2 它下面没有数字发生 = 0
- 6 随后是 4 = 1
- 4 没有小于的数字 = 0
- 7 后面没有次要数字 = 0
- 8 没有小于的数字 = 0
之后,我们计算空的位置和位置(3.3)之间的曼哈顿距离。对于上面的例子,空框在位置(1.2),所以曼哈顿距离即:d = abs(3-1) + abs(3-2) = 3 最后将所有计算值相加。如果结果是偶数,则表示谜题是可解的,但未解则为奇数。0 +7 +1 +2 +0 +1 +0 +0 +0 +3 = 14
该解决方案旨在创建一个知识库,其中包含板上数字的所有可能状态,我们将看到在当前位置之后有多少小于 N 的数字。
这是我的代码:
问题是我犯了一个错误,因为在某些情况下我可以有多个选择,例如>:
posC(C,Pc) 的正确解是 posC(3,1),即 1;但是还有其他一些后果有时会导致错误的输出......我在我的代码中做错了什么以及如何更改它?
java - 8 谜题:可解性和最短解
我使用广度优先搜索构建了一个 8 谜题求解器。我现在想修改代码以使用启发式方法。如果有人能回答以下两个问题,我将不胜感激:
可解性
我们如何决定一个 8 谜题是否可解?(给定一个起始状态和一个目标状态)这是维基百科所说的:
不变量是所有16个方格排列的奇偶性加上右下角空方格的出租车距离(行数加列数)的奇偶性。
不幸的是,我无法理解那是什么意思。理解起来有点复杂。有人可以用更简单的语言解释吗?
最短的解决方案
给定一个启发式,是否保证使用 A* 算法给出最短的解决方案?更具体地说,打开列表中的第一个节点是否总是有一个深度(或如此胖的移动次数),它是打开列表中所有节点的深度中的最小值?
启发式是否应该满足某些条件才能使上述陈述为真?
编辑:一个可接受的启发式方法如何总是提供最佳解决方案?我们如何测试启发式是否可以接受?
我将使用此处列出的启发式方法
来自 Eyal Schneider 的澄清:
prolog - 解决 8 个难题启发式
我对 prolog 很陌生,并且在使用 8 个谜题启发式方法时遇到了麻烦。我不确定如何比较两个列表(目标和开始)并找出我的 h 值。我要做的是发送 compare_list 两个列表目标并开始。它应该比较每个头,如果它们不相等,则在总数中加 1,否则递归调用它。我不确定如何在 prolog 中执行 if else 语句。
c++ - 解决 8 谜题游戏
我正在尝试用 C++ 编写一个 8 拼图游戏求解器,但在执行此操作时遇到了很多问题。该程序目前正在运行,但要解决这个难题需要太多步骤。我的意思是,有时它可以找到最佳解决方案,有时它需要多达 400 步才能解决。我的主要疑问如下。想象一下我有这个图表(这只是一个草稿):
我使用曼哈顿距离作为启发式函数。在第一步之后,我们有两个状态,其中 f(n)=5,所以我扩展了树。展开后,我仍然得到两个 f(n)=2 的状态。这是我的疑问..我是否还需要扩展树直到我得到一个唯一的最低 f(n)?
提前致谢!