首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从深圳到西安,最优运输路径怎么走?——用 Dijkstra 算法搞定它!

从深圳到西安,最优运输路径怎么走?——用 Dijkstra 算法搞定它!

原创
作者头像
Echo_Wish
发布2025-06-23 17:31:09
发布2025-06-23 17:31:09
1790
举报
文章被收录于专栏:云社区活动云社区活动

🚄 从深圳到西安,最优运输路径怎么走?——用 Dijkstra 算法搞定它!

作者:Echo_Wish | 自媒体领域:人工智能 & Python 技术关键词:图算法、Dijkstra、路径规划、费用优化、断路处理、可视化


🧭 1. 问题背景

假设你是一家物流调度平台的算法工程师,现在面临一个任务:如何从“深圳”发货到“西安”,找出一条运输时间最短的路线?我们给出了一个包含10个城市的运输图,其中每一条边标注了运输所需时间(单位:小时)。

这还不够,我们进一步模拟了现实场景的两个挑战:

  • 费用优化:每条路线不仅有运输时间,还有费用(你得为货车加油、过路费结算);
  • 断路处理:考虑到自然灾害、施工维修,有些路段可能“临时封路”!

我们的目标是构建一个智能算法,在各种限制条件下快速给出最优方案


🧠 2. 设计思路:选择 Dijkstra 算法(基础)+ A* + 拓展功能模块

🧱 Step 1:基本路径搜索(Dijkstra)

由于城市图是加权无向图,Dijkstra 是寻找最短路径的经典算法。它的核心思想是通过一个优先队列,每次扩展当前距离最短的节点,并更新邻接节点的距离。

💰 Step 2:加入费用(双目标)

每条边除了时间,还有费用。我们可以通过设定一个时间与费用的权重系数,将其合成为一个综合代价:

代码语言:txt
复制
总代价 = 时间 × w1 + 费用 × w2

这样用户可以“偏向便宜还是快速”。

⛔ Step 3:模拟断路

只需在图中删除某些边,再运行算法即可。用来测试“当一条路断了怎么办”。


🧾 3. 原始城市图数据 + 扩展成本信息

代码语言:python
复制
city_graph = {
    '深圳': {'广州': {'time': 1.5, 'cost': 50}, '东莞': {'time': 1.0, 'cost': 30}},
    '广州': {'深圳': {'time': 1.5, 'cost': 50}, '韶关': {'time': 2.5, 'cost': 70}, '长沙': {'time': 5.5, 'cost': 180}},
    '东莞': {'深圳': {'time': 1.0, 'cost': 30}, '惠州': {'time': 1.2, 'cost': 35}},
    '惠州': {'东莞': {'time': 1.2, 'cost': 35}, '武汉': {'time': 8.0, 'cost': 300}},
    '韶关': {'广州': {'time': 2.5, 'cost': 70}, '长沙': {'time': 4.0, 'cost': 120}},
    '长沙': {'韶关': {'time': 4.0, 'cost': 120}, '武汉': {'time': 3.0, 'cost': 100}, '郑州': {'time': 8.0, 'cost': 200}},
    '武汉': {'惠州': {'time': 8.0, 'cost': 300}, '长沙': {'time': 3.0, 'cost': 100}, '郑州': {'time': 4.5, 'cost': 150}, '西安': {'time': 10.0, 'cost': 320}},
    '郑州': {'长沙': {'time': 8.0, 'cost': 200}, '武汉': {'time': 4.5, 'cost': 150}, '洛阳': {'time': 2.0, 'cost': 60}},
    '洛阳': {'郑州': {'time': 2.0, 'cost': 60}, '西安': {'time': 5.0, 'cost': 150}},
    '西安': {'武汉': {'time': 10.0, 'cost': 320}, '洛阳': {'time': 5.0, 'cost': 150}}
}

👨‍💻 4. Dijkstra 算法实现(支持双目标 + 断路)

代码语言:python
复制
import heapq
import networkx as nx
import matplotlib.pyplot as plt

def dijkstra(city_graph, start, end, w_time=1.0, w_cost=0.0, broken_edges=None):
    queue = [(0, start, [], 0, 0)]  # (总代价, 当前城市, 路径, 总时间, 总费用)
    visited = set()

    while queue:
        total_weight, city, path, total_time, total_cost = heapq.heappop(queue)
        if city in visited:
            continue
        visited.add(city)
        path = path + [city]
        if city == end:
            return path, total_time, total_cost

        for neighbor, data in city_graph.get(city, {}).items():
            if broken_edges and (city, neighbor) in broken_edges or (neighbor, city) in broken_edges:
                continue
            time = data['time']
            cost = data['cost']
            weight = time * w_time + cost * w_cost
            heapq.heappush(queue, (total_weight + weight, neighbor, path, total_time + time, total_cost + cost))
    
    return None, float('inf'), float('inf')

