Dijkstra 算法 Java-- 距离不对
Dijkstra's Algorithm Java-- Distance not right
我正在尝试编写 dijkstra 算法的代码,从我需要显示距离并打印节点路径的任何顶点开始。它适用于顶点 2,4 和 5,但对于 1 和 3 它会变得混乱。可能是小得有点傻,但我看不到。
public static void main(String[] args)
{
int INF = Integer.MAX_VALUE;
int verticies = 5;
int W[][] = {{INF,7,4,6,1},
{0,INF,0,0,0},
{0,2,INF,4,0},
{0,0,0,INF,0},
{0,0,0,1,INF}};
int startNode = 1;
dijkstra(W,verticies,startNode-1);
}
public static void dijkstra(int G[][],int n,int startnode)
{
int INF = Integer.MAX_VALUE, nINF = Integer.MIN_VALUE;
//int cost[MAX][MAX],distance[MAX],pred[MAX];
//int visited[MAX],count,mindistance,nextnode,i,j;
int cost[][] = new int[n][n];
int distance[] = new int[n];
int pred[] = new int[n];
boolean visited[] = new boolean[n];
int count=0, mindistance=0, nextnode=0,i,j;
//pred[] stores the predecessor of each node
//count gives the number of nodes seen so far
//create the cost matrix
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(G[i][j]==0)
cost[i][j]=INF;
else
cost[i][j]=G[i][j];
//initialize pred[],distance[] and visited[]
for(i=0;i<n;i++)
{
distance[i]=cost[startnode][i];
pred[i]=startnode;
visited[i]=false;
}
distance[startnode]=0;
visited[startnode]=true;
count=1;
while(count<n-1)
{
mindistance=INF;
//nextnode gives the node at minimum distance
for(i=0;i<n;i++)
if(distance[i]<mindistance&&!visited[i])
{
mindistance=distance[i];
nextnode=i;
}
//check if a better path exists through nextnode
visited[nextnode]=true;
for(i=0;i<n;i++)
if(!visited[i])
if(mindistance+cost[nextnode][i]<distance[i])
{
distance[i]=mindistance+cost[nextnode][i];
pred[i]=nextnode;
}
count++;
}
//print the path and distance of each node
for(i=0;i<n;i++)
if(i!=startnode)
{
if(distance[i] == INF || distance[i] < 0){
System.out.print("\nNo edge exists between node "+(startnode+1)+" and node "+(i+1));
} else {
System.out.format("\nDistance of node %d = %d", (i + 1), distance[i]);
System.out.format("\nPath = %d", (i + 1));
j = i;
do {
j = pred[j];
System.out.format("<-%d", (j + 1));
} while (j != startnode);
}
}
}
我不知道具体是怎么做到的,但你正在以某种方式让 INF
进入你的计算。我怀疑行 distance[i]=mindistance+cost[nextnode][i];
,但它可能不是唯一的罪魁祸首,我没有检查过。当 mindistance
为 1(或更大)且成本为 Integer.MAX_VALUE
时,您会得到算术溢出并且结果为负数。进一步的行为,我没有预料到,但并不像预期的那样。
当您在两个地方定义 INF
时,我将值更改为 1,000,000,我从您的程序中得到以下输出:
Distance of node 2 = 6
Path = 2<-3<-1
Distance of node 3 = 4
Path = 3<-1
Distance of node 4 = 2
Path = 4<-5<-1
Distance of node 5 = 1
Path = 5<-1
我相信这是正确的。
我是怎么发现的?我将这条语句插入了你的外部 while 循环的中间:
System.out.println("count " + count + " nextnode " + nextnode + " mindistance " + mindistance);
当它打印出一个很大的负数时,我开始怀疑算术溢出。在您学会使用调试器之前,System.out.println()
是您调试的好朋友。
我正在尝试编写 dijkstra 算法的代码,从我需要显示距离并打印节点路径的任何顶点开始。它适用于顶点 2,4 和 5,但对于 1 和 3 它会变得混乱。可能是小得有点傻,但我看不到。
public static void main(String[] args)
{
int INF = Integer.MAX_VALUE;
int verticies = 5;
int W[][] = {{INF,7,4,6,1},
{0,INF,0,0,0},
{0,2,INF,4,0},
{0,0,0,INF,0},
{0,0,0,1,INF}};
int startNode = 1;
dijkstra(W,verticies,startNode-1);
}
public static void dijkstra(int G[][],int n,int startnode)
{
int INF = Integer.MAX_VALUE, nINF = Integer.MIN_VALUE;
//int cost[MAX][MAX],distance[MAX],pred[MAX];
//int visited[MAX],count,mindistance,nextnode,i,j;
int cost[][] = new int[n][n];
int distance[] = new int[n];
int pred[] = new int[n];
boolean visited[] = new boolean[n];
int count=0, mindistance=0, nextnode=0,i,j;
//pred[] stores the predecessor of each node
//count gives the number of nodes seen so far
//create the cost matrix
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(G[i][j]==0)
cost[i][j]=INF;
else
cost[i][j]=G[i][j];
//initialize pred[],distance[] and visited[]
for(i=0;i<n;i++)
{
distance[i]=cost[startnode][i];
pred[i]=startnode;
visited[i]=false;
}
distance[startnode]=0;
visited[startnode]=true;
count=1;
while(count<n-1)
{
mindistance=INF;
//nextnode gives the node at minimum distance
for(i=0;i<n;i++)
if(distance[i]<mindistance&&!visited[i])
{
mindistance=distance[i];
nextnode=i;
}
//check if a better path exists through nextnode
visited[nextnode]=true;
for(i=0;i<n;i++)
if(!visited[i])
if(mindistance+cost[nextnode][i]<distance[i])
{
distance[i]=mindistance+cost[nextnode][i];
pred[i]=nextnode;
}
count++;
}
//print the path and distance of each node
for(i=0;i<n;i++)
if(i!=startnode)
{
if(distance[i] == INF || distance[i] < 0){
System.out.print("\nNo edge exists between node "+(startnode+1)+" and node "+(i+1));
} else {
System.out.format("\nDistance of node %d = %d", (i + 1), distance[i]);
System.out.format("\nPath = %d", (i + 1));
j = i;
do {
j = pred[j];
System.out.format("<-%d", (j + 1));
} while (j != startnode);
}
}
}
我不知道具体是怎么做到的,但你正在以某种方式让 INF
进入你的计算。我怀疑行 distance[i]=mindistance+cost[nextnode][i];
,但它可能不是唯一的罪魁祸首,我没有检查过。当 mindistance
为 1(或更大)且成本为 Integer.MAX_VALUE
时,您会得到算术溢出并且结果为负数。进一步的行为,我没有预料到,但并不像预期的那样。
当您在两个地方定义 INF
时,我将值更改为 1,000,000,我从您的程序中得到以下输出:
Distance of node 2 = 6
Path = 2<-3<-1
Distance of node 3 = 4
Path = 3<-1
Distance of node 4 = 2
Path = 4<-5<-1
Distance of node 5 = 1
Path = 5<-1
我相信这是正确的。
我是怎么发现的?我将这条语句插入了你的外部 while 循环的中间:
System.out.println("count " + count + " nextnode " + nextnode + " mindistance " + mindistance);
当它打印出一个很大的负数时,我开始怀疑算术溢出。在您学会使用调试器之前,System.out.println()
是您调试的好朋友。