1.Dijkstra算法:
1.这是一个图:
2.这是与这个图有关的表:
Dijkstra算法解决的问题一个顶点到其余各顶点的最短路径
主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
那么它是如何解决的呢?
见图:很明显,该顶点是V0,求的是V0到V1,V2,V3,V4的最短距离。
那么是如何做到的呢?
大致上是以起点向外扩展,当整个图都扩展出来时即得到了整个图的所有点到起点的最短路径。
详细解释见表:
在表中每个顶点下面都有三个参数,下面来详细解释一下这三个参数的意思:
S:标记点,有两种状态。0,1 。0,代表该点还未加入这个图里去。1,代表这个点已经加入图。
d:表示在以知的图里,各个点到起点的最短路径。注意在这里再详细解释一下。比如说,当这个图里只有0时,各个点到起点的最短路径就是各个点到起点的直接相连的边。如果该边不能到达则设置为无穷大。加入了新的点后,可以从起点,经过新的点间接的到达目标点。
p:路径,记录的是从哪个点到达目标点的。
原理解释:
创建两个表,OPEN, CLOSE。
OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
1. 访问路网中距离起始点最近且没有被检查过的点,把这个点放入OPEN组中等待检查。
2. 从OPEN表中找出距起始点最近的点,找出这个点的所有子节点,把这个点放到CLOSE表中。
3. 遍历考察这个点的子节点。求出这些子节点距起始点的距离值,放子节点到OPEN表中。
4. 重复第2和第3步,直到OPEN表为空,或找到目标点。
//注这里的open close对应S的零和一的状态。
const int MAXINT = 32767;
const int MAXNUM = 10;
int dist[MAXNUM];
int prev[MAXNUM];
int A[MAXUNM][MAXNUM];
void Dijkstra(int v0)
{
bool S[MAXNUM]; // 判断是否已存入该点到S集合中
int n=MAXNUM;
for(int i=1; i<=n; ++i)
{
dist[i] = A[v0][i];
S[i] = false; // 初始都未用过该点
if(dist[i] == MAXINT)
prev[i] = -1;
else
prev[i] = v0;
}
dist[v0] = 0;
S[v0] = true;
for(int i=2; i<=n; i++)
{
int mindist = MAXINT;
int u = v0; // 找出当前未使用的点j的dist[j]最小值
for(int j=1; j<=n; ++j)
if((!S[j]) && dist[j]<mindist)
{
u = j; // u保存当前邻接点中距离最小的点的号码
mindist = dist[j];
}
S[u] = true;
for(int j=1; j<=n; j++)
if((!S[j]) && A[u][j]<MAXINT)
{
if(dist[u] + A[u][j] < dist[j]) //在通过新加入的u点路径找到离v0点更短的路径
{
dist[j] = dist[u] + A[u][j]; //更新dist
prev[j] = u; //记录前驱顶点
}
}
}
}