目前在學Pyqgis
想實現的功能是給一個起點跟結束start=A end=H
line_dict={
'A':[['B','C']],
'B':[['A','C']],
'C':[['A','B'],['E','F','G']],
'E':[['C','F','G'],['I','H']],
'F':[['C','E','G']],
'I':[['H','E']],
'H':[['I','E']],
'G':[['E','F','C']]}
每條線是dictionary value為相連的線id
可以順利找到路徑 但是會有些bug
走過的線都加進去
紅色的圈是交接點 不需管黃色的點
紅色線上面的字母對應的是原始資料line_dict的key ,value是紅色圈交接點所交接的紅線英文字母ID
有嘗試過 但是答案有些出入
start,end=A,H
road,tmp=[start],start
layer.removeSelection()
while tmp!=end:
for i in line_dict[tmp]:
for j in i :
print(f"開始點{road[-1]} 有{len(i)}個交接點:{i}")
if j not in road:
road.append(j)
tmp=j
print(f"最終路徑為:{road}")
layer.select(road)
起點為A 終點為H
提供思路也行 小弟再來思考看看 ~ 感謝大大
output 為A-->C-->E-->H
程式採用遞迴,修改如下:
# data
line_dict={
'A':[['B','C']],
'B':[['A','C']],
'C':[['A','B'],['E','F','G']],
'E':[['C','F','G'],['I','H']],
'F':[['C','E','G']],
'I':[['H','E']],
'H':[['I','E']],
'G':[['E','F','C']]
}
# 整理 line_dict 的 value
line_dict_flatten = {}
for k, v in line_dict.items():
new_list = []
for item in v:
new_list += item
line_dict_flatten[k] = new_list
print(line_dict_flatten)
# 尋找可行路徑
start_node,end_node='A','H'
road,current_node=[start_node],start_node
max_nodes = 10
all_feasible_path = []
# 遞迴
def find_next(node, path):
if len(path)>=max_nodes: return
for next_node in line_dict_flatten[node]:
if next_node != end_node:
path2 = path.copy()
path2.append(next_node)
#print(path2)
find_next(next_node, path2)
else:
# if ''.join(path) == "ACE":
# print(path + [next_node])
all_feasible_path.append(path + [next_node])
return
find_next(current_node, road)
# 找最短路徑
print(min(all_feasible_path, key=lambda x: len(x)))
兩種作法供參考
def shortest_path(start, target):
seen = set()
queue = [(start, [])]
while queue:
node, history = queue.pop(0)
if node == target:
return history + [node]
if node in seen:
continue
seen.add(node)
for n in nodes_info[node]:
queue.append((n, history + [node]))
line_dict = {
"A": [["B", "C"]],
"B": [["A", "C"]],
"C": [["A", "B"], ["E", "F", "G"]],
"E": [["C", "F", "G"], ["I", "H"]],
"F": [["C", "E", "G"]],
"I": [["H", "E"]],
"H": [["I", "E"]],
"G": [["E", "F", "C"]],
}
# 將原始資料攤平
nodes_info = {key: [item for sub in val for item in sub] for key, val in line_dict.items()}
print(shortest_path("A", "H"))
如果懶惰的話,可以用 networkx
import networkx as nx
line_dict = {
"A": [["B", "C"]],
"B": [["A", "C"]],
"C": [["A", "B"], ["E", "F", "G"]],
"E": [["C", "F", "G"], ["I", "H"]],
"F": [["C", "E", "G"]],
"I": [["H", "E"]],
"H": [["I", "E"]],
"G": [["E", "F", "C"]],
}
# 將原始資料攤平
nodes_info = {key: [item for sub in val for item in sub] for key, val in line_dict.items()}
g = nx.DiGraph()
for node in nodes_info:
for node2 in nodes_info[node]:
g.add_edge(node, node2)
print(nx.shortest_path(g, "A", "H"))