我是prolog的新手,我完全不明白为什么这段代码不起作用,所以我想找到一条路径及其距离,只需一次通过所有节点然后这里回到第一个节点是我做的:
distance(a,b,5).
distance(b,a,5).
distance(a,c,3).
distance(c,a,3).
distance(c,b,2).
distance(b,c,2).
head([H|List],H).
tail([H|List],List).
%Finding the Cycle
cycle(Node,Cycle) :-
distance(Node,Next,D),
cycle(Node,Next,[Node],Cycle).
cycle(Curr,Curr,Visited,Cycle) :-
reverse([Curr|Visited],Cycle).
cycle(Node,Curr,Visited,Cycle) :-
\+ member(Curr,Visited),
distance(Curr,Next,D),
cycle(Node,Next,[Curr|Visited],Cycle).
%Finding all the possible paths
find(Start,Cycle):-findall(Z,cycle(Start,Z),Cycle).
%Selecting only the cycles that contains all the nodes
path(Start,Cycle,DT):-find(Start,List),
path(Start,Cycle,DT,List).
path(Start,Cycle,DT,List):-head(List,Cycle),
tail(List,T),
distanceC(Cycle,DT),
pathL(Cycle),
path(Start,Cycle,DT,T).
%Calculating the distance of a path
distanceC([_],0).
distanceC([X,Y|Rest],DT):-distance(X,Y,D1),distanceC([Y|Rest],DT1), DT is D1 + DT1.
pathL(H):- length(H,Z),
Z==3.
当我开始递归时, path(Start,Cycle,DT,List)
无法正常工作
答案 0 :(得分:0)
一种方法:
% We need to know all the nodes to visit
% For our purpose the first node is known
% So we remove it
all_the_nodes_but_Start(Nodes, Start) :-
setof(A, B^C^distance(A,B,C), Nodes_h),
select(Start, Nodes_h, Nodes).
% the predicate
circuit(Start, Distance, Path) :-
% we fetch the nodes
all_the_nodes_but_Start(Nodes, Start),
% the working predicate
circuit(Start, Nodes, Start, 0, Distance, [Start], Path).
% @Start : the first and last node to visit
% @Cur_Nodes : the rest of the nodes to visit
% @Current_Node : the node where we are at present
% @Cur_Dist : ... I think that the rest is clear
circuit(Start, Cur_Nodes, Current_Node, Cur_Dist, Distance, Cur_Path, Path) :-
% we get a link
distance(Current_Node, Next_Node, Len),
% verify that it is not yet visited, getting the rest of nodes to visit
select(Next_Node, Cur_Nodes, Rest_Nodes),
% compute the distance
Next_Dist is Len + Cur_Dist,
% compute the next step with a neq node in the current path
circuit(Start, Rest_Nodes, Next_Node, Next_Dist, Distance, [Next_Node | Cur_Path], Path).
% When all the nodes are visited
circuit(Start, [], Current_Node, Cur_Dist, Distance, Cur_Path, Path) :-
% get back home
distance(Current_Node, Start, Len),
Distance is Cur_Dist + Len,
% getting the path
reverse([Start | Cur_Path], Path).
现在,我们得到:
?- circuit(a, Len, Path).
Len = 10,
Path = [a, b, c, a] ;
Len = 10,
Path = [a, c, b, a] ;
false.