[英]Python: all simple paths in a directed graph
我正在使用其中沒有循環的(數量)有向圖,並且我需要找到任何兩個節點之間的所有簡單路徑。 一般來說,我不會擔心執行時間,但我必須在非常多的時間步中為非常多的節點執行此操作 - 我正在處理基於時間的模擬。
我過去曾嘗試過 NetworkX 提供的工具,但總的來說我發現它們比我的方法慢。 不知道最近有沒有什么變化。
我已經實現了這個遞歸函數:
import timeit
def all_simple_paths(adjlist, start, end, path):
path = path + [start]
if start == end:
return [path]
paths = []
for child in adjlist[start]:
if child not in path:
child_paths = all_simple_paths(adjlist, child, end, path)
paths.extend(child_paths)
return paths
fid = open('digraph.txt', 'rt')
adjlist = eval(fid.read().strip())
number = 1000
stmnt = 'all_simple_paths(adjlist, 166, 180, [])'
setup = 'from __main__ import all_simple_paths, adjlist'
elapsed = timeit.timeit(stmnt, setup=setup, number=number)/number
print 'Elapsed: %0.2f ms'%(1000*elapsed)
在我的計算機上,每次迭代平均需要 1.5 毫秒。 我知道這是一個小數目,但我不得不這樣做操作很多次。
如果您有興趣,我在這里上傳了一個包含鄰接列表的小文件:
我使用鄰接列表作為輸入,來自 NetworkX DiGraph 表示。
任何改進算法的建議(即它是否必須是遞歸的?)或我可以嘗試的其他方法都非常受歡迎。
謝謝你。
安德烈亞。
通過在此處緩存共享子問題的結果,您可以在不更改算法邏輯的情況下節省時間。
例如, all_simple_paths(adjlist, 'A', 'D', [])
調用all_simple_paths(adjlist, 'A', 'D', [])
將all_simple_paths(adjlist, 'D', 'E', [])
計算all_simple_paths(adjlist, 'D', 'E', [])
:
Python 有一個用於此任務的內置裝飾器lru_cache
。 它使用哈希來記住參數,因此您需要更改adjList
和tuple
path
,因為list
不可哈希。
import timeit
import functools
@functools.lru_cache()
def all_simple_paths(adjlist, start, end, path):
path = path + (start,)
if start == end:
return [path]
paths = []
for child in adjlist[start]:
if child not in path:
child_paths = all_simple_paths(tuple(adjlist), child, end, path)
paths.extend(child_paths)
return paths
fid = open('digraph.txt', 'rt')
adjlist = eval(fid.read().strip())
# you can also change your data format in txt
adjlist = tuple(tuple(pair)for pair in adjlist)
number = 1000
stmnt = 'all_simple_paths(adjlist, 166, 180, ())'
setup = 'from __main__ import all_simple_paths, adjlist'
elapsed = timeit.timeit(stmnt, setup=setup, number=number)/number
print('Elapsed: %0.2f ms'%(1000*elapsed))
在我的機器上運行時間:
- 原始:0.86ms
- 帶緩存:0.01ms
而且這種方法應該只在有很多共享的子問題時才有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.