Search Prolog中的A*搜索
我尝试在prolog中实现一个解算器,作为一种尝试和学习该语言并利用本机回溯的方法。我在网上关注了一些,并编写了a*算法的这个简单版本 它所做的只是生成一个节点的所有子节点,并将它们固定在队列BFS样式的末尾(最终我打算用优先级队列来代替它以提高效率),并探索所有子节点,使用findall回溯解决方案 相关代码:Search Prolog中的A*搜索,search,prolog,Search,Prolog,我尝试在prolog中实现一个解算器,作为一种尝试和学习该语言并利用本机回溯的方法。我在网上关注了一些,并编写了a*算法的这个简单版本 它所做的只是生成一个节点的所有子节点,并将它们固定在队列BFS样式的末尾(最终我打算用优先级队列来代替它以提高效率),并探索所有子节点,使用findall回溯解决方案 相关代码: solve(State,Soln) :- f_function(State,0,F), search([State#0#F#[]],[],S), re
solve(State,Soln) :- f_function(State,0,F),
search([State#0#F#[]],[],S), reverse(S,Soln).
search([State#_#_#Soln|_], All, Soln) :-
goal(State).
search([B|R], All, S) :-
gen(B, R, Children),
%insert_all(Children,R,Open), %insertion sort option
append(R, Children, Open), %naive option
append(All, Children, Allnew),
search(Open, Allnew, S).
gen(State#D#_#A, R,C) :-
findall(Child#D1#F1#[Move|A],
( mover(State, Child, Move),
D1 is D + 1,
f_function(Child, D1, F1),
\+member(Child, R)
), C).
这段代码为简单的初始配置找到了解决方案,只需要几次移动就可以找到解决方案,但是对于更复杂的测试用例,它不会停止
为了避免无限循环,我保留了一个列表,列出所有曾经生成的状态(即使它们已经从队列中消失),并在添加它们之前对照该列表检查我的新子级
如果有人能告诉我为什么这不会停止,我会非常感激 尽早尝试针对
All
移动测试;否则,阻止任何无限循环都为时已晚。@ScottHunter在gen调用时对All进行测试,这是我在搜索过程中调用的第一个谓词。除非我误解了,它会在第二次搜索中检查,然后再添加新创建的cchildren,这样就不会有问题了;我不知道移动器(mover)或f_函数(function)是做什么的,但显然有什么东西阻止了你的查询停止。移动器(mover)是将移动应用于子对象以创建新子对象的函数,而f_函数是一个启发式函数,目前未在搜索中使用。我的直觉告诉我,问题出在算法的A*部分,但如果结果证明我发布的内容不是问题的根源,那么我就知道该在哪里查找问题了。你没有展示如何调用谓词。但是检查append/3
调用。如果其中任何一个有两个变量,他们可能会试图找到无数最终会失败的解决方案。另外,newAll
是一个原子,而不是一个变量。我认为这是一个输入错误?尝试尽早将测试移动到All
;否则,阻止任何无限循环都为时已晚。@ScottHunter在gen调用时对All进行测试,这是我在搜索过程中调用的第一个谓词。除非我误解了,它会在第二次搜索中检查,然后再添加新创建的cchildren,这样就不会有问题了;我不知道移动器(mover)或f_函数(function)是做什么的,但显然有什么东西阻止了你的查询停止。移动器(mover)是将移动应用于子对象以创建新子对象的函数,而f_函数是一个启发式函数,目前未在搜索中使用。我的直觉告诉我,问题出在算法的A*部分,但如果结果证明我发布的内容不是问题的根源,那么我就知道该在哪里查找问题了。你没有展示如何调用谓词。但是检查append/3
调用。如果其中任何一个有两个变量,他们可能会试图找到无数最终会失败的解决方案。另外,newAll
是一个原子,而不是一个变量。我想那是打字错误吧?