Java最短路径

时间:2012-02-23 19:30:14

标签: java algorithm shortest-path

我正在尝试用Java制作小型塔防守游戏。我有一个由Point2D.Double数组组成的网格,名为:

FieldArr并[h] [V]

h表示水平字段,v表示垂直垂直字段

这就像这样的网格

+ + + + + + +
S + X + + + +
+ + + X + + +
+ X + + + + F
+ + X + + + +

S表示开始,F表示完成,X表示塔

现在我想计算最短的路线,但我没有任何线索如何开始这个

塔楼有以下vars用于定位: Horizo​​ntalNr和VerticalNr。

对于我做的油漆:

public void paint(Graphics2D g2) {
    int Xpos = HorizontalNr * playfield.getSquarewidth() + playfield.GetinitialXPos();
    int Ypos = VerticalNr * playfield.getSquarewidth() + playfield.GetinitialYPos();
    g2.fillRect(Xpos, Ypos, 50, 50);
}

任何人都有任何提示,关于如何制作我的敌人类,所以我不会遇到算法的任何问题? 和/或有关于如何计算最短路径的提示?

已经谢谢了 grt kiwi

3 个答案:

答案 0 :(得分:4)

shortest path problem已经进行了很多研究,很多文献都存在这个问题。最好只使用现有算法,而不是自己发明算法。

例如,一个简单而有效的算法是Dijkstra's algorithm。来自维基百科:

  
      
  1. 让我们开始的节点称为初始节点。设节点Y的距离是从初始节点到Y的距离.Dijkstra算法将分配一些初始距离值,并尝试逐步改进它们。   为每个节点分配一个暂定距离值:为我们的初始节点设置为零,为所有其他节点设置为无穷大。
  2.   
  3. 标记未访问的所有节点。将初始节点设置为当前节点。创建一组称为未访问集的未访问节点,其中包含除初始节点之外的所有节点。
  4.   
  5. 对于当前节点,考虑所有未访问的邻居并计算其暂定距离。例如,如果当前节点A标记为临时距离6,并且将其与邻居B连接的边缘具有长度2,则到B(通过A)的距离将是6 + 2 = 8。如果该距离小于先前记录的B的临时距离,则覆盖该距离。即使邻居已被检查过,但此时并未将其标记为已访问,并且它仍保留在未访问的集合中。
  6.   
  7. 当我们考虑当前节点的所有邻居时,将当前节点标记为已访问并将其从未访问的集合中删除。永远不会再次检查受访节点;现在记录的距离是最终的,最小的。
  8.   
  9. 如果目标节点已被标记为已访问(在规划两个特定节点之间的路由时)或未访问集合中节点之间的最小暂定距离是无穷大(计划完整遍历时),则停止。算法已经完成。
  10.   
  11. 将标记有最小暂定距离的未访问节点设置为下一个“当前节点”,然后返回步骤3.
  12.   

答案 1 :(得分:2)

如果你想要避开塔楼,那么你要从头到尾寻找欧几里德路径,这可以用最短的路径来解决ala djkstra。

答案 2 :(得分:1)

正如马克所说,这是最短路径问题,可以轻松有效地解决。

请注意,由于您的问题未加权,因此您可以在此处使用BFS,这非常容易实现,并且还可以保证找到未加权图的排序路径。

BFS的伪代码:

findShortestPath(source,target):
  queue<- new queue
  visited <- {}
  Map<point,point> parents <- empty map
  queue.push(source)
  while (queue.empty() == false): 
     current <- queue.takeFirst()
     if (current.equals(target)):
         extract the path from source to destination using the map parents(*)
         return
     visited.add(current)
     for each p such that p and current are neighbors: //insert neighbors to queue
          if p is not in visited: 
                if (p is not an obstacle):
                   queue.push(p)
                   parents.put(p,current) //current is the parent of p

(*)从地图中提取路径很简单:只需按照current <- parent.get(current)进行操作,直到获得null,这样就可以提取您将使用的确切路径。

请注意,更快的解决方案[在大多数情况下]将A* manhattan distance heuristic,但实施起来要复杂得多。