Djikstra的最短路径算法

时间:2016-09-30 09:31:55

标签: java algorithm graph-algorithm shortest-path

我正在学习Djikstra,我根据与Djikstra略有不同的想法准备了以下代码。 现在,在许多网站中,我已经看到使用Extract min和boolean数组的访问边缘。 我没有使用过,我的回答也是正确的。是否存在我的算法无法工作的测试用例或场景。

import java.util.*;
class ShortestPath2
{
static int Ar[][];
static int dist[];

static int nodes;
public static void djikstra(int source)
{
LinkedList<Integer> list=new LinkedList<Integer>();
dist[source]=0;

list.add(source);
while(!list.isEmpty())
{
source=list.removeFirst();

for(int i=0;i<nodes;i++)
{
if(Ar[source][i]!=0)
{

if(dist[i]>dist[source]+Ar[source][i])
{
dist[i]=Math.min(dist[i],dist[source]+Ar[source][i]);
list.add(i);
}


}

}



}

System.out.println(Arrays.toString(dist));
}

public static void main(String[] args)
{

 nodes=9;

Ar=new int[nodes][nodes];
dist=new int[nodes];

Arrays.fill(dist,Integer.MAX_VALUE);



Ar=new int[][]{{0, 4, 0, 0, 0, 0, 0, 8, 0},
                                  {4, 0, 8, 0, 0, 0, 0, 11, 0},
                                  {0, 8, 0, 7, 0, 4, 0, 0, 2},
                                  {0, 0, 7, 0, 9, 14, 0, 0, 0},
                                  {0, 0, 0, 9, 0, 10, 0, 0, 0},
                                  {0, 0, 4, 14, 10, 0, 2, 0, 0},
                                  {0, 0, 0, 0, 0, 2, 0, 1, 6},
                                  {8, 11, 0, 0, 0, 0, 1, 0, 7},
                                  {0, 0, 2, 0, 0, 0, 6, 7, 0}
                                 };

djikstra(0);




}
}

2 个答案:

答案 0 :(得分:1)

Dijkstra算法背后的整个想法是使用优先级队列。您无法从Dijkstra中删除优先级队列,仍称其为Dijkstra算法。你写的是没有检查被访问的BFS。如果图形具有负循环,则代码不会终止。您的代码将在图表a上找到没有负循环的最短路径,但复杂性可能变为指数级。因为有可能一遍又一遍地重新访问节点(因为删除了访问列表)。如果将访问列表添加到代码中,则代码将不会始终找到最短路径,因为您没有使用优先级队列。因此,您需要优先级队列和访问列表,以便在线性时间内找到最短路径。

A --100---B --100-- I---100---O  // A-B, B-I, I-O weight : 100
|        / \       / \        |  // A-C, C-D, ... weight : 1
C-D-E-F-G   H-J-K-L   M-N-P-Q-R

例如,您可以使用上图来查看代码重新访问 O 的次数。

答案 1 :(得分:1)

Dijkstra的原始实现并没有解决负边缘(但可以检测到它)和负循环问题。

要解决此问题,我们可以使用Bellman Ford算法。

  1. 即使存在负边缘(但没有负循环),它也会给出正确的最短路径

  2. 它可以检测是否存在负循环(但如果存在负循环,则不能给出正确的解决方案,所以我们最好终止代码)