如何让Prolog深度优先搜索算法更深入到树中? (适用于推箱子)
How to make Prolog depth-first-search algorithm go deeper into the tree? (Applied to Sokoban)
我正在尝试使用深度优先搜索算法解决 Prolog 中的 Sokoban puzzle,但我无法深入搜索解决方案树。我只能探索第一层。
所有资源都在 Github(提出问题时链接到修订版),所以请随意探索和测试它们。我把规则分成几个文件:
- board.pl:包含与版块相关的规则:方向、社区、...
- game.pl:该文件规定了关于移动、有效位置的规则,...
- level1.pl: 为示例游戏定义棋盘、方块的位置和解方块。
- sokoban.pl:尝试实施dfs :(
我知道我需要在创建新状态时更深入,而不是检查它是否是最终状态并回溯...我需要继续移动,只移动一次是不可能到达最终状态的.
任何 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/4
、problem_solution/2
而不是 solve_dfs/4
、solve_problem/2
等
DCG 还可以帮助您在代码的某些地方更方便地描述列表。
+1 用于使用 Prolog 解决一个很好且具有挑战性的搜索问题!
我正在尝试使用深度优先搜索算法解决 Prolog 中的 Sokoban puzzle,但我无法深入搜索解决方案树。我只能探索第一层。
所有资源都在 Github(提出问题时链接到修订版),所以请随意探索和测试它们。我把规则分成几个文件:
- board.pl:包含与版块相关的规则:方向、社区、...
- game.pl:该文件规定了关于移动、有效位置的规则,...
- level1.pl: 为示例游戏定义棋盘、方块的位置和解方块。
- sokoban.pl:尝试实施dfs :(
我知道我需要在创建新状态时更深入,而不是检查它是否是最终状态并回溯...我需要继续移动,只移动一次是不可能到达最终状态的.
任何 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/4
、problem_solution/2
而不是 solve_dfs/4
、solve_problem/2
等
DCG 还可以帮助您在代码的某些地方更方便地描述列表。
+1 用于使用 Prolog 解决一个很好且具有挑战性的搜索问题!