Dijkstra算法正確性證明
問題:求圖中點1到其他各點的最短距離
算法描述:
設初始時圖的所有點的集合U
-
把起點s放入初始集合Set中
U=U-{s}
Set=Set+{s}
-
找s經過集合Set中的點,能達到的距離最短的點k(k\(\in\)U),將k並入Set
言外之意k的前一個點必然屬於Set
U=U-{k}
Set=Set+{k}
由於每次引入的只有一個點k,所以只需要基於k對s到達所有點的距離進行更新,之前的點無需考慮
-
repet step2
until U == Set
算法正確性證明:
1. 變量的命名:
Set={1,2,,,,,,x}
記錄已求出最短路徑的頂點
dist[u]
從start點開始,經過Set中的點,到u點(u\(\in\)U)的最短距離
short[u]
從start開始到u的全局最短路徑(路徑中可能有部分點\(\notin\)Set)
可知 \(short[u]\leq dist[u]\)
U
所有點除去Set中的點組成的集合
2. 證明過程:(貪心正確性的證明)
需要證明的命題:
算法進行到第k步時,Set中的任意一個節點Set_i的dist[Set_i]等於全局最短路徑short[Set_i]
(第n步時,dist[n]=short[n],此時找到點1到所有點的最短距離)
歸納基礎:
k=1,Set={start_point} => dist[start_point] == short[start_point] ==0,命題正確
歸納假設:
假設第k步成立,現在來證明第k+1步成立
第k步成立的作用在於s到Set中的所有節點(設某節點為k)有dist[k]=short[k]
所以對於引入的第k+1個點v,s->v序列中Set中的點一定是連續的(如下圖。因為s->v中的Set的最后一個點u之前的所有點必然都屬於Set)
設k+1步選擇了頂點v(v是s經過Set所能到達的U中距離最近的點)
則頂點v必然與Set中的u點直接相連, 也就是說上圖中非Set中的點集為空集
證明如下:
假設藍色部分“非Set中的點”所組成的集合不為空,也就是s到v的最短路徑是先有一部分Set中的點,再由一部分U中的點組成,那么
short[v]:s->...->u->...->y->...->v
如下圖
因為之前論證過s->u(u代表Set集合中的最后一個點)過程中所有的點均屬於Set,所以有:
- s->...->u1->v
- s->...->u2->y->v
易知length(s->...->u1->v)\(\leq\)length(s->...->u2->y)
v是s經由Set所能達到的距離最小點
又length(y->v)$\geq$0
所以不存在這樣的y,s到v的最短路徑上v的前一個節點必然為Set中的點
從而也就論證了迪傑斯特拉算法的正確性