link(entry, a).
link(a, b).
link(b, c).
link(c, d).
link(d, e).
link(b, e).
link(e, f).
link(f, c).
link(f, exit).
route(1, 2) :-
member(1, [entry,a,b,c,d,e,f,exit]),
member(2, [entry,a,b,e,f,exit]).
route(X, Z, [entry,a,b,c,d,e,f,exit]) :- route(X, Z,[R],[entry,a,b,c,d,e,f,exit]).
route(X, Z, [exit,f,e,d,c,b,a,entry], [entry,a,b,c,d,e,f,exit]) :-
reverse(X, Y, [exit,f,e,d,c,b,a,entry], [entry,a,b,c,d,e,f,exit]),
route(Y, Z),
write(X).
尽管阅读了几个小时,我还是很难理解如何让我的程序生成并在控制台窗口中显示列出的路径。有谁能提供建议吗?我基本上没有编程经验,prolog可能是我的大部分知识,这还不够。
route(X, Y, [X, Y]) :- link(X,Y).
route(X, Y, [X | TY]) :-
link(X, T),
route(T, Y, TY).
对于如上所述的route
,以下代码按长度的递增顺序搜索路径。
?- length(X, _), route(entry,exit, X).
X = [entry, a, b, e, f, exit] ;
X = [entry, a, b, c, d, e, f, exit] ;
X = [entry, a, b, e, f, c, d, e, f, exit] ;
X = [entry, a, b, c, d, e, f, c, d, e, f, exit] ;
X = [entry, a, b, e, f, c, d, e, f, c, d, e, f, exit]
由于我们并没有将route
谓词约束为不允许重复节点,所以我们在路径的更高长度上有循环。
编辑:以下工作原理SWI Prolog检查您的系统是否具有dif/2
。在这里使用maplist
可以进行增加路径长度的搜索。
route(X, Y, [X, Y]) :- link(X,Y).
route(X, Y, [X|TY]) :-
link(X, T),
maplist(dif(X), TY), % X is different from all nodes in TY
route(T, Y, TY).
如果没有dif
,请在route(T, Y, TY)
之后使用+ member(X, TY)
这将提供
?- route(entry, exit, X).
X = [entry, a, b, e, f, exit] ;
X = [entry, a, b, c, d, e, f, exit] ;
在两个解决方案之后,它将无休止地循环。如果你想阻止这种情况的发生,你可以将路径的长度限制为现有节点的数量
?- between(2, 8, N), length(X, N), route(entry, exit, X).
N = 6,
X = [entry, a, b, e, f, exit] ;
N = 8,
X = [entry, a, b, c, d, e, f, exit] ;
false.