python-圖論最短路徑算法
一、深度優先算法、廣度優先算法差別
'''
查找最短路徑
定義:
v = 頂點
t = 目标頂點
v1 = 子頂點
廣度優先算法:優先周遊 v 的所有鄰接頂點,在所有鄰接頂點中查找 t,直到所有頂點都通路過;
深度優先算法:優先周遊 v 的第一個 v1,如果 v1 存在子頂點則繼續深入查找,直到以 v 為頂點的所有子節點通路過;
'''
二、執行結果
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
廣度優先搜尋過程
a ['b', 'c']
b ['a', 'c']
c ['a', 'd']
d ['e']
e ['d']
搜尋 a -> e 最短路徑
結果=e times=4 searched=['a', 'b', 'c', 'd', 'e']
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
深度優先搜尋過程
a ['b', 'c']
b ['a', 'c']
c ['a', 'd']
d ['e']
e ['d']
#!/usr/bin/env python3
# coding=utf-8
'''
查找最短路徑
定義:
v = 頂點
t = 目标頂點
v1 = 子頂點
廣度優先算法:優先周遊 v 的所有鄰接頂點,在所有鄰接頂點中查找 t,直到所有頂點都通路過;
深度優先算法:優先周遊 v 的第一個 v1,如果 v1 存在子頂點則繼續深入查找,直到以 v 為頂點的所有子節點通路過;
'''
from collections import deque
times = 0
tragetNode = None
def getGrahp():
gp = {
"a":["b","c"],
"b":["a","c"],
"c":["a","d"],
"d":["e"],
"e":["d"]
}
return gp
def search_widest(start,target):
'''
廣度優先搜尋:
(1)頂點v入隊列。
(2)當隊列非空時則繼續執行,否則算法結束。
(3)出隊列取得隊頭頂點v;通路頂點v并标記頂點v已被通路。
(4)查找頂點v的第一個鄰接頂點v1。
(5)若v的鄰接頂點v1未被通路過的,則v1入隊列。
(6)繼續查找頂點v的另一個新的鄰接頂點v1,轉到步驟(5)。直到頂點v的所有未被通路過的鄰接點處理完。轉到步驟(2)。
'''
global times
global tragetNode
gp = getGrahp() # 圖
searched = [start] # 已經搜尋過的頂點
search_queue = deque() # 搜尋隊列
search_queue += gp[start]
tragetNode = None
print('\n%s\n廣度優先搜尋過程'%('~'*30))
print(start,gp[start])
while search_queue:
v = search_queue.popleft() # 出隊一個待搜尋頂點
if v in searched or v not in gp.keys():
continue
print(v,gp[v])
times += 1
searched.append(v)
if v == target:
tragetNode = v
break
else:
search_queue += gp[v] # 待搜尋頂點搜尋隊列
print('\n')
print('搜尋 %s -> %s 最短路徑'%(start,target))
print('結果=%s\ttimes=%s\tsearched=%s'%(tragetNode,times,searched))
def search_deep(start,target):
'''
深度優先搜尋:
(1)通路初始頂點v并标記頂點v已通路。
(2)查找頂點v的第一個鄰接頂點w。
(3)若頂點v的鄰接頂點w存在,則繼續執行;否則回溯到v,再找v的另外一個未通路過的鄰接點。
(4)若頂點w尚未被通路,則通路頂點w并标記頂點w為已通路。
(5)繼續查找頂點w的下一個鄰接頂點wi,如果v取值wi轉到步驟(3)。直到連通圖中所有頂點全部通路過為止。
'''
global times
global tragetNode
times = 0
tragetNode = None
gp = getGrahp() # 圖
print('\n%s\n深度優先搜尋過程'%('~'*30))
searched = []
def func(v):
global times
global tragetNode
if v in searched or v not in gp.keys():
return
times += 1
searched.append(v)
print(v,gp[v])
if v == target:
tragetNode = v
return
for v1 in gp[v]:
func(v1)
func(start)
print('\n')
print('搜尋 %s -> %s 最短路徑'%(start,target))
print('結果=%s\ttimes=%s\tsearched=%s'%(tragetNode,times,searched))
def main():
start = 'a'
target = 'e'
search_widest(start,target)
search_deep(start,target)
if __name__ == '__main__':
main()