具有优先级的Prolog寻路

时间:2014-12-07 09:59:24

标签: prolog path-finding pathfinder

我有一个编写Prolog程序的任务,该程序列出了两个地下(地铁)站之间的路径,但是它应该支持更少线路的路径(它应该在切换线路之前尽可能长地保持在同一条线路上)。

我已经提出了一个模拟场景和这段代码,虽然它正确地列出了一些路径(我知道我仍然需要对循环检测进行编码),但不会优先考虑相同的线段。

我的路由器是:

route(X,Y,[drive(X,Y,L)],_) :- road(X,Y,L).

%route(From, To, Directions, Lines_Visited).
route(X,Y,[drive(X,Z,L)|R],Ls) :-
    take(Ls,L,_),     %prioritise same-line paths
    road(X,Z,L),  
    route(Z,Y,R,Ls), !.

route(X,Y,[drive(X,Z,L)|R],Ls) :-
    road(X,Z,L),       %if no same-line pathes exist, try different line
    route(Z,Y,R,[Ls|L]).

其中take / 3是

take([H|T], H, T).

一个测试场景是:

road(a,b,x).
road(b,c,x).
road(c,d,x).
road(d,e,x).
road(e,f,x).
road(b,f,y).
road(f,g,x).

%a - b - c - d - e - f - g
%    |_______________|

如果我尝试路线(a,f,X)。我得到了路径a - > b - > f,其改变线一次,然后是单线路径a-> b-> c-> d-> e-> f。

显然我的优先次序不起作用,我无法想出一种不同的方法。有人可以提出一些指示,并指出我更有效地解决这个问题的方向吗?

1 个答案:

答案 0 :(得分:1)

您的代码需要进行大量重组。基本上,你根本没有使用当前路径中使用哪一行的信息(take / 3没用,因为它没有绑定第三个参数)。这是我对此的看法。添加循环检测,现在您已经“看到了迄今为​​止”的节点......

%route(From, To, Directions, Lines_Visited).
route(X,X,RPath,Path) :- reverse(RPath,Path).
route(X,Y,[Last|R],Ls) :-
    Last = [drive(X,Z,L)|_], %prioritise same-line paths
    road(X,Z,L),  
    route(Z,Y,R,Ls).
route(X,Y,PathSoFar,Ls) :-
    road(X,Z,L),       %if no same-line pathes exist, try different line
    route(Z,Y,[road(X,Z,L)|PathSoFar],Ls).

试验:

?- route(a,f,[],X).
X = [road(a, b, x), road(b, c, x), road(c, d, x), road(d, e, x), road(e, f, x)] ;
X = [road(a, b, x), road(b, f, y)] ;
false.