python: Dijkstra Algorithms
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/7/7 23:36
# User : geovindu
# Product : PyCharm
# Project : Pysimple
# File : Dijkstra demo.py
import heapq
import networkx as nx
import matplotlib.pyplot as plt
# Dijkstra 通用算法
def dijkstra(graph, start, end):
dist = {city: float("inf") for city in graph}
dist[start] = 0
prev = {city: None for city in graph}
heap = [(0, start)]
visited = set()
while heap:
current_dist, curr_city = heapq.heappop(heap)
if curr_city in visited:
continue
if curr_city == end:
break
visited.add(curr_city)
for neighbor, weight in graph[curr_city].items():
if neighbor in visited:
continue
new_dist = current_dist + weight
if new_dist < dist[neighbor]:
dist[neighbor] = new_dist
prev[neighbor] = curr_city
heapq.heappush(heap, (new_dist, neighbor))
# 回溯路径
path = []
temp = end
while temp is not None:
path.append(temp)
temp = prev[temp]
path.reverse()
return dist[end], path
# 路网数据:里程(km)、耗时(h)、高速费(元)
graph_km = {
"深圳": {"惠州":75, "广州":140, "东莞":65},
"惠州": {"深圳":75, "河源":90},
"东莞": {"深圳":65, "广州":50},
"广州": {"深圳":140, "东莞":50, "韶关":190, "佛山":25},
"佛山": {"广州":25, "肇庆":70},
"肇庆": {"佛山":70, "梧州":210},
"梧州": {"肇庆":210, "桂林":260},
"桂林": {"梧州":260, "柳州":170},
"柳州": {"桂林":170, "南宁":220},
"南宁": {"柳州":220},
"韶关": {"广州":190, "赣州":230},
"河源": {"惠州":90, "赣州":180},
"赣州": {"河源":180, "韶关":230, "吉安":240, "南昌":390},
"吉安": {"赣州":240, "南昌":215, "萍乡":280},
"南昌": {"赣州":390, "吉安":215, "九江":130, "福州":380},
"萍乡": {"吉安":280, "长沙":150},
"长沙": {"萍乡":150, "武汉":280, "株洲":60},
"株洲": {"长沙":60, "衡阳":130},
"衡阳": {"株洲":130, "郴州":180},
"郴州": {"衡阳":180, "韶关":150},
"九江": {"南昌":130, "武汉":200},
"武汉": {"九江":200, "长沙":280, "郑州":470},
"郑州": {"武汉":470, "西安":450},
"西安": {"郑州":450},
"福州": {"南昌":380, "厦门":230},
"厦门": {"福州":230}
}
graph_hour = {
"深圳": {"惠州":1.0, "广州":1.8, "东莞":0.8},
"惠州": {"深圳":1.0, "河源":1.3},
"东莞": {"深圳":0.8, "广州":0.7},
"广州": {"深圳":1.8, "东莞":0.7, "韶关":2.2, "佛山":0.4},
"佛山": {"广州":0.4, "肇庆":0.9},
"肇庆": {"佛山":0.9, "梧州":2.5},
"梧州": {"肇庆":2.5, "桂林":3.0},
"桂林": {"梧州":3.0, "柳州":2.0},
"柳州": {"桂林":2.0, "南宁":2.5},
"南宁": {"柳州":2.5},
"韶关": {"广州":2.2, "赣州":2.7},
"河源": {"惠州":1.3, "赣州":2.0},
"赣州": {"河源":2.0, "韶关":2.7, "吉安":2.6, "南昌":4.2},
"吉安": {"赣州":2.6, "南昌":2.3, "萍乡":3.0},
"南昌": {"赣州":4.2, "吉安":2.3, "九江":1.4, "福州":4.0},
"萍乡": {"吉安":3.0, "长沙":1.6},
"长沙": {"萍乡":1.6, "武汉":3.0, "株洲":0.8},
"株洲": {"长沙":0.8, "衡阳":1.4},
"衡阳": {"株洲":1.4, "郴州":2.0},
"郴州": {"衡阳":2.0, "韶关":1.7},
"九江": {"南昌":1.4, "武汉":2.1},
"武汉": {"九江":2.1, "长沙":3.0, "郑州":4.8},
"郑州": {"武汉":4.8, "西安":4.3},
"西安": {"郑州":4.3},
"福州": {"南昌":4.0, "厦门":2.4},
"厦门": {"福州":2.4}
}
graph_cost = {
"深圳": {"惠州":35, "广州":65, "东莞":30},
"惠州": {"深圳":35, "河源":42},
"东莞": {"深圳":30, "广州":25},
"广州": {"深圳":65, "东莞":25, "韶关":85, "佛山":15},
"佛山": {"广州":15, "肇庆":35},
"肇庆": {"佛山":35, "梧州":100},
"梧州": {"肇庆":100, "桂林":120},
"桂林": {"梧州":120, "柳州":70},
"柳州": {"桂林":70, "南宁":95},
"南宁": {"柳州":95},
"韶关": {"广州":85, "赣州":105},
"河源": {"惠州":42, "赣州":80},
"赣州": {"河源":80, "韶关":105, "吉安":110, "南昌":180},
"吉安": {"赣州":110, "南昌":95, "萍乡":125},
"南昌": {"赣州":180, "吉安":95, "九江":55, "福州":170},
"萍乡": {"吉安":125, "长沙":65},
"长沙": {"萍乡":65, "武汉":130, "株洲":25},
"株洲": {"长沙":25, "衡阳":55},
"衡阳": {"株洲":55, "郴州":80},
"郴州": {"衡阳":80, "韶关":65},
"九江": {"南昌":55, "武汉":85},
"武汉": {"九江":85, "长沙":130, "郑州":210},
"郑州": {"武汉":210, "西安":190},
"西安": {"郑州":190},
"福州": {"南昌":170, "厦门":105},
"厦门": {"福州":105}
}
# 城市坐标布局
city_pos = {
"深圳":(5,0), "惠州":(6,1), "东莞":(4,0), "广州":(3,0),
"佛山":(2,0), "肇庆":(1,1), "梧州":(-2,2), "桂林":(-3,4),
"柳州":(-4,3), "南宁":(-5,1), "韶关":(2,4), "河源":(7,3),
"赣州":(8,6), "吉安":(9,9), "南昌":(10,8), "萍乡":(7,8),
"长沙":(6,9), "株洲":(6,8), "衡阳":(6,6), "郴州":(6,4),
"九江":(11,9), "武汉":(9,11), "郑州":(10,14), "西安":(7,15),
"福州":(13,7), "厦门":(14,4)
}
all_city_list = list(city_pos.keys())
def draw_route(start, end, path_km, total_km):
G = nx.Graph()
for city, neighbors in graph_km.items():
for neighbor, km in neighbors.items():
G.add_edge(city, neighbor, weight=km)
plt.figure(figsize=(14,11))
# 全部节点、普通道路
nx.draw_networkx_nodes(G, city_pos, node_color="#cfe2f3", node_size=1200)
nx.draw_networkx_edges(G, city_pos, edge_color="#cccccc", width=1)
nx.draw_networkx_labels(G, city_pos, font_size=9, font_weight="bold")
# 最优路径红色加粗
path_edges = list(zip(path_km, path_km[1:]))
nx.draw_networkx_edges(G, city_pos, edgelist=path_edges, edge_color="red", width=5)
# 起点终点特殊标记
nx.draw_networkx_nodes(G, city_pos, nodelist=[start], node_color="#ff7777", node_size=1500)
nx.draw_networkx_nodes(G, city_pos, nodelist=[end], node_color="#77ff77", node_size=1500)
# 全部英文标题,无中文,彻底消除警告
plt.title(f"{start} to {end} Shortest Distance Route | Total: {total_km} km\nPath: {' -> '.join(path_km)}", fontsize=14)
plt.axis("off")
plt.tight_layout()
plt.show()
if __name__ == "__main__":
# Windows专用中文字体配置,微软雅黑系统自带,不会缺失
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
plt.rcParams["axes.unicode_minus"] = False
print("===== China City Highway Route Planner =====")
print("Available cities:")
print(", ".join(all_city_list))
print("-" * 60)
# 交互输入
while True:
start_input = input("Input start city: ").strip()
end_input = input("Input destination city: ").strip()
# 校验城市是否存在
if start_input not in all_city_list or end_input not in all_city_list:
print("City not found, please re-enter!\n")
continue
if start_input == end_input:
print("Start and destination cannot be the same!\n")
continue
break
# 计算三种方案
km_total, km_path = dijkstra(graph_km, start_input, end_input)
hour_total, hour_path = dijkstra(graph_hour, start_input, end_input)
cost_total, cost_path = dijkstra(graph_cost, start_input, end_input)
# 控制台输出结果(英文)
print("\n" + "="*60)
print(f"【{start_input} -> {end_input} Three Optimal Plans】")
print("="*60)
print(f"📏 Shortest Distance: Total {km_total} km")
print(f" Route: {' -> '.join(km_path)}")
print(f"\n⏰ Shortest Time: Total {hour_total:.1f} hours")
print(f" Route: {' -> '.join(hour_path)}")
print(f"\n💰 Minimum Toll Fee: Total {cost_total} RMB")
print(f" Route: {' -> '.join(cost_path)}")
print("="*60)
# 绘制路网图
draw_route(start_input, end_input, km_path, km_total)
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号