Dijkstra
Dijkstra算法概念
笔者认为Dijkstra 其算法本质广度优先搜索(BFS)。其算法思想为设置两个集合S和T,集合S中存放已找到的最短路径的节点,集合T中存放尚未找到的最短路径的节点。初始状态下,S中只包含源点,然后从集合T中遍历找到源点路径长度(权值)最小的节点U加入到集合S中,T中去除该节点。集合S中每加入一个节点,集合T中各节点的新的最短路径为原来的路径长度与现在从源点经过当前节点到达T中各节点新的最短路径长度的较小值。此过程重复,直至T中所有节点到S中。
图中的权值不能为负数。
实现
图
由图生成的二维数组为
其中Max代表两点之间不能连通
0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
0 | 7 | Max | 2 | Max | 20 | Max |
7 | 0 | 3 | 4 | Max | Max | Max |
Max | 3 | 0 | 2 | 3 | Max | Max |
2 | 4 | 2 | 0 | 7 | 6 | Max |
Max | Max | 3 | 7 | 0 | 4 | 3 |
20 | Max | Max | 6 | 4 | 0 | 1 |
Max | Max | Max | Max | 3 | 1 | 0 |
算法步骤
1、源点为0,S中含有节点0,T中含有剩余节点。源点到其他节点的路径为:
0(已用) | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
0 | 7 | Max | 2 | Max | 20 | Max |
2、源点到节点3的路径最短,故S中放入节点3,节点3标志为已用,此时源点经过节点3到其他节点的最短路径为:
0(已用) | 1 | 2 | 3(已用) | 4 | 5 | 6 |
---|---|---|---|---|---|---|
0 | 6 | 4 | 2 | 9 | 8 | Max |
3、T中最短路径节点为2,将节点2放入S中,此时源点经过节点2到其他节点的最短路径为:
0(已用) | 1 | 2(已用) | 3(已用) | 4 | 5 | 6 |
---|---|---|---|---|---|---|
0 | 6 | 4 | 2 | 7 | 8 | Max |
4、T中最短路径节点为1,将节点1放入S中,此时源点经过节点1到其他节点的最短路径为:
0(已用) | 1(已用) | 2(已用) | 3(已用) | 4 | 5 | 6 |
---|---|---|---|---|---|---|
0 | 6 | 4 | 2 | 7 | 8 | Max |
5、T中最短路径节点为4,将节点4放入S中,此时源点经过节点4到其他节点的最短路径为:
0(已用) | 1(已用) | 2(已用) | 3(已用) | 4(已用) | 5 | 6 |
---|---|---|---|---|---|---|
0 | 6 | 4 | 2 | 7 | 8 | 10 |
6、T中最短路径节点为5,将节点5放入S中,此时源点经过节点5到其他节点的最短路为:
0(已用) | 1(已用) | 2(已用) | 3(已用) | 4(已用) | 5(已用) | 6 |
---|---|---|---|---|---|---|
0 | 6 | 4 | 2 | 7 | 8 | 9 |
7、T中最短路径节点为6,将节点6放入S中,此时源点经过节点6到其他节点的最短路为:
0(已用) | 1(已用) | 2(已用) | 3(已用) | 4(已用) | 5(已用) | 6(已用) |
---|---|---|---|---|---|---|
0 | 6 | 4 | 2 | 7 | 8 | 9 |
最后由节点0到节点6的最短路径长度为9,路径为0-3-5-6.
代码实现
static void Dijkstra(int[,] mgrap, int v)
{
int len = mgrap.GetLength(0);//节点个数
int[] dist = new int[len];//从原点v到其他的各定点当前的最短路径长度
int[] path = new int[len];//path[i]表示从原点到定点i之间最短路径的前驱节点
int[] s = new int[len]; //选定的顶点的集合
int mindis, i, j, u;
u = 0;
for (i = 0; i < len; i++)
{
dist[i] = mgrap[v, i]; //距离初始化
s[i] = 0; //s[]置空 0表示i不在s集合中
if (mgrap[v, i] < int.MaxValue) //路径初始化
path[i] = v;
else
path[i] = -1;
}
s[v] = 1; //源点编号v放入s中
path[v] = 0;
for (i = 0; i < len; i++) //循环直到所有顶点的最短路径都求出
{
mindis = int.MaxValue; //mindis置最小长度初值
for (j = 0; j < len; j++) //选取不在s中且具有最小距离的顶点u
if (s[j] == 0 && dist[j] < mindis)
{
u = j;
mindis = dist[j];
}
s[u] = 1; //顶点u加入s中
for (j = 0; j < len; j++) //修改不在s中的顶点的距离
if (s[j] == 0)
if (mgrap[u, j] < int.MaxValue && dist[u] + mgrap[u, j] < dist[j])
{
dist[j] = dist[u] + mgrap[u, j];
path[j] = u;
}
}
}