有向图中的Prolog路线

时间:2016-11-20 09:46:11

标签: prolog

我对Prolog很陌生,想要创建一个程序,我可以在这里请求带有谓词“route(Startpoint,Endpoint,Route)”的路径。

到目前为止我的代码是:

% facts

connection(s1,s2).
connection(s2,s3).
connection(s3,s4).
connection(s4,s5).
connection(s5,s6).
connection(s6,s7).
connection(s7,s1).

% predicates

route1(X,Y,[X,Y]) :- connection(X,Y).
route1(X,Y,R) :- connection(X,Z), route1(Z,Y,RZ), R=[X|RZ].

route2(X,Y,[X,Y]) :- connection(Y,X).
route2(X,Y,R) :- connection(Z,X), route2(Z,Y,RZ), R=[X|RZ].

route(X,Y,R) :- route1(X,Y,R); route2(X,Y,R).

我的代码适用于某些路由,但不适用于某个循环(如上面的事实)。如何在Prolog中阻止多次访问某个路由?

例如,当我问“?- route1(s1,s4,R).”时,Prolog首先向我提供了正确的路线“[s1,s2,s3,s4]”,但它也为我提供了其他路线,例如“[s1, s2, s3, s4, s5, s6, s7, s1, s2, s3, s4]”,“{{ 1}}“等等。

提前致谢!

1 个答案:

答案 0 :(得分:2)

你可以写:

route1(X,Y,[X,Y]) :- connection(X,Y).
route1(X,Y,R) :- connection(X,Z), route1(Z,Y,RZ),R=[X|RZ],       
                 sort(R,R1),length(R,N),length(R1,N1),
                 (N>N1->!,fail ;true). 

sort/2删除重复项,因此如果您希望解决方案不重复排序列表,并且输出列表必须具有相同的长度。

?- route1(s1,s4,R).
R = [s1, s2, s3, s4] ;
false.

另一种方法是:

route1(X,Y,R):-route1(X,Y,[],R).

route1(X,Y,_,[X,Y]) :- connection(X,Y).
route1(X,Y,L,R) :- connection(X,Z),\+member(Z,L),
                   route1(Z,Y,[Z|L],RZ),R=[X|RZ]. 

示例:

?- route1(s1,s4,R).
R = [s1, s2, s3, s4] ;
false.