prolog中的循环路线程序

时间:2016-11-21 20:56:56

标签: prolog

我在prolog中创建了一个程序,它应该为我提供两个站之间的所有可能路径。在每条路线中,每个车站只能访问一次。到目前为止我的代码是:

% facts

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

% predicates

direction1(X,Y) :- connection(X,Y).
direction2(X,Y) :- connection(Y,X).

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

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

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

问题是prolog并没有给我所有路线,例如当我要求路线[s1,s4,R]时,prolog没有给我路线[s1,s2,s3, S4]。我认为这是由" + direction1(X,Y)"和" +方向2(X,Y)"。但我需要这样做以防止prolog在一条路线中多次访问一个电台。任何想法如何解决这个问题?

enter image description here enter image description here 提前谢谢!

1 个答案:

答案 0 :(得分:1)

微创修复方法是删除您正确识别为此失败源的\+direction1(X,Y),并在\+ member(X, L)的定义中添加另一个route1/4防护。

编辑:以上是不够的。这是对整个事物的更清晰的重写,具有更易读的格式和变量名称:

route1(X,Y,R):- route1(X,Y,[X],R).  % note that X is visited immediately
route1(X,Y,_,[X,Y]) :- direction1(X,Y).
route1(X, Y, Visited, Route) :-
    direction1(X, Z),
    Z \= Y,
    \+ member(Z, Visited),
    route1(Z, Y, [Z|Visited], Route1),
    Route = [X|Route1].

然后,您应该统一路线谓词的两个变体:其中一个仅查找仅沿“方向1”边缘的路线,而另一个仅沿“方向2”边缘找到路线。通常,您希望能够在任何方向上遍历任何边缘。