使用prolog在网格中的最短路径

时间:2014-11-02 04:38:28

标签: path prolog dijkstra shortest

对不起第一个问题,我是新来的......我对代码进行了清理。问题是: 我有一个带有路径和障碍物的方格。我想找到从一个点到另一个点的最短路径。这是人工智能的一部分。当路径太大时,我看不到bash上的整个点列表,但是在游戏中,行进这条路径的角色,它并不是最短的路径。所以,我的问题是,如何更改此代码以解决最短路径。非常感谢你!

mov(X1,Y1,X2,Y2):-
   pos(X1,Y1), X2 is X1 , Y2 is Y1+1 ,pos(X2,Y2).
mov(X1,Y1,X2,Y2):-
   pos(X1,Y1), X2 is X1 , Y2 is Y1-1 ,pos(X2,Y2). 
mov(X1,Y1,X2,Y2):-
   pos(X1,Y1), X2 is X1+1 , Y2 is Y1 , pos(X2,Y2).
mov(X1,Y1,X2,Y2):-
   pos(X1,Y1), X2 is X1 -1 , Y2 is Y1 , pos(X2,Y2).

path(X1,Y1,X2,Y2,Path) :-
   travel(pos(X1,Y1),pos(X2,Y2),[pos(X1,Y1)],Q),
   reverse(Q,Path).

travel(pos(X1,Y1),pos(X2,Y2),P,[pos(X2,Y2)|P]) :-
   mov(X1,Y1,X2,Y2).
travel(pos(X1,Y1),pos(X2,Y2),Visited,Path) :-
   mov(X1,Y1,X,Y),
   pos(X,Y) \== pos(X2,Y2), 
   \+member(pos(X,Y),Visited),
   travel(pos(X,Y),pos(X2,Y2),[pos(X,Y)|Visited],Path).

1 个答案:

答案 0 :(得分:1)

首先是Prolog的一些建议。

  1. member/2是内置的,您不必定义它。
  2. ISO否定为\+,而不是not/1
  3. 为了提高效果,memberchk/2节拍member/2
  4. 我在您的代码中看到了很多foo(X,Y) :- X == Y, ...。如果你只是说foo(X,X)并且省去了这样的明确测试的麻烦,那就好了,除非你要做一个条件表达式以避免选择点或什么。
  5. 此代码中的大量削减。削减和错误往往是很好的朋友,因为削减可以通过阻止它被执行来破坏看似合理的代码。
  6. 如果我必须解决这个问题,我想将最短路径逻辑与网格遍历逻辑分开。您永远无法对此进行调试,即使您这样做,您所拥有的也是无法修改的无法读取的代码块之一。很明显,由于您在路径查找逻辑中嵌入了遍历逻辑,因此您的术语数量激增。将它们分成两个单独的步骤,您可能会发现您可以获得较小的部分,您可以进行有意义的测试和调试。无论语言如何,这都是编程的好方法:如果需要更改网格结构或使寻路更加智能或复杂,您会怎么做?保持碎片粒度总是有助于管理变更。

    至于S.O.礼仪,这不是很好:你应该谈论什么不起作用,你尝试过什么,你想要提供minimum, complete, verifiable example。我怀疑在制作这样的东西时你可能自己解决了这个问题。