使用列表列表的Prolog最短路径

时间:2013-12-03 02:55:26

标签: prolog path-finding nested-lists

好吧,所以我最近一直在努力教自己Prolog,并且很难找到列表列表中两个(已定义)元素之间的“最短路径”。它可能不是表示网格或找到最短路径的最有效方式,但我想以这种方式尝试。

例如:

[[x,x,x,x,x,x,x],
 [x,1,o,o,o,o,x],
 [x,-,-,-,o,-,x],
 [x,-,-,o,o,-,x],
 [x,o,o,o,o,2,x],
 [x,o,-,-,o,o,x],
 [x,x,x,x,x,x,x]]

我可以做出一些假设(在路径寻找之前给出或基于检查):

  • 网格是正方形
  • 他们将永远存在从1到2
  • 的路径
  • '1'可以通过除' - '(墙壁)或'x'(边框)
  • 之外的任何内容

目标是让'1'找到'2'的最短路径。

在以下情况中:

[[x,x,x,x,x,x,x],
 [x,o,o,1,o,o,x],
 [x,-,o,o,o,-,x],
 [x,-,o,-,o,-,x],
 [x,o,o,2,o,o,x],
 [x,o,-,-,-,o,x],
 [x,x,x,x,x,x,x]]

注意,有两条“最短路径”:

[d,l,d,d,r]

[d,r,d,d,l]

在Prolog中,我正在尝试创建该函数(如果这是正确的名称):

shortestPath(Grid,Path)

我已经创建了一个函数来查找元素'1'和'2',以及一个验证网格是否有效的函数,但是我甚至无法开始构建一个函数来查找最短的路径'1'到'2'。

给定一个定义的Grid,我希望Path的输出是最短的路径。或者,给定一个定义的Grid和一个定义的Path,我想检查它是否确实是一条最短的路径。

非常感谢帮助!如果我错过了什么,或者不清楚,请告诉我!

1 个答案:

答案 0 :(得分:1)

未优化的解决方案

shortestPath(G, S) :-
    findall(L-P, (findPath(G,P), length(P,L)), All),
    keysort(All, [_-S|_]).

findPath(G, Path) :-
    pos(G, (Rs,Cs), 1),
    findPath(G, [(Rs,Cs)], [], Path).

findPath(G, [Act|Rest], Trail, Path) :-
    move(Act,Next,Move),
    pos(G, Next, Elem),
    (   Elem == 2
    ->  reverse([Move|Trail], Path)
    ;   Elem == o
    ->  \+ memberchk(Next, Rest),
        findPath(G, [Next,Act|Rest], [Move|Trail], Path)
    ).

move((R,C), (R1,C1), M) :-
    R1 is R-1, C1 is C  , M = u;
    R1 is R  , C1 is C-1, M = l;
    R1 is R+1, C1 is C  , M = d;
    R1 is R  , C1 is C+1, M = r.

pos(G, (R,C), E) :- nth1(R, G, Row), nth1(C, Row, E).

grid(1,
[[x,x,x,x,x,x,x],
 [x,1,o,o,o,o,x],
 [x,-,-,-,o,-,x],
 [x,-,-,o,o,-,x],
 [x,o,o,o,o,2,x],
 [x,o,-,-,o,o,x],
 [x,x,x,x,x,x,x]]).

grid(2,
[[x,x,x,x,x,x,x],
 [x,o,o,1,o,o,x],
 [x,-,o,o,o,-,x],
 [x,-,o,-,o,-,x],
 [x,o,o,2,o,o,x],
 [x,o,-,-,-,o,x],
 [x,x,x,x,x,x,x]]).