最近由于工作需要,需要研究最佳路径选择问题.估重新复习了遍dijkstra算法,以下做个记录
代码
#include "stdio.h"
#include <iostream.h>
using namespace std;
#define BIG 65535 //无穷大
//Dijkstra算法函数,求给定顶 点到其余各点的最短路径
//参数:邻接矩阵、顶点数、出发点的下标、结果数组、路径前一点记录
void Dijkstra(int Cost[][5],int n,int v0,int Distance[],int prev[])
{
int s[5];
int mindis,dis;
int i,j,u;
//初始化
for(i=0;i<n;i++)
{
Distance[i]=Cost[v0][i];
s[i]=0;
if(Distance[i]==BIG)
prev[i] = -1;
else
prev[i] = v0;
}
Distance[v0] = 0;
s[v0] =1; //标记v0
//在当前还未找到最短路径的顶点中,
//寻找具有最短距离的顶点
for(i=1;i<n;i++)
{//每循环一次,求得一个最短路径
mindis=BIG;
u = v0;
for (j=0;j<n;j++) //求离出发点最近的顶点
if(s[j]==0&&Distance[j]<mindis)
{
mindis=Distance [j];
u=j;
} // if语句体结束,j循环结束
s[u] = 1;
for(j=0;j<n;j++) //修改递增路径序列(集合)
if(s[j]==0&&Cost[u][j]<BIG)
{ //对还未求得最短路径的顶点
//求出由最近的顶点 直达各顶点的距离
dis=Distance[u] +Cost[u][j];
// 如果新的路径更短,就替换掉原路径
if(Distance[j]>dis)
{
Distance[j] = dis;
prev[j] = u;
}
} // if 语句体结束,j循环结束
} // i循环结束
}
// 输出最短路径
// 参数:路径前一点记录、出发点的下标、到达点下标、顶点数
void PrintPrev(int prev[],int v0,int vn,int n)
{
int tmp = vn;
int i = 1;
//临时存路径
int *tmpprv = new int[n];
//初始化数组
for(int ii=0;ii<n;ii++)
tmpprv[ii] = 0;
//记录到达点下标
tmpprv[0] = vn+1;
//中间点用循环记录
for(int j=1;j<n;j++)
{
if(prev[tmp] != -1&&tmp != 0)
{
tmpprv[i] = prev[tmp]+1;
tmp = prev[tmp];
i++;
}
else break;
}
//输出路径,数组逆向输出
for(int i=n-1;i>=0;i--)
{
if(tmpprv[i] !=0)
{ //排除0元素
cout<<"\tV"<<tmpprv[i];
if(i) //不是最后一个输出符号
cout << " --> ";
}
}
}
//主函数
int main()
{
//给出有向网的顶点数组
char *Vertex[5]={"V1","V2","V3","V4","V5"};
//给出有向网的邻接矩阵
int Cost[5][5]={{0,10,BIG,30,100},
{BIG,0,50,BIG,BIG},
{BIG,BIG,0,BIG,10},
{BIG,BIG,20,0,60},
{BIG,BIG,BIG,BIG,0},
};
int Distance[5]; //存放求得的最短路径长度
int prev[5]; //存放求得的最短路径
//调用Dijkstra算法函数,求顶点V1到其余各点的最短路径
//参数:邻接矩阵、顶点数、出发点的下标、 结果数组
Dijkstra(Cost,5,0,Distance,prev);
for(int i=0;i<5;i++)
{
//输出最短路径长度
cout << Vertex[0] << "-->" << Vertex[i] << "\t" <<Distance[i];
//输出最短路径
PrintPrev(prev,0,i,5);
cout <<endl;
}
system("pause");
return 0;
}
#include <iostream.h>
using namespace std;
#define BIG 65535 //无穷大
//Dijkstra算法函数,求给定顶 点到其余各点的最短路径
//参数:邻接矩阵、顶点数、出发点的下标、结果数组、路径前一点记录
void Dijkstra(int Cost[][5],int n,int v0,int Distance[],int prev[])
{
int s[5];
int mindis,dis;
int i,j,u;
//初始化
for(i=0;i<n;i++)
{
Distance[i]=Cost[v0][i];
s[i]=0;
if(Distance[i]==BIG)
prev[i] = -1;
else
prev[i] = v0;
}
Distance[v0] = 0;
s[v0] =1; //标记v0
//在当前还未找到最短路径的顶点中,
//寻找具有最短距离的顶点
for(i=1;i<n;i++)
{//每循环一次,求得一个最短路径
mindis=BIG;
u = v0;
for (j=0;j<n;j++) //求离出发点最近的顶点
if(s[j]==0&&Distance[j]<mindis)
{
mindis=Distance [j];
u=j;
} // if语句体结束,j循环结束
s[u] = 1;
for(j=0;j<n;j++) //修改递增路径序列(集合)
if(s[j]==0&&Cost[u][j]<BIG)
{ //对还未求得最短路径的顶点
//求出由最近的顶点 直达各顶点的距离
dis=Distance[u] +Cost[u][j];
// 如果新的路径更短,就替换掉原路径
if(Distance[j]>dis)
{
Distance[j] = dis;
prev[j] = u;
}
} // if 语句体结束,j循环结束
} // i循环结束
}
// 输出最短路径
// 参数:路径前一点记录、出发点的下标、到达点下标、顶点数
void PrintPrev(int prev[],int v0,int vn,int n)
{
int tmp = vn;
int i = 1;
//临时存路径
int *tmpprv = new int[n];
//初始化数组
for(int ii=0;ii<n;ii++)
tmpprv[ii] = 0;
//记录到达点下标
tmpprv[0] = vn+1;
//中间点用循环记录
for(int j=1;j<n;j++)
{
if(prev[tmp] != -1&&tmp != 0)
{
tmpprv[i] = prev[tmp]+1;
tmp = prev[tmp];
i++;
}
else break;
}
//输出路径,数组逆向输出
for(int i=n-1;i>=0;i--)
{
if(tmpprv[i] !=0)
{ //排除0元素
cout<<"\tV"<<tmpprv[i];
if(i) //不是最后一个输出符号
cout << " --> ";
}
}
}
//主函数
int main()
{
//给出有向网的顶点数组
char *Vertex[5]={"V1","V2","V3","V4","V5"};
//给出有向网的邻接矩阵
int Cost[5][5]={{0,10,BIG,30,100},
{BIG,0,50,BIG,BIG},
{BIG,BIG,0,BIG,10},
{BIG,BIG,20,0,60},
{BIG,BIG,BIG,BIG,0},
};
int Distance[5]; //存放求得的最短路径长度
int prev[5]; //存放求得的最短路径
//调用Dijkstra算法函数,求顶点V1到其余各点的最短路径
//参数:邻接矩阵、顶点数、出发点的下标、 结果数组
Dijkstra(Cost,5,0,Distance,prev);
for(int i=0;i<5;i++)
{
//输出最短路径长度
cout << Vertex[0] << "-->" << Vertex[i] << "\t" <<Distance[i];
//输出最短路径
PrintPrev(prev,0,i,5);
cout <<endl;
}
system("pause");
return 0;
}