使用序言的网格中最短路径

问题描述 投票:0回答:1

抱歉,第一个问,我是新手。我对代码进行了清理。问题是:我有一个带有路径和障碍物的正方形网格。我想找到从一点到另一点的最短路径。这是人工智能的一部分。当路径太大时,我无法在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).
prolog shortest-path dijkstra
1个回答
1
投票

首先是一些Prolog建议。

  1. member/2是内置的,您不必定义它。
  2. ISO取反是\+,而不是not/1
  3. 为了演奏,memberchk/2击败member/2
  4. 我在您的代码中看到很多foo(X,Y) :- X == Y, ...。如果您只说foo(X,X)并省去进行像这样的显式测试的麻烦,那就更好了,除非您要执行条件表达式以避免选择点之类的东西。
  5. 此代码中有很多削减。剪切和错误往往是很好的朋友,因为剪切可能会阻止执行,从而破坏外观合理的代码。

如果必须解决此问题,我希望将最短路径逻辑与网格遍历逻辑分开。您将永远无法调试它,即使这样做,您将拥有的是那些无法修改的不可读代码块之一。显然,您有大量的术语,因为您将遍历逻辑嵌入到路径查找逻辑中。将它们分成两个单独的步骤,您可能会发现可以做一些有意义的测试和调试的较小零件。不管使用哪种语言,这都是编程的一种好方法:如果需要更改网格结构或使寻路更加智能或复杂,该怎么办?保持粒度始终有助于管理变更。

关于S.O.礼节,这不是很好:您应该谈论什么无效以及您尝试过的事情,并且想要提供minimum, complete, verifiable example。我怀疑产生这样的事情您可能会自己解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.