[英]How to enumerate possible reconstructions of a Hamiltonian cycle without DFS/BFS?
我有一個有向哈密頓循環:
[..., a, b, ... , c, d, ..., e, f, ...]
其中b = next(a)
, d = next(c)
, f = next(e)
。
假設我刪除了邊(a,b),(c,d)和(e,f)。
問題 :如何生成圖形的所有可能重組,使其保持哈密頓循環(請記住,我可能必須反轉其中一個部分中的順序以確定方向)?
我知道的
我知道通過去除n邊緣可達到的新漢密爾頓循環的數量是double-factorial(n-1)
。 我也知道,如果我刪除兩個連續的邊,我會得到重復的解決方案(我很好......它們相對於獨特的循環應該是最小的並且它保持結果代碼干凈)。
我嘗試過的(粗略的偽代碼)
考慮這一點的一種方法是,任何屈服的哈密爾頓循環都必須保留在跳轉到新的部分之前必須沿着斷開的圖形的部分行進的屬性。
因此,例如,考慮上面的循環(其中n = 3
),有以下3個部分:
[b, ..., c]
[d, ..., e]
[f, ..., a]
那么讓我們說我的新解決方案如下:
[..., a, d, ...]
我知道e是我的終端頂點列表中必須出現的頂點。
所以,使用這個想法,Python將是這樣的:
from itertools import permutations
def hamiltonian_cycles(l, s=None, r=None):
if s is None:
s = [l[0]]
if r is None:
r = l[1:]
if not r:
yield s
else:
for permutation in permutations(r):
s1 = s[:] + [permutation[0]]
for cycle in hamiltonian_cycles(l, s1, permutation[1:]):
yield cycle
s2 = s[:] + [(permutation[0][1], permutation[0][0])]
for cycle in hamiltonian_cycles(l, s2, permutation[1:]):
yield cycle
>>> l = [('f', 'a'), ('b', 'c'), ('d', 'e')]
>>> for cycle in hamiltonian_cycles(l):
... print(cycle)
[('f', 'a'), ('b', 'c'), ('d', 'e')]
[('f', 'a'), ('b', 'c'), ('e', 'd')]
[('f', 'a'), ('c', 'b'), ('d', 'e')]
[('f', 'a'), ('c', 'b'), ('e', 'd')]
[('f', 'a'), ('d', 'e'), ('b', 'c')]
[('f', 'a'), ('d', 'e'), ('c', 'b')]
[('f', 'a'), ('e', 'd'), ('b', 'c')]
[('f', 'a'), ('e', 'd'), ('c', 'b')]
這看起來很丑陋並且在n=3
停止工作,因此問題就在於此。
為什么我不想使用BFS / DFS
我需要一個在刪除的邊數上是線性的生成器,而不是總邊數+頂點數。
由於這個有用的答案在這里 ,這里,做它的代碼。
from itertools import chain, permutations, product
def new_edge_sets(deleted_edges):
def edges_to_pieces(l):
new_list = []
n = len(l)
for i in xrange(-1,n-1):
new_list.append((l[i%n][1], l[(i+1)%n][0]))
return new_list
def permute(it):
return product(*(permutations(i) for i in it))
def permute2(it):
return chain.from_iterable(permute(p) for p in permutations(it))
def pieces_to_edges(p):
new_list = []
n = len(p)
for i in xrange(n):
new_list.append((p[i%n][1], p[(i+1)%n][0]))
return new_list
def permute3(s):
return (pieces_to_edges(s[:1] + list(p)) for p in permute2(s[1:]))
return permute3(edges_to_pieces(deleted_edges))
例:
>>> deleted_edges = [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h')]
>>> l = list(new_edge_sets(deleted_edges))
>>> len(l)
48
>>> for new_edges in l:
... print(new_edges)
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h')]
[('a', 'b'), ('c', 'd'), ('e', 'g'), ('f', 'h')]
[('a', 'b'), ('c', 'e'), ('d', 'f'), ('g', 'h')]
[('a', 'b'), ('c', 'e'), ('d', 'g'), ('f', 'h')]
[('a', 'c'), ('b', 'd'), ('e', 'f'), ('g', 'h')]
[('a', 'c'), ('b', 'd'), ('e', 'g'), ('f', 'h')]
[('a', 'c'), ('b', 'e'), ('d', 'f'), ('g', 'h')]
[('a', 'c'), ('b', 'e'), ('d', 'g'), ('f', 'h')]
[('a', 'b'), ('c', 'f'), ('g', 'd'), ('e', 'h')]
[('a', 'b'), ('c', 'f'), ('g', 'e'), ('d', 'h')]
[('a', 'b'), ('c', 'g'), ('f', 'd'), ('e', 'h')]
[('a', 'b'), ('c', 'g'), ('f', 'e'), ('d', 'h')]
[('a', 'c'), ('b', 'f'), ('g', 'd'), ('e', 'h')]
[('a', 'c'), ('b', 'f'), ('g', 'e'), ('d', 'h')]
[('a', 'c'), ('b', 'g'), ('f', 'd'), ('e', 'h')]
[('a', 'c'), ('b', 'g'), ('f', 'e'), ('d', 'h')]
[('a', 'd'), ('e', 'b'), ('c', 'f'), ('g', 'h')]
[('a', 'd'), ('e', 'b'), ('c', 'g'), ('f', 'h')]
[('a', 'd'), ('e', 'c'), ('b', 'f'), ('g', 'h')]
[('a', 'd'), ('e', 'c'), ('b', 'g'), ('f', 'h')]
[('a', 'e'), ('d', 'b'), ('c', 'f'), ('g', 'h')]
[('a', 'e'), ('d', 'b'), ('c', 'g'), ('f', 'h')]
[('a', 'e'), ('d', 'c'), ('b', 'f'), ('g', 'h')]
[('a', 'e'), ('d', 'c'), ('b', 'g'), ('f', 'h')]
[('a', 'd'), ('e', 'f'), ('g', 'b'), ('c', 'h')]
[('a', 'd'), ('e', 'f'), ('g', 'c'), ('b', 'h')]
[('a', 'd'), ('e', 'g'), ('f', 'b'), ('c', 'h')]
[('a', 'd'), ('e', 'g'), ('f', 'c'), ('b', 'h')]
[('a', 'e'), ('d', 'f'), ('g', 'b'), ('c', 'h')]
[('a', 'e'), ('d', 'f'), ('g', 'c'), ('b', 'h')]
[('a', 'e'), ('d', 'g'), ('f', 'b'), ('c', 'h')]
[('a', 'e'), ('d', 'g'), ('f', 'c'), ('b', 'h')]
[('a', 'f'), ('g', 'b'), ('c', 'd'), ('e', 'h')]
[('a', 'f'), ('g', 'b'), ('c', 'e'), ('d', 'h')]
[('a', 'f'), ('g', 'c'), ('b', 'd'), ('e', 'h')]
[('a', 'f'), ('g', 'c'), ('b', 'e'), ('d', 'h')]
[('a', 'g'), ('f', 'b'), ('c', 'd'), ('e', 'h')]
[('a', 'g'), ('f', 'b'), ('c', 'e'), ('d', 'h')]
[('a', 'g'), ('f', 'c'), ('b', 'd'), ('e', 'h')]
[('a', 'g'), ('f', 'c'), ('b', 'e'), ('d', 'h')]
[('a', 'f'), ('g', 'd'), ('e', 'b'), ('c', 'h')]
[('a', 'f'), ('g', 'd'), ('e', 'c'), ('b', 'h')]
[('a', 'f'), ('g', 'e'), ('d', 'b'), ('c', 'h')]
[('a', 'f'), ('g', 'e'), ('d', 'c'), ('b', 'h')]
[('a', 'g'), ('f', 'd'), ('e', 'b'), ('c', 'h')]
[('a', 'g'), ('f', 'd'), ('e', 'c'), ('b', 'h')]
[('a', 'g'), ('f', 'e'), ('d', 'b'), ('c', 'h')]
[('a', 'g'), ('f', 'e'), ('d', 'c'), ('b', 'h')]
from matrix import MatrixOperations A=[[0,1,0,1,1,0,0],[1,0,1,0,0,0,0],[0,1,0,1,0,0,1],[1,0,1,0,1,0,1],[1,0,0,1,0,1,0],[0,0,0,0,1,0,1],[0,0,1,1,0,1,0]] print("THE ADJACENCY MATRIX\\n");MatrixOperations.PrintMatrix(A) n=len(A) X=[] vis=[0 for i in range(n)] def hamiltonian(vis,A,i): vis[i]=1 if(len(X)==n-1 and A[i][0]==1): print (X) for j in range(0,n): if (vis[j]==0 and A[i][j]==1): X.append(j) #print(X) this print shows the whole tracing process hamiltonian(vis,A,j) if(len(X)>0): del X[-1] vis[i]=0 print("\\nPossible Hamiltonian cycles") hamiltonian(vis,A,0)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.