[英]Hamiltonian Path Algorithm Time-Complexity
我正在編寫一個程序在圖中搜索漢密爾頓路徑。 它通過搜索圖的各個頂點之間的所有可能排列,然后檢查每個排列中所有連續頂點之間是否存在邊來工作。
我計算出時間復雜度為O(n)=n!*n^2
。
為了計算時間復雜度,我認為:為了計算每個排列,我遍歷了頂點列表。 更何況還有n! 排列,然后對於每個排列,我再次遍歷頂點列表以檢查兩個連續頂點之間是否存在邊。 因此,這使O(n)=n!*n*n
。
我在計算中犯了錯誤嗎?
我想我做錯了,因為我測量了程序在不同大小的圖形上執行的時間,並且復雜度看起來更像O(n)=n!
以下是程序執行所需時間的一些值,其中圖中的頂點數為n。
On a Machine with 3.5GHz i7 Processor and 16 GB RAM:
n=2 : 0.000025 s
n=3 : 0.000041 s
n=4 : 0.00013 s
n=5 : 0.00065 s
n=6 : 0.0045 s
n=7 : 0.039 s
n=8 : 0.31 s
n=9 : 3.2 s
n=10 : 36 s
n=11 : 455 s
這是我的代碼:
主要
graph=Graph([[1,4],[0,2,3],[1,3],[1,2,4],[0,3]]) #n = 5 (number of nodes)
ham = hamiltonianPaths0(graph)
hamiltonianPaths0函數
def hamiltonianPaths0(graph, circuit=False):
name = "circuit" if circuit else "path"
f=0
paths=[]
for i in permutations(graph.vertices):
k=1
for j in range(len(i)-1+int(circuit)):
if [i[j],i[(j+1)%len(i)]] in graph.edges:
#print("Edge from {} to {}".format(i[j], i[(j+1)%len(i)]))
k+=1
if k==len(i)+int(circuit):
print("{} is a hamiltonian {} !".format(i,name))
f+=1
paths.append(i)
print("{} hamiltonian {}(s) found !".format(f,name))
return paths
排列功能
def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = list(range(n))
cycles = list(range(n, n-r, -1))
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return
PS:圖類從列表中生成一個圖,為每個頂點指定與其鏈接的其他頂點。 例如: Graph([[1],[0,2],[1]])
將產生一個圖形,該圖形具有3個頂點(0,1,2),其中0鏈接到1,1鏈接到0,2鏈接到2,2鏈接至1)。 Graph.vertices
是包含圖的所有頂點的列表。
O(n!)和O(n!* n ^ 2)具有相同的復雜度。 讓我們在其右側以較低的數量“超調”並減少表達式。
n! * n * n <= n! * (n+1) * (n+2)
n! * n * n <= (n+2)!
但是,O(n!)== O((n + 2)!)
優質教育
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.