我在序言中有此数据库,我想计算:
1)flightTime(开始,目的地,时间,路径),以计算所有可能路径的飞行时间。
2)pathLength(Path,Length)计算给定路径的长度(路径将是列表)。
3)shortestPath(开始,目标),以打印两个机场之间的最短路径。
flightPath(fco,jfk,10,4321).
flightPath(fco,sin,12,5671).
flightPath(sin,nrt,8,3467).
flightPath(lju,fco,4,2521).
flightPath(lju,cdg,9,8653).
flightPath(cdg,fco,3,1989).
flightPath(cdg,jfk,8,5461).
flightPath(cdg,lax,17,9321).
flightPath(jfk,lax,6,4141).
flightPath(lax,nrt,6,5743).
transferTime(fco,2).
transferTime(sin,1).
transferTime(lju,3).
transferTime(cdg,1).
transferTime(jfk,4).
transferTime(lax,4).
transferTime(nrt,1).
connection(X,Y) :- flightPath(X,Y,_,_);(flightPath(X,Z,_,_),connection(Z,Y)).
我设法仅一站就获得了直接航班和间接航班的flightTime,但同样,我需要所有可能的路径。
flightTime(X,Y,T,P) :-
flightPath(X,Y,T,_),
P = Y; ( flightPath(X,Z,T1,_),
flightPath(Z,Y,T2,_),
transferTime(Z,T3),
T is T1+T2+T3, P = Z
).
为简单起见,我制作了一个显示所有可能路径的图形:
答案 0 :(得分:4)
这是我的解决方法:
flightTime(X,Y,T,[Y]):- flightPath(X,Y,T,_).
flightTime(X,Y,T,[Z|TL]):-
flightPath(X,Z,T2,_),
transferTime(Z,T3),
flightTime(Z,Y,T1,TL),
T is T1+T2+T3 .
pathLength(Path, Lentgh):- length(Path,Lentgh).
shortestPath(X,Y,P):- once( (pathLength(P,_),flightTime(X,Y,_,P)) ).
对于flightTime/4
,解决方案只是为了找到所有可能的路径而进行的递归。 pathLength/2
的前进也没什么特别的。
示例:
?- flightTime(X,Y,T,L).
X = fco,
Y = jfk,
T = 10,
L = [jfk] ;
X = fco,
Y = sin,
T = 12,
L = [sin] ;
X = sin,
Y = nrt,
T = 8,
L = [nrt] ;
X = lju,
Y = fco,
T = 4,
L = [fco]
... and continues
现在找到最短路径的方法有很多。最简单,最明显的方法是使用类似以下内容的
存储所有路径->路径的长度编码->按长度排序-> 选择最小长度的路径:
custom_length(L,Len-L):- length(L,Len).
shortestPath2(X,Y,P):-
findall(P1,flightTime(X,Y,_,P1), L),
maplist(custom_length,L,L1),
sort(L1,[_-P|_]).
示例:
?- shortestPath2(fco,nrt,P).
P = [sin, nrt].
它很好用,但是想象一下,findall/3
会生成的列表对于在两个站点之间具有多条路径的大型图可能很大,然后进行排序可能会非常耗时...
最好的做法是让length生成最小的路径长度:
shortestPath(X,Y,P):- once( (pathLength(P,_),flightTime(X,Y,_,P)) ).