解决特定循环

时间:2014-03-25 05:35:24

标签: prolog

near(a1,b1).    near(b1,c1).    near(c1,d1).    near(d1,e1).    near(e1,f1).
near(f1,g1).    near(a1,a2).    near(a2,a3).    near(a3,a4).    near(a4,a5).
near(a5,a6).    near(a6,a7).    near(a7,a8).    near(a8,a9).    near(b1,b2).
near(b2,b3).    near(b3,b4).    near(b4,b5).    near(b5,b6).    near(b6,b7).
near(b7,b8).    near(b8,b9).    near(c4,d4).    near(d1,e4).    near(e4,f4).
near(f4,g4).    near(g4,h4).    near(g1,g2).    near(g2,g3).    near(g3,g4).
near(f4,f5).    near(f5,f6).    near(f6,f7).    near(f7,f8).    near(f8,f9).
near(a6,b6).    near(b6,c6).    near(a9,b9).    near(b9,c9).    near(c9,d9).
near(d9,f9).    near(f9,g9).    near(g9,h9).    near(h9,i9).

path(X,X).
path(X,Y):-
   near(X,Z), path(Z,Y),
   write(X),
   write('->'),
   write(Z).

maze(X,Y):-findall(X,path(X,Y),Path_List),write(Path_List).

这是寻找迷宫的方式。

我想要像这样打印

 Route1 [18] a1 -> b1 -> c1 -> d1 -> e1 -> f1 -> g1 -> g2 -> g3 -> g4 -> h4 -> h5 -> h6 -> h7 -> h8 -> h9 -> i9

并显示其他4条路线。

我认为使用剪切?或回溯。但我无法触及此代码..

1 个答案:

答案 0 :(得分:0)

通常,写出回溯算法实际解决问题所需的中间步骤是非常无用的技术。 path / 2 second子句产生的大部分输出都是' noise'。

这也是导致trace / 0作为Prolog的主要调试工具的动机。跟踪带有附加信息,如嵌套级别,必不可少以了解输出。

然后我建议摆脱路径/ 2中的写入,添加一个参数'带回来'路径,并写一个服务谓词打印:

path(X,X, [X]).
path(X,Y, [X|Cs]):-
    near(X,Z), path(Z,Y, Cs).

maze(X,Y):- forall(path(X,Y,Ps),writeln(Ps)).

?- maze(a1,i9).
[a1,b1,c1,d1,e4,f4,f5,f6,f7,f8,f9,g9,h9,i9]
[a1,b1,b2,b3,b4,b5,b6,b7,b8,b9,c9,d9,f9,g9,h9,i9]
[a1,a2,a3,a4,a5,a6,a7,a8,a9,b9,c9,d9,f9,g9,h9,i9]
[a1,a2,a3,a4,a5,a6,b6,b7,b8,b9,c9,d9,f9,g9,h9,i9]
true.

不是很吸引人,但肯定更有用。

请注意,路径/ 3(以及路径/ 2)将在循环存在的情况下永远循环 ...

使用pqGraphviz编辑,此代码段

maze_g(X,Y) :-
    graph_window(maze_g(X,Y),[]).

maze_g(X,Y,G) :-
    forall(path(X,Y,Ns),
        (maplist(make_node(G),Ns,Ps)
        ,nodes_chain(Ps,Cs)
        ,make_edges(G,Cs))).

后跟?- maze_g(a1,i9).,产量

a basic pqGraphviz rendering all paths