簡而言之,您可能需要在邊上執行多次傳遞來組裝使用所有邊的路徑。
所包含的代碼運行在以下假設:
- 的溶液存在。即,所有頂點屬於底層圖的單個連接組件,並且對於除了2個頂點以外的全部或全部頂點,都可以使用
in_degree
= out_degree
。在後一種情況下,其中一個頂點有in_degree
- out_degree
= 1,另一個頂點有in_degree
- out_degree
= -1。
此外,即使有這些條件,對於利用所有邊找到從源到匯的路徑的問題,並不一定有獨特的解決方案。此代碼只找到一個解決方案,而不是所有解決方案(存在多種解決方案的示例是'雛菊'[(1,2),(2,1),(1,3),(3,1),(1,4),(4,1),(1,5),(5,1)]
,其中開始和結束是相同的。)
該想法是爲邊緣的起始節點索引的路徑創建所有邊的字典,然後在字典添加到路徑時刪除字典中的邊緣。我們不是試圖在第一遍中獲取路徑中的所有邊,而是多次查看字典,直到使用所有邊。第一遍創建從源到匯的路徑。隨後的通行證添加循環。
警告:幾乎沒有一致性檢查或驗證。如果起點不是邊緣的有效源,那麼返回的'路徑'將被斷開連接!
"""
This is a basic implementatin of Hierholzer's algorithm as applied to the case of a
directed graph with perhaps multiple identical edges.
"""
import collections
def node_dict(edge_list):
s_dict = collections.defaultdict(list)
for edge in edge_list:
s_dict[edge[0]].append(edge)
return s_dict
def get_a_path(n_dict,start):
"""
INPUT: A dictionary whose keys are nodes 'a' and whose values are lists of
allowed directed edges (a,b) from 'a' to 'b', along with a start WHICH IS
ASSUMED TO BE IN THE DICTIONARY.
OUTPUT: An ordered list of initial nodes and an ordered list of edges
representing a path starting at start and ending when there are no other
allowed edges that can be traversed from the final node in the last edge.
NOTE: This function modifies the dictionary n_dict!
"""
cur_edge = n_dict[start][0]
n_dict[start].remove(cur_edge)
trail = [cur_edge[0]]
path = [cur_edge]
cur_node = cur_edge[1]
while len(n_dict[cur_node]) > 0:
cur_edge = n_dict[cur_node][0]
n_dict[cur_node].remove(cur_edge)
trail.append(cur_edge[0])
path.append(cur_edge)
cur_node = cur_edge[1]
return trail, path
def find_a_path_with_all_edges(edge_list,start):
"""
INPUT: A list of edges given by ordered pairs (a,b) and a starting node.
OUTPUT: A list of nodes and an associated list of edges representing a path
where each edge is represented once and if the input had a valid Eulerian
trail starting from start, then the lists give a valid path through all of
the edges.
EXAMPLES:
In [2]: find_a_path_with_all_edges([(1,2),(2,1),(2,3),(1,2)],1)
Out[2]: ([1, 2, 1, 2, 3], [(1, 2), (2, 1), (1, 2), (2, 3)])
In [3]: find_a_path_with_all_edges([(1, 16), (9, 3), (8, 9), (15, 8), (5, 1), (8, 15), (3, 5)],8)
Out[3]:
([8, 15, 8, 9, 3, 5, 1, 16],
[(8, 15), (15, 8), (8, 9), (9, 3), (3, 5), (5, 1), (1, 16)])
"""
s_dict = node_dict(edge_list)
trail, path_check = get_a_path(s_dict,start)
#Now add in edges that were missed in the first pass...
while max([len(s_dict[x]) for x in s_dict]) > 0:
#Note: there may be a node in a loop we don't have on trail yet
add_nodes = [x for x in trail if len(s_dict[x])>0]
if len(add_nodes) > 0:
skey = add_nodes[0]
else:
print "INVALID EDGE LIST!!!"
break
temp,ptemp = get_a_path(s_dict,skey)
i = trail.index(skey)
if i == 0:
trail = temp + trail
path_check = ptemp + path_check
else:
trail = trail[:i] + temp + trail[i:]
path_check = path_check[:i] + ptemp + path_check[i:]
#Add the final node to trail.
trail.append(path_check[-1][1])
return trail, path_check
你有什麼試過的?有沒有遇到特定的問題,或者你只是想讓別人爲你編碼?你需要更具體的 – goncalopp
這裏有一些圖形包和解決方案!試過他們中的任何一個?例如蟒蛇,圖! –
不,我試圖做很久,我可以生成路徑,但他們不考慮我的循環。我試圖提取會形成一個循環的邊,然後嘗試開發考慮循環的路徑,但是我無法找到一個運行良好的代碼來幫助我找到所有可能的循環! – user3111649