我正在尝试编写一个程序,该程序在图形中的两个顶点之间找到最小长度路径,从这些路径中选择一个遍历最少边缘的路径。我使用Dijkstra的算法进行了一些修改(下面)。
输出应该是:0->3->4
,而是我的程序打印0->4
。
为什么输出错误?
#include<stdio.h>
#include<string.h>
#define INFINITY 9999
#define n 5
#define s 0
#define d 4
void Dijkstra(int Graph[n][n], int _n,int _s, int _d);
int main()
{
int Graph[n][n] = {
{0, 6, 5, 1, INFINITY},
{6, 0, 3, INFINITY, INFINITY},
{5, 3, 0, 2, 5},
{1, INFINITY, 2, 0, 6},
{INFINITY, INFINITY, 5, 6, 0}
};
Dijkstra(Graph,n,s,d);
getchar();
return 0;
}
void Dijkstra(int Graph[n][n], int _n,int _s, int _d)
{
int distance[n], parent[n], visited[n], edge[n]={0}, mindistance,
nextnode= _s, i, j,temp[n][n], res[n];
//parent[] stores the predecessor of each node
//edge[] stores the number of edged of every vertex's shortest path
for (i = 0; i < n; i++) //create the temp matrix
for (j = 0; j < n; j++)
if (Graph[i][j] == INFINITY)
temp[i][j] = INFINITY;
else
temp[i][j] = Graph[i][j];
for(i=0;i<n;i++)
{
distance[i] = INFINITY; //initialize distance
parent[i] = _s; //initialize parent
visited[i] = 0;
if (distance[i] > 0 && distance[i] < INFINITY)
edge[i]++;
}
distance[_s] = 0;
visited[_s] = 1;
while (visited[_d] == 0)
{
//nextnode gives the node at minimum distance
for (i = 0; i < n; i++)
{
mindistance = temp[_s][i] + distance[i];
if (distance[i] < mindistance && !visited[i])
{
mindistance = distance[i];
nextnode = i;
}
}
//check if a better path exists through nextnode
visited[nextnode] = 1;
if (nextnode != _d)
for (i = 0; i < n; i++)
if (!visited[i])
{
if (mindistance + Graph[nextnode][i] < distance[i])
{
distance[i] = mindistance + Graph[nextnode][i];
parent[i] = nextnode;
edge[i] = edge[nextnode] + 1;
}
if (mindistance + Graph[nextnode][i] == distance[i])
{
if (edge[i] >= edge[nextnode] + 1)
{
parent[i] = nextnode;
edge[i] = edge[nextnode] + 1;
}
}
}
}
//print the path
for (i = 0; i < n; i++)
res[i] = 0;
i = nextnode;
while (i != _s)
{
res[i] = parent[i];
i = parent[i];
}
printf("%d", _s);
printf("->");
for (i = 0; i < n; i++)
{
if (res[i] != 0)
{
printf("%d", res[i]);
printf("->");
}
}
printf("%d", _d);
}
答案 0 :(得分:0)
在循环中有两个问题,您选择下一个要遍历的节点。设置
显然是不正确的 mindistance = Graph[_s][i] + distance[i];
每次迭代,因为您需要mindistance
来跟踪迭代中的最小观察距离。相反,在循环之前你应该设置
mindistance = INFINITY;
在我们查看此循环时,请注意在选择要遍历的下一个节点时忽略边缘计数标准。您也需要在此处使用该标准,以确保找到符合条件的路径。
通过这些更正,您的程序会为我生成预期的输出。
顺便说一句,请注意,这仍然是非常直接的Dijkstra。诀窍是要认识到你正在实施双组分距离测量。最重要的组件是路径长度(边缘权重之和),但边缘计数是断开连接的次要组件。因此,实现看起来有点不同,但是如果你将距离比较和设置分解为单独的函数,那么你将无法将剩余部分与标准Dijkstra(简单变体)分开。
答案 1 :(得分:0)
我已经编辑了我的代码,但我仍然得到了相同的错误输出:
#include<stdio.h> #include<conio.h> #define INFINITY 9999 #define n 5 #define s 0 #define d 4 void Dijkstra(int Graph[n][n], int _n,int _s, int _d); int main() { int Graph[n][n]={{0,6,5,1,INFINITY},{6,0,3,INFINITY,INFINITY},{5,3,0,2,5},{1,INFINITY,2,0,6},{INFINITY,INFINITY,5,6,0}}; Dijkstra(Graph,n,s,d); getchar(); return 0; } void Dijkstra(int Graph[n][n],int _n,int _s,int _d) { int temp[n][n],distance[n],parent[n],visited[n],mindistance,nextnode,j,i; //parent[] stores the predecessor of each node //edge[] stores the number of edges in the shortest path from the source //create the cost matrix for(i=0;i<_n;i++) for(j=0;j<_n;j++) temp[i][j]=Graph[i][j]; //initialize for(i=0;i<_n;i++) { distance[i]=INFINITY; parent[i]=_s; visited[i]=0; } distance[_s]=0; visited[_s]=1; nextnode=_s; while(visited[_d]==0) { mindistance=INFINITY; //nextnode gives the node at minimum distance for(i=0;i<_n;i++) { distance[i]=temp[nextnode][i]; if(distance[i]<mindistance && !visited[i]) { mindistance=distance[i]; nextnode=i; } } //check if a better path exists through nextnode visited[nextnode]=1; for(i=0;i<_n;i++) if(!visited[i]) if(mindistance+temp[nextnode][i]<distance[i]) { temp[nextnode][i]=mindistance+distance[i]; parent[i]=nextnode; } } //print the path and distance of each node i=_d; printf("%d",i); do { i=parent[i]; printf("<-%d",i); }while(i!=_s); }
只需要进行一些小改动就可以得到假定的输出;我评论了下面的代码:
…
distance[_s]=0;
// visited[_s]=1; do not mark the initial node as visited - will select below
// nextnode=_s; no need here - will select as the node at minimum distance
while (!visited[_d])
{
mindistance=INFINITY;
//nextnode gives the node at minimum distance
for (i=0; i<_n; i++)
{
// distance[i]=temp[nextnode][i]; don't change tentative distance here
if (distance[i]<mindistance && !visited[i])
{
mindistance=distance[i];
nextnode=i;
}
}
//check if a better path exists through nextnode
visited[nextnode]=1;
for (i=0; i<_n; i++)
if (!visited[i])
if (mindistance+temp[nextnode][i]<distance[i])
{
// temp[nextnode][i]=mindistance+distance[i]; other way round
distance[i]=mindistance+temp[nextnode][i]; // smaller
parent[i]=nextnode;
}
}
…