我必须修改以下Prolog程序,在程序图上实现迭代深化dfs搜索:
s(a, b).
s(b, c).
s(c, d).
s(a, d).
goal(d).
/* Solution is the inverse list of the visited node
from the start node Node and a goal node
if it is TRUE that:
path/3 predicate is TRUE (Solution is the inverse list
from the start node Node and a GoalNode)
and it is TRUE that GoalNode is a goal
*/
depth_first_iterative_deepening(Node, Solution) :-
path(Node, GoalNode, Solution),
goal(GoalNode).
/* Path/3 predicate generate, for the given initial node,
all the possibles acyclic paths of increasing
length
*/
/* BASE CASE: The shorter path from a node X to itself is Path=[X] */
path(Node, Node, [Node]).
/* GENERAL CASE: If I have to go from a start node X
to an end node Y and X != Y
[LastNode|Path] is the path from FirstNode and LastNode
if it is TRUE that:
1) Path is the path from FirstNode and OneButLast node
2) Exist an edge from OneButLast and LastNode
3) I have yet never visited LastNode
*/
path(FirstNode, LastNode, [LastNode|Path]) :-
path(FirstNode, OneButLast, Path),
s(OneButLast, LastNode),
not(member(LastNode, Path)).
path/3
谓词为给定的初始节点生成所有可能的非循环路径,增加长度,因此使用 {{1} } 谓词我根据长度(从最短的一个到最长的一个)生成从起始节点到结束节点的所有解决方案。
好的,所以我必须修改这个程序以限制解决方案的长度
我必须有这样的 depth_first_iterative_deepening/2
谓词:
depth_first_iterative_deepening2/3
其中depth_first_iterative_deepening2(Node, Max, Solution)
是受访节点的最大数量,因此Max
可以接受。
所以如果Solution
长度小于或等于Solution
值,Node
是从起始节点Solution
到目标节点的解决方案路径。
我曾尝试在之前的谓词中进行此更改,但它存在一些问题而且效果不佳:
Max
如何计算一个depth_first_iterative_deepening2(Node, Max, Solution) :-
path2(Node, GoalNode, Solution),
goal(GoalNode),
length(Solution, Length),
write(Length),
(Length =< Max).
(使用 Solution
谓词)进入目标节点的时间,我将这个解决方案的长度放入Length变量中并且我强制说这个解决方案的长度必须小于或等于变量的值path2/3
问题在于,如果找到的解决方案是正常的(其长度为Max
<=
值),它可以正常工作,但如果解决方案发现它不正常(长度为Max
那么>
值)就会出错:
Max
在查看跟踪时,似乎问题是当 [debug] ?- depth_first_iterative_deepening2(a,1,Solution).
24
ERROR: Out of local stack
Exception: (1,597,352) path2(a, _G4793274, _G4792038) ?
失败时,它会再次回忆 (Length =< Max)
谓词以找到另一种解决方案(它是相同的,因为path2/3
始终找到第一个调用的最短路径,因此它将找到导致失败的相同解决方案)
我希望如果 path2/3
检查失败,那么 (Length =< Max)
必须失败
我可以使用剪切来做到这一点吗?如果是这样,怎么样?
答案 0 :(得分:3)
你可以尝试
( (Length =< Max) ; (Length > Max), !, fail).
而不是
(Length =< Max).
答案 1 :(得分:0)
这是我前段时间提出的那个'技巧'。
将测试放在之前调用访问:
depth_first_iterative_deepening2(Node, Max, Solution) :-
length(Solution, Length),
Length =< Max,
path2(Node, GoalNode, Solution),
goal(GoalNode).