如何让Prolog深度优先搜索算法更深入到树中? (适用于推箱子)

How to make Prolog depth-first-search algorithm go deeper into the tree? (Applied to Sokoban)

我正在尝试使用深度优先搜索算法解决 Prolog 中的 Sokoban puzzle,但我无法深入搜索解决方案树。我只能探索第一层。

所有资源都在 Github(提出问题时链接到修订版),所以请随意探索和测试它们。我把规则分成几个文件:

我知道我需要在创建新状态时更深入,而不是检查它是否是最终状态并回溯...我需要继续移动,只移动一次是不可能到达最终状态的.

任何 help/advice 将不胜感激,我一直在玩没有改进。

谢谢!

PS.- 啊!我正在使用 SWI-Prolog,以防它有所不同

PS.- 我真的是 Prolog 的新手,也许我正面临一个明显的错误,但这就是我在这里问的原因。

这很容易解决:在 sokoban.pl 谓词 solve_problem/2 中,您将解决方案限制为目标中单个元素的列表:

   solve_dfs(Problem, Initial, [Initial], [Solution])

相反,您可能是指:

    solve_dfs(Problem, Initial, [Initial], Solution)

因为一个解决方案可以包含很多步。

事实上,更好的搜索策略通常是迭代深化,您可以通过以下方式获得:

    length(Solution, _),
    solve_dfs(Problem, Initial, [Initial], Solution)

迭代加深是一种完全搜索策略,也是一种在相当一般的假设下最优策略。

除此之外,我建议您减少程序中大量不纯的 I/O 调用。您在屏幕上写东西的谓词太多了。

相反,专注于清晰的声明性描述,并将输出与解决方案的描述清楚地分开。事实上,让 toplevel 为您打印:描述解决方案的外观(您已经在这样做),并让 toplevel 将解决方案显示为变量绑定。此外,以声明的方式思考,并使用更好的名称,例如 dfs_moves/4problem_solution/2 而不是 solve_dfs/4solve_problem/2

DCG 还可以帮助您在代码的某些地方更方便地描述列表。

+1 用于使用 Prolog 解决一个很好且具有挑战性的搜索问题!