解决单源最短路径的一个常用算法叫做:Dijkstra算法,这是一个非常经典的贪心算法例子。
注意:这个算法只对权值非负情况有效。
在每个阶段,Dijkstra算法选择一个顶点v,它在所有unknown顶点中具有最小的distance,同时算法将起点s到v的最短路径声明为known。
这个算法的本质就是 给定起点,然后假设你有一个点集(known点集),对这个点集中的点,我们已经求出起点到其的最短距离。然后慢慢扩张这个集合。直到某一时刻它包括目标点。
具体概念详细介绍见书吧,下面结合一个例子,阐述一下该算法遍历顶点的过程。
假设开始顶点s为v1。
则,第一个选择的顶点是v1,路径长是0,该顶点标记为known,
1: known(v1) unknown(v2,v3,v4,v5,v6,v7); 这时由known点集扩充,v4 为下一个最短路径顶点,路径长为1,标记v4为known
2: known(v1,v4) unknown(v2,v3,v5,v6,v7); 这时由known点集扩充,v2 为下一个最短路径顶点,路径长为2,标记v2为known
3: known(v1,v4,v2) unknown(v3,v5,v6,v7); 这时由known点集扩充,v3,v5 为下一个最短路径顶点,路径长为3, 标记v3,v5为known
4: known(v1,v4,v2,v3,v5) unknown(v6,v7); 这时由known点集扩充,v7 为下一个最短路径顶点,路径长为5, 标记v7为known
5: known(v1,v4,v2,v3,v5,v7) unknown(v6); 这时由known点集扩充,v6 为下一个最短路径顶点,路径长为6, 标记v6为known
伪代码:
struct VertexNode
{
char data[2];
int distance;
bool known;
VertexNode* path;
adjVertexNode* list;
};
void
Dijkstra(Graph& g, VertexNode& s)
{
for each vertex v in g
{
{
v.distance = INFINITY;
v.known = false;
v.path = NULL;
}
s.distance = 0;
for (int i=0; i<g.vertexnum; i++)
{
vertex v = smallest unknown distance vertex;
if (v==NULL)
break;
else
v.known = true;
for each w adjacent to v
{
if (!w.known)
{
if (v.distance + weight(v,w) < w.distance)
{
w.distance = v.distance + weight(v,w);
w.path = v;
}
}
}
}
}
void PrintPath(
Graph& g, VertexNode* target)
{// print the shortest path from s to target
if(target.path!=NULL)
{
PrintPath(g, target.path);
cout << " " ;
}
cout << target ;
}
代码实现:
#include <iostream>
using namespace std;
#define MAX_VERTEX_NUM 20
#define INFINITY 2147483647
struct adjVertexNode
{
int adjVertexPosition;
int weight;
adjVertexNode * next;
};
struct VertexNode
{
char data [ 2 ];
int distance;
bool known;
VertexNode * path;
adjVertexNode * list;
};
struct Graph
{
VertexNode VertexNode [ MAX_VERTEX_NUM ];
int vertexNum;
int edgeNum;
<
using namespace std;
#define MAX_VERTEX_NUM 20
#define INFINITY 2147483647
struct adjVertexNode
{
int adjVertexPosition;
int weight;
adjVertexNode * next;
};
struct VertexNode
{
char data [ 2 ];
int distance;
bool known;
VertexNode * path;
adjVertexNode * list;
};
struct Graph
{
VertexNode VertexNode [ MAX_VERTEX_NUM ];
int vertexNum;
int edgeNum;
<