dijkstra算法,最经典的单源最短路径算法
以下面的有向加权图分析dijkstra算法
S=[0]
D(0)=0 D(1)=600 D(2)=900 D(3)=200 D(4)=1100 D(5)= D(7)=$
S=[0、3]
D(0)=0 D(1)=600 D(2)=800 D(3)=200 D(4)=1100 D(5)= D(7)=1700
S=[0、3、1]
D(0)=0 D(1)=600 D(2)=800 D(3)=200 D(4)=1000 D(5)=800 D(6)=$ D(7)=1700
S=[0、3、1、2]
D(0)=0 D(1)=600 D(2)=800 D(3)=200 D(4)=1000 D(5)=800 D(6)=1300 D(7)=1700
S=[0、3、1、2、5]
D(0)=0 D(1)=600 D(2)=800 D(3)=200 D(4)=1000 D(5)=800 D(6)=1200 D(7)=1700
S=[0、3、1、2、5、4]
D(0)=0 D(1)=600 D(2)=800 D(3)=200 D(4)=1000 D(5)=800 D(6)=1200 D(7)=1700
S=[0、3、1、2、5、4、6、7]
D(0)=0 D(1)=600 D(2)=800 D(3)=200 D(4)=1000 D(5)=800 D(6)=1200 D(7)=1700
代码实现
const MaxDistance = math.MaxInt32
func dijkstra(i int, j int, n int, weight []int, edges [][]int) int {
s := make(map[int]int, 0)
distance := make(map[int]int, 0)
for k := 0; k < n; k++ {
if k == i {
distance[k] = 0
} else {
distance[k] = math.MaxInt32
}
}
outCome := make(map[int]map[int]int, 0)
for k, edge := range edges {
u, v := edge[0], edge[1]
if _, ok := outCome[u]; !ok {
outCome[u] = make(map[int]int, 0)
}
outCome[u][v] = weight[k]
if u == i {
distance[v] = weight[k]
}
}
fmt.Println("s:", s)
fmt.Println("distance:", distance)
fmt.Println("outCome:", outCome)
minDistance := func() (int, int) {
v := -1
min := MaxDistance
for i, d := range distance {
if _, ok := s[i]; !ok && d < min {
min = d
v = i
}
}
return v, min
}
for len(outCome) > 0 {
v, min := minDistance() //v=3 min=200
if v < 0 {
return -1
}
s[v] = 0 //s = [0:0, 3:0]
tmp := outCome[v] // tmp = [2:600, 7:1500]
for key, val := range tmp {
//200 + 600 < 900
if min+val < distance[key] {
distance[key] = min + val
}
}
delete(outCome, v)
}
fmt.Println("-----------------------------")
fmt.Println(s)
fmt.Println(distance)
fmt.Println(outCome)
return distance[j]
}
func main() {
edges := [][]int{[]int{0, 1}, []int{0, 2}, []int{0, 3}, []int{0, 4}, []int{1, 2}, []int{1, 4}, []int{1, 5}, []int{2, 1}, []int{2, 6}, []int{2, 7}, []int{3, 2}, []int{3, 7}, []int{4, 5}, []int{5, 6}, []int{6, 1}}
weight := []int{600, 900, 200, 1100, 500, 400, 200, 400, 500, 1400, 600, 1500, 400, 300, 200}
fmt.Println(dijkstra(0, 7, 8, weight, edges))
}
原理简单来说就是一条最短路径上的任意节点到原点的距离都是最短的。所以每次只用找到最短路径节点并延伸即可。
参考文章: