[英]Find path from a list of tuples in Python
我有以下形式的元組列表:
data = [('Abe', 'Bob', '3'),
('Abe', 'Frank', '5'),
('Abe', 'George', '4'),
('Carl', 'Bob', '1'),
('Dan', 'Carl', '2')]
此數據模擬無向圖,其中從'Abe'到大小為3的'Bob'之間存在聯系。由於該圖是無向的,因此也意味着從'Bob'到大小為3的'Abe'之間存在聯系。好。
我需要顯示兩個輸入之間是否存在連接及其權重。 例如,如果輸入為“ Abe”,“ Dan”,則結果將返回從“ Abe”到“ Dan”的最短(最小節點跳,不是最不重要的權重)路徑,即Abe,Bob,Carl,Dan和權重3 + 1 + 2 = 6。
我有這段代碼顯示“ Abe”是否會到達“ Dan”,但是我不知道如何返回路徑。
def get_path_and_weight(data, start, end):
reachable = [start]
added = -1
while added != 0:
added = 0
for first, second, weight in data:
if(first in reachable) and (second not in reachable):
reachable.append(second)
added += 1
if(first not in reachable) and (second in reachable):
reachable.append(first)
added += 1
if (end in reachable):
print("YES")
#return path
else:
print("NO")
有許多已經開發和調試過的軟件包可以做到這一點,例如, networkx
import networkx as nx
data = [('Abe', 'Bob', '3'),
('Abe', 'Frank', '5'),
('Abe', 'George', '4'),
('Carl', 'Bob', '1'),
('Dan', 'Carl', '2')]
g = nx.Graph()
for e in data:
g.add_edge(e[0], e[1], distance=int(e[2]))
>>> nx.shortest_path(g, 'Abe', 'Bob', 'distance'), nx.shortest_path_length(g, 'Abe', 'Bob', 'distance')
(['Abe', 'Bob'], 3)
您可以生成所有可能的路徑,然后按權重對它們進行排序。 注意我已經將數據中的權重更改為數字,而不是字符串:
data = [
('Abe', 'Bob', 3),
('Abe', 'Frank', 5),
('Abe', 'George', 4),
('Carl', 'Bob', 1),
('Dan', 'Carl', 2),
]
WEIGHT = 0
NODES = slice(1, None)
def get_path_and_weight(data, start, end):
paths = [[0, start]]
added = True
while added:
added = False
for first, second, weight in data:
for path in paths:
candidate = None
if (first in path[NODES]) and (second not in path[NODES]):
candidate = second
elif (first not in path[NODES]) and (second in path[NODES]):
candidate = first
if candidate:
new_path = list(path)
new_path.append(candidate)
new_path[WEIGHT] += weight
if new_path not in paths:
paths.append(new_path)
added = True
for path in sorted(paths):
if end in path[NODES]:
return path
return None
然后,您可以將其稱為:
weight, *path = get_path_and_weight(data, "Abe", "Dan")
print(path, "with weight", weight)
給出結果:
['Abe', 'Bob', 'Carl', 'Dan'] with weight 6
並且由於它返回路徑或None
,因此您仍然可以將其用作謂詞函數:
if get_path_and_weight(data, "Abe", "Dan"):
print("connected")
def get_rpath_with_weight(data,start,end):
rpath = []
reachable=False
nxt_dst = start
weight_ = 0
rpath.append(nxt_dst)
for datum in data:
if nxt_dst in datum:
#print datum
fm_ = datum[0]
to_ = datum[1]
weight_ = weight_ + int(datum[2])
if fm_ == nxt_dst:
nxt_dst = to_
else:
nxt_dst = fm_
if nxt_dst == end:
reachable=True
rpath.append(nxt_dst)
print rpath,weight_,reachable
get_rpath_with_weight(data,'Abe','Dan')
get_rpath_with_weight(data,'Dan','Frank')
樣本輸出
['Abe', 'Bob', 'Carl', 'Dan'] 6 True
['Dan', 'Carl'] 2 False
上面的示例可以獲取路徑並確定是否可訪問,但是我認為您也需要進一步增強它以處理多個路徑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.