Prolog中最大深度约束的迭代加深

时间:2013-05-13 11:16:25

标签: prolog

我必须修改以下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) 必须失败

我可以使用剪切来做到这一点吗?如果是这样,怎么样?

2 个答案:

答案 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).