前面已經多次介紹過dijkstra演算法是貪心演算法,是動態規劃,實際上可以從分支限界的角度來理解;
分支限界法,實際上就是回溯法,一般意義的回溯法是基於深度優先搜尋,也可以配合限界函式剪枝,通常分支限界法基於寬度優先搜尋,通過佇列或者優先順序佇列實現。
剪枝的策略:不相鄰的邊剪掉,二是結點控制關係的路徑剪掉,兩條路徑到達同乙個頂點,在解空間樹上是屬於兩條不同的路徑,把路徑長的節點後面的分支剪掉
import numpy as np
import heapq
class
dijkstra
:def
__init__
(self,graph,start)
:# 鄰接表
self.graph = graph
# 頂點個數
self.num =
len(graph)
#源點 self.start = start
# 已知最短路徑,又叫當前最優值,並初始化
self.dist =
self.dist[start]
=0.0
# 初始化優先順序佇列
self.queue =
(0.0
,start)
)#追蹤解
self.parent =
defshortest_path
(self)
:while self.queue:
#取出根節點
distance = enode[0]
vertex = enode[1]
# 取鄰接的邊,實際上過濾了不相鄰的邊
# 這裡可以寫成 for j in range(self.num),
# 看成完全n叉樹,也可以看成隨機叉樹的處理
for j in self.graph[vertex]
.keys():
# 他們都叫這個為控制約束,兩條到某同一點的路徑,長的那一條後面就被剪掉了
# 也就是貪心法裡面的貪心策略
if distance + self.graph[vertex]
[j]< self.dist[j]
: self.dist[j]
= distance + self.graph[vertex]
[j] self.parent[j]
= vertex
(self.dist[j]
,j))
defprint_result
(self)
(self.parent)
(self.dist)
def
dijkstra_test
(graph,start)
: pqueue =
(0.0
,start)
)
visit =
set(
) parent =
distance =
distance[start]
=0.0
while pqueue:
dist = pair[0]
vertex = pair[1]
visit.add(vertex)
edges = graph[vertex]
for v in edges:
if v not
in visit:
if dist + graph[vertex]
[v]< distance[v]
:(dist + graph[vertex]
[v],v)
) distance[v]
= dist + graph[vertex]
[v] parent[v]
= vertex
(parent)
(distance)
#%%
g =,
'b':
,'c':,
'd':
,'e':,
'f':
,'g':}
dij = dijkstra(g,
'd')
dij.shortest_path(
)dij.print_result(
)dijkstra_test(g,
'd')
分支限界法之單源最短路徑
問題描述 下面以乙個例子來說明單源最短路徑問題 在下圖所給的有向圖g中,每一邊都有乙個非負邊權。要求圖g的從源頂點s到所有其他頂點的最短路徑。演算法思想 解單源最短路徑問題的優先佇列式分支限界法用一極小堆來儲存活結點表。其優先順序是結點所對應的當前路長。1 從圖g的源頂點s和空優先佇列開始。2 結點...
單源最短路徑(分支限界)
優先順序 當前路徑長度 剪枝函式 由於圖g中各邊的權均非負,所以結點所對應的當前路長也是解空間樹中以該結點為根的子樹中所有結點對應的路長的乙個下界。擴充套件結點的過程中,一旦發現乙個結點的下界不小於當前找到的最短路長,則演算法剪去以該結點為根的子樹。資料的儲存 二維陣列type g n n 儲存鄰接...
分支限界法 優先佇列 單源最短路徑
演算法思想 分支限界法常以廣度優先或以最小耗費 最大效益 優先的方式搜尋問題的解空間樹。在分支限界法中,每乙個活結點只有一次機會成為擴充套件結點。活結點一旦成為擴充套件結點,就一次性產生其所有兒子結點。在這些兒子結點中,導致不可行解或導致非最優解的兒子結點被捨棄,其餘兒子結點被加入活結點表中。此後,...