路由进入无限循环序言
Route goes infinite loop prolog
刚开始做序言并练习路线问题
train(a,b).
train(b,a).
train(b,c).
train(c,b).
route(X,Y,[]) :-
train(X,Y)
; train(Y,X).
route(X,Y,[H|T]) :-
route(X,H,[]),
route(H,Y,T).
通过这样做 route/3 第一个规则给出了两个直接相连的地方,一个空集表示有一条路线。第二条规则规定了从一个地方到另一个地方有中间地点的情况。但是当我查询这个时,我得到了一条循环路线。
有人说有一个辅助谓词 visited_route/4 来跟踪已经访问过的地方,但不知道这种方式是如何工作的。提示或示例会有所帮助。
您当前解决方案的问题是 Prolog 求解器会生成无限轨迹,例如 [a,b,a,b,a,b,a...],永远不会到达终点。
您可能想要做的是排除 X、Y 或 H 是 T 成员的情况(这可能是 visited_route/4 谓词)。这样,您将永远不会两次通过同一个节点。
编辑
我坐下来更新了我的 Prolog 知识,创建了这样的代码,它似乎有效:
train(a,b).
%train(b,a). Your predicate is symmetric, you don't need to specify both directions
train(b,c).
%train(c,b).
train(c,d).
train(c,e).
train(d,f).
train(e,f).
visited_route(X, Y, [], V) :-
( train(X,Y) ; train(Y,X) ),
not(member(Y, V)).
visited_route(X, Y, [H | T], V) :-
visited_route(X, H, [], [X | V]),
visited_route(H, Y, T, [X | V]).
route(X,Y,R) :-
visited_route(X, Y, R, []).
Visited route 有一个额外的列表,其中包含从 X 到 Y(不包括 Y)的途中访问的所有节点。当求解器在第一个 visited_route 谓词中找到从 X 到 Y 的路径时,它会检查该路径是否不经过已经访问过的节点,如果是则丢弃候选节点。
刚开始做序言并练习路线问题
train(a,b).
train(b,a).
train(b,c).
train(c,b).
route(X,Y,[]) :-
train(X,Y)
; train(Y,X).
route(X,Y,[H|T]) :-
route(X,H,[]),
route(H,Y,T).
通过这样做 route/3 第一个规则给出了两个直接相连的地方,一个空集表示有一条路线。第二条规则规定了从一个地方到另一个地方有中间地点的情况。但是当我查询这个时,我得到了一条循环路线。
有人说有一个辅助谓词 visited_route/4 来跟踪已经访问过的地方,但不知道这种方式是如何工作的。提示或示例会有所帮助。
您当前解决方案的问题是 Prolog 求解器会生成无限轨迹,例如 [a,b,a,b,a,b,a...],永远不会到达终点。
您可能想要做的是排除 X、Y 或 H 是 T 成员的情况(这可能是 visited_route/4 谓词)。这样,您将永远不会两次通过同一个节点。
编辑
我坐下来更新了我的 Prolog 知识,创建了这样的代码,它似乎有效:
train(a,b).
%train(b,a). Your predicate is symmetric, you don't need to specify both directions
train(b,c).
%train(c,b).
train(c,d).
train(c,e).
train(d,f).
train(e,f).
visited_route(X, Y, [], V) :-
( train(X,Y) ; train(Y,X) ),
not(member(Y, V)).
visited_route(X, Y, [H | T], V) :-
visited_route(X, H, [], [X | V]),
visited_route(H, Y, T, [X | V]).
route(X,Y,R) :-
visited_route(X, Y, R, []).
Visited route 有一个额外的列表,其中包含从 X 到 Y(不包括 Y)的途中访问的所有节点。当求解器在第一个 visited_route 谓词中找到从 X 到 Y 的路径时,它会检查该路径是否不经过已经访问过的节点,如果是则丢弃候选节点。