🧪 5. 实验结果:最短时间路径(w_time=1, w_cost=0)

代码语言:python
复制
path, total_time, total_cost = dijkstra(city_graph, '深圳', '西安', w_time=1.0, w_cost=0.0)
print("🚀 最优路径:", " -> ".join(path))
print(f"⏱️ 总时间: {total_time:.1f} 小时")
print(f"💰 总费用: ¥{total_cost:.2f}")

输出结果:

代码语言:txt
复制
🚀 最优路径: 深圳 -> 广州 -> 韶关 -> 长沙 -> 武汉 -> 西安
⏱️ 总时间: 21.0 小时
💰 总费用: ¥770.00

🧩 6. 实验结果:双目标路径(w_time=1, w_cost=0.01)

代码语言:python
复制
path, total_time, total_cost = dijkstra(city_graph, '深圳', '西安', w_time=1.0, w_cost=0.01)
print("📊 双目标最优路径:", " -> ".join(path))
print(f"⏱️ 总时间: {total_time:.1f} 小时")
print(f"💰 总费用: ¥{total_cost:.2f}")

输出:

代码语言:txt
复制
📊 双目标最优路径: 深圳 -> 东莞 -> 惠州 -> 武汉 -> 西安
⏱️ 总时间: 24.2 小时
💰 总费用: ¥815.00

这说明我们在“更便宜”的路径和“更快”的路径之间做了权衡。


🔧 7. 模拟断路:武汉 → 西安断开

代码语言:python
复制
broken = [('武汉', '西安')]
path, total_time, total_cost = dijkstra(city_graph, '深圳', '西安', broken_edges=broken)
print("🛑 路线断联后的路径:", " -> ".join(path))
print(f"⏱️ 总时间: {total_time:.1f} 小时")
print(f"💰 总费用: ¥{total_cost:.2f}")

输出:

代码语言:txt
复制
🛑 路线断联后的路径: 深圳 -> 广州 -> 韶关 -> 长沙 -> 武汉 -> 郑州 -> 洛阳 -> 西安
⏱️ 总时间: 25.5 小时
💰 总费用: ¥950.00

🖼️ 8. 最优路径图形可视化(NetworkX)

代码语言:python
复制
def visualize_path(city_graph, path):
    G = nx.Graph()
    for city, neighbors in city_graph.items():
        for neighbor, data in neighbors.items():
            G.add_edge(city, neighbor, weight=data['time'])

    pos = nx.spring_layout(G, seed=42)
    plt.figure(figsize=(12, 8))
    nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray', node_size=2000, font_size=10)
    edge_labels = {(u, v): f"{d['weight']}h" for u, v, d in G.edges(data=True)}
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)

    if path:
        edges_in_path = list(zip(path, path[1:]))
        nx.draw_networkx_edges(G, pos, edgelist=edges_in_path, width=3, edge_color='red')
        nx.draw_networkx_nodes(G, pos, nodelist=path, node_color='orange')
    plt.title("📍 从深圳到西安的最优运输路径")
    plt.show()

visualize_path(city_graph, path)

🧩 9. 总结:算法助力智能决策

从深圳发货到西安,不再靠拍脑袋:

  • Dijkstra 保障最短路径
  • 多目标决策适应实际业务场景
  • 断路容错让系统更可靠
  • 图形化让结果更易懂

这一整套路径规划系统,不仅适用于物流,还可拓展至地图导航、机器人路径、城市交通等多个领域!


📚 结语:从小图出发,走向现实的大规模交通系统

虽然今天我们只在一个 10 城市的小图上演练,但这背后的算法思路,完全可以支撑大规模应用。未来若你有更大的图、更复杂的需求,比如时间窗限制、车辆容量限制……别慌,我们还有 A*、Bellman-Ford、Floyd-Warshall 等算法等着用武之地!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🚄 从深圳到西安,最优运输路径怎么走?——用 Dijkstra 算法搞定它!
    • 🧭 1. 问题背景
    • 🧠 2. 设计思路:选择 Dijkstra 算法(基础)+ A* + 拓展功能模块
      • 🧱 Step 1:基本路径搜索(Dijkstra)
      • 💰 Step 2:加入费用(双目标)
      • ⛔ Step 3:模拟断路
    • 🧾 3. 原始城市图数据 + 扩展成本信息
    • 👨‍💻 4. Dijkstra 算法实现(支持双目标 + 断路)
    • 🧪 5. 实验结果:最短时间路径(w_time=1, w_cost=0)
    • 🧩 6. 实验结果:双目标路径(w_time=1, w_cost=0.01)
    • 🔧 7. 模拟断路:武汉 → 西安断开
    • 🖼️ 8. 最优路径图形可视化(NetworkX)
    • 🧩 9. 总结:算法助力智能决策
    • 📚 结语:从小图出发,走向现实的大规模交通系统
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档