迪杰斯特拉 Dijkstra 算法
1,迪杰斯特拉算法介绍
迪杰斯特拉算法(Dijkstra)
也叫狄克斯特拉算法,它使用类似广度优先搜索的方法,解决从一个顶点到其他所有顶点的最短路径问题,它解决的是加权图(不能有负权)的最短路径问题。
从起始点开始,采用贪心算法的策略,每次选择一个没被标记且距离起始点最近的顶点,把它标记下,然后更新和它邻接的顶点 ……,直到所有顶点都计算完为止。
如上图所示,假如计算从上海到其他所有城市的最短时间,上面的时间有可能是开车,有可能是高铁也可能是坐飞机,和真实距离不成正比。
我们从起始点开始,使用一个数组 dis
,数组中 dis[j]
的值表示从起始点到顶点 j
的时间,刚开始的时候,起始点到他自己为 0
,到其他顶点都为无穷大,如下图所示。
如果想要减少从起始点到 j
的时间,唯一的方式就是需要寻找一个中转站 k
。从起始点到 k
的时间为 dis[k]
,从 k
到 j
的时间为 g[k][j]
,然后判断中转的总时间 dis[k] + g[k][j]
是否小于 dis[j]
,如果中转时间小于 dis[j]
,就更新 dis[j]
。
比如最上面图中,从起始点到南京的时间是 3
小时,如果通过杭州中转,时间就会变成 2
小时。核心代码是下面这行。
dis[j] = min(dis[j], dis[k] + g[k][j]);
迪杰斯特拉算法的解题思路如下:
1,从起始点开始计算所有和它相连的点(也就是起始点指向的点),计算完之后把起始点标记下(表示已经计算过了)。
2,找出离起始点最近且没有被标记过的点 v
,计算所有和 v
相连且没有被标记过的点,计算完之后把 v
标记下。
3,重复上面的步骤 2
,直到所有顶点都标记完为止。
2,迪杰斯特拉算法的代码实现
迪杰斯特拉算法使用的是贪心的策略,每次都是从未标记的顶点中找到一个离起始点最近的点,用它来更新所有和它连接且未被标记过的点,代码比较简单,我们来看下。
Java 代码:
private void test() {
int[][] g = {
{
0, 1, 3, 0, 0, 0},// 图的邻接矩阵。
{
0, 0, 1, 4, 2, 0},
{
0, 0, 0, 5, 5, 0},
{
0, 0, 0, 0, 0, 3},
{
0, 0, 0, 1, 0, 6},
{
0, 0, 0, 0, 0, 0}};
dijkstra(g, 0);
}
/**
* @param g 图的邻接矩阵
* @param start 起始点
*/
public