Swift最短路径之Dijkstra(单源最短路)算法

Dijkstra“单源最短路”,是指指定一个点(源点)到其余各个顶点的最短路径。例如:求下图中的1号顶点到其他顶点的最短路径。


Swift最短路径之Dijkstra(单源最短路)算法_第1张图片
dijkstra.png
  • 与上文中的Floyd-Warshall算法一样。用一个二维数组来存储该图。


    let max:Int = 10000
    var map = [[0, 1, 12, max, max, max],
    [max, 0, 9, 3, max, max],
    [max, max, 0, max, 5, max],
    [max, max, 4, 0, 13, 15],
    [max, max, max, max, 0, 4],
    [max, max, max, max, max, 0]]

  • 用一个一维数组dist来存储1号顶点到其余各个顶点的初始路程。
    1 2 3 4 5 6
    var dist = [0, 1, 12, max, max, max]
    我们将此时dist数组中的值称为最短路程的“估计值”。

  • 先找一个离1号顶点最近的顶点,通过dist可知,2号顶点是当前离1号顶点最近的顶点,选择了2号顶点之后,dist[2]就已经从“估计值”变成“确定值”,即1号顶点到2号顶点的最短路程就是当前的distp[2]值。再来看2->3 和 2->4 这两条边。先计算通过2->3这条边能否让1号顶点到3号顶点的路程变短:比较dis[2] + map[2][3] 和dist[3]的值,dist[3] = 12,dis[2] + map[2][3] = 1 + 9 = 10,即dist[3] > dis[2] + map[2][3],dist[3] 更新为10,这个过程叫“松弛”。这便是Dijkstra算法的主要思想:通过“边”来松弛1号顶点到其余各个顶点的路程。同理,松弛2->4 这条边。dist[4]更新为4.对2号顶点所有的出边进行了松弛后,dist更新为:
    var dist = [0, 1, 10, 4, max, max]

  • 接下来,继续在剩下的3,4,5和6号顶点中,选出离1号顶点最近的顶点4号顶点,对4号顶点用刚才的方法进行松弛。然后在剩下的顶点中,继续选出离1号顶点最近的顶点,对所有的的边进行松弛。直到所有的顶点的边都松弛完毕。
    ok,以上就是Dijkstra算法的基本步骤,总结一下:每次找到离源点最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的路径。完整代码如下:


let max:Int = 10000
var map = [[0, 1, 12, max, max, max],
[max, 0, 9, 3, max, max],
[max, max, 0, max, 5, max],
[max, max, 4, 0, 13, 15],
[max, max, max, max, 0, 4],
[max, max, max, max, max, 0]]

func dijkstra(map:[Array]) -> [Int] {

var book = Array.init(repeatElement(0, count: map.count))
var dist = map.first!

book[0] = 1
for i in 0..<(map.count - 1) {
    
    //取出离源点最近的点
    var min = max
    var u = 0
    
    for j in 0.. (dist[u] + map[u][v]) {
                dist[v] = dist[u] + map[u][v]
            }
        }
    }
}

return dist

}
print(dijkstra(map: map)) //[0, 1, 8, 4, 13, 17]

你可能感兴趣的:(Swift最短路径之Dijkstra(单源最短路)算法)