首页 > 编程语言 >(4-3)Floyd-Warshall算法:Floyd-Warshall算法的应用案例

(4-3)Floyd-Warshall算法:Floyd-Warshall算法的应用案例

时间:2024-07-10 21:30:43浏览次数:12  
标签:自驾 dist Warshall range 距离 算法 Floyd False INF

4.3  Floyd-Warshall算法的应用案例

Floyd-Warshall算法在许多实际应用中都有着广泛的应用,特别是在需要计算图中所有顶点对之间的最短路径时,它是一种非常有效的解决方案。

4.3.1  自驾线路规划

暑假来临,家庭A决定自驾旅行,计划去四个城市:A、B、C、D,每个城市之间的行车距离如下:

  1. A <-> B: 100km
  2. A <-> D: 200km
  3. B <-> C: 150km
  4. C <-> D: 300km

请使用Floyd-Warshall算法,帮助航家庭A规划最短的航线,以最大程度地减少自驾距离和时间。请计算出每对城市之间的最短自驾距离,并给出优化后的自驾线路信息。

实例4-3:解决航空网络规划问题codes/4/air.py

实例文件air.py的具体实现代码如下所示。

import numpy as np
import matplotlib.pyplot as plt

INF = float('inf')

# 城市之间的自驾距离(邻接矩阵表示)
flightDistances = [
    [0, 100, INF, 200],   # A
    [100, 0, 150, INF],   # B
    [INF, 150, 0, 300],   # C
    [200, INF, 300, 0]    # D
]

# 城市名称
cityNames = ["A", "B", "C", "D"]

def floydWarshall():
    V = len(flightDistances)
    dist = [row[:] for row in flightDistances]

    # Floyd-Warshall算法
    for k in range(V):
        for i in range(V):
            for j in range(V):
                if dist[i][k] != INF and dist[k][j] != INF and dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]

    # 输出最短自驾距离矩阵
    print("Shortest Self-driving distances between every pair of cities:")
    for row in dist:
        for distance in row:
            print("INF" if distance == INF else distance, end=" ")
        print()

    # 输出自驾线路信息
    print("\nOptimized Self-driving routes:")
    for i in range(V):
        for j in range(i + 1, V):
            if dist[i][j] != INF:
                print(f"From {cityNames[i]} to {cityNames[j]}, distance: {dist[i][j]} km")

    # 绘制自驾线路图
    draw_flight_map(dist)

def draw_flight_map(distances):
    cities = len(distances)
    positions = np.random.rand(cities, 2)  # 随机生成城市位置
    plt.figure(figsize=(8, 6))

    # 绘制城市节点
    for i in range(cities):
        plt.plot(positions[i, 0], positions[i, 1], 'o', markersize=10, label=cityNames[i])

    # 绘制自驾线路
    for i in range(cities):
        for j in range(i + 1, cities):
            if distances[i][j] != INF:
                plt.plot([positions[i, 0], positions[j, 0]], [positions[i, 1], positions[j, 1]], 'k-')

    plt.title("Self-driving Routes between Cities")
    plt.xlabel("Longitude")
    plt.ylabel("Latitude")
    plt.legend()
    plt.grid(True)
    plt.show()

def main():
    floydWarshall()

if __name__ == "__main__":
    main()

在这个例子中,我们假设有4个城市(A、B、C、D),并给出了它们之间的线路距离。然后,我们使用Floyd-Warshall算法计算了每对城市之间的最短自驾线路距离,并输出了优化后的线路信息。这有助于规划自驾线路,以最大程度地减少自驾距离和时间。上述代码的实现流程如下所示:

(1)首先,定义了四个城市之间的自驾线路距离和城市名称,并导入了必要的库,包括 numpy 和 matplotlib.pyplot。

(2)接着,定义了floydWarshall 函数,该函数执行 Floyd-Warshall 算法来计算最短自驾线路距离。在算法执行过程中,首先复制了自驾线路距离矩阵,然后使用三重循环来更新最短距离。内部循环遍历所有城市对,如果经过中间城市可以缩短当前两个城市之间的距离,则更新最短距离。算法完成后,输出了最短航线距离矩阵和优化后的自驾线路信息。

(3)然后,定义了draw_flight_map 函数,用于绘制城市之间的自驾线路图。该函数接受一个距离矩阵作为输入,并生成城市的随机位置。然后,它绘制城市节点和自驾线路,并设置图形的标题、标签和图例。最后,通过调用 plt.show() 函数显示图形。

(4)最后,在主 main 函数中调用了 floydWarshall 函数,触发整个流程的执行。

执行后将使用 Floyd-Warshall 算法计算城市之间的最短自驾线路距离打印输出如下所示的计算结果。同时,它还绘制了如图4-1所示的城市间的自驾线路图,以可视化展示自驾路线。

Shortest Self-driving distances between every pair of cities:
0 100 250 200 
100 0 150 300 
250 150 0 300 
200 300 300 0 

Optimized Self-driving routes:
From A to B, distance: 100 km
From A to C, distance: 250 km
From A to D, distance: 200 km
From B to C, distance: 150 km
From B to D, distance: 300 km
From C to D, distance: 300 km

对上面输出结果的具体说明如下所示:

  1. Shortest Self-driving distances between every pair of cities" 部分显示了每对城市之间的最短自驾线路距离矩阵。例如,从城市A到城市B的最短自驾线路距离是100公里,从城市A到城市C的最短自驾线路距离是250公里,以此类推。
  2. "Optimized Self-driving routes" 部分列出了优化后的自驾线路信息。每行显示了从一个城市到另一个城市的最短自驾线路距离,以及航线的具体路径。例如,从城市A到城市B的最短自驾线路距离是100公里,从城市A到城市C的最短自驾线路距离是250公里,以此类推。

图4-1  城市间的航线图

4.3.2  城市交通规划应用

在实际应用中,城市交通规划者可以利用Floyd-Warshall算法来计算城市道路网络中各个路段的最短路径,从而优化交通流量并减少拥堵。请看下面的题目:

在一个由五个交叉路口A、B、C、D和E组成的城市中,每个交叉路口之间通过道路相连。通过给出每个路口之间的道路距离和交通规则,你需要设计一个交通规划系统,帮助司机在城市中选择最短路径到达目的地。道路网络的信息如下所示。

  1. 交叉路口名称:A、B、C、D和E。
  2. 道路距离:给出了每个交叉路口之间的道路距离,以邻接矩阵的形式表示。
  3. 交通规则:存在单行道和禁止左转等限制,通过布尔类型的二维数组表示。

请编写一个程序,计算出从交叉路口A到其他交叉路口的最短路径,并输出最短路径以及对应的距离。同时,确保所计算出的路径不违反任何交通规则。你可以假设司机总是从交叉路口A出发,但目的地可以是任何一个交叉路口。请你在考虑交通规则的情况下,设计一个算法来找到最佳路径,并解释他们的思路和算法设计。

实例4-4:解决城市交通规划的最短路径问题codes/4/city.py

实例文件city.py的具体实现代码如下所示。

import networkx as nx
import matplotlib.pyplot as plt

INF = float('inf')

# 城市道路网络中各路段之间的距离(邻接矩阵表示)
roadDistances = [
    [0, 10, 5, INF, INF],   # Road from A
    [INF, 0, 3, 2, INF],    # Road from B
    [INF, 2, 0, 1, 7],      # Road from C
    [INF, INF, INF, 0, 4],  # Road from D
    [INF, INF, INF, INF, 0] # Road from E
]

# 交叉路口名称
junctions = ["A", "B", "C", "D", "E"]

# 交叉路口之间的单行道和禁止左转等限制
roadRestrictions = [
    [False, False, False, False, False],  # Road from A
    [False, False, True, False, False],   # Road from B
    [False, False, False, False, True],    # Road from C
    [False, False, False, False, False],   # Road from D
    [False, False, False, False, False]    # Road from E
]

def floydWarshall():
    V = len(roadDistances)
    dist = [row[:] for row in roadDistances]  # Make a deep copy of roadDistances

    # 考虑单行道和禁止左转等限制
    for i in range(V):
        for j in range(V):
            if roadRestrictions[i][j]:
                dist[i][j] = INF  # 将有限制的路段距离设为无穷大

    # Floyd-Warshall算法
    for k in range(V):
        for i in range(V):
            for j in range(V):
                if dist[i][k] != INF and dist[k][j] != INF and dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]

    # 创建图
    G = nx.Graph()
    for i in range(V):
        for j in range(V):
            if i != j and dist[i][j] != INF:
                G.add_edge(junctions[i], junctions[j], weight=dist[i][j])

    # 可视化图
    pos = nx.spring_layout(G)
    plt.figure(figsize=(8, 6))
    nx.draw(G, pos, with_labels=True, node_size=1000, node_color="lightblue", font_size=12, font_weight="bold")
    labels = nx.get_edge_attributes(G, 'weight')
    nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)
    plt.title("City Road Network Visualization")
    plt.show()

    # 输出最短路径距离矩阵
    print("Shortest distances between every pair of junctions:")
    for i in range(V):
        for j in range(V):
            if dist[i][j] == INF:
                print("INF", end=" ")
            else:
                print(dist[i][j], end=" ")
        print()

    # 输出路线信息
    print("Optimized traffic routes:")
    for i in range(V):
        for j in range(V):
            if i != j and dist[i][j] != INF:
                print(f"Shortest route from {junctions[i]} to {junctions[j]}: {junctions[i]}", end="")
                k = j
                while k != i:
                    print(f" -> {junctions[k]}", end="")
                    k = dist[i][k] if dist[i][k] < INF else j  # Follow the shortest path
                print(f", distance: {dist[i][j]} km")

if __name__ == "__main__":
    floydWarshall()

上述代码的实现流程如下所示:

(1)首先,定义了城市道路网络中各路段之间的距离(邻接矩阵表示),以及交叉路口之间的交通规则(如单行道和禁止左转)。

(2)然后,使用 Floyd-Warshall 算法计算从交叉路口 A 到其他交叉路口的最短路径。在计算过程中考虑交通规则,并将有限制的路段距离设为无穷大。

(3)接着,将计算得到的最短路径结果转换为 NetworkX 图形对象,并利用 Matplotlib 库进行可视化。在绘制时使用节点表示交叉路口,边表示道路,边的权重表示道路距离。

(4)最后,打印输出如下所示的最短路径距离矩阵和优化的交通路线信息,并绘制如图4-2所示的城市道路网络的可视化图。图中的节点代表交叉路口,边代表道路,边的权重表示道路距离。通过可视化图形,可以直观地展示城市道路网络的结构,以及各个交叉路口之间的连接关系和距离。

Shortest distances between every pair of junctions:
0 7 5 6 10
INF 0 INF 2 6
INF 2 0 1 5
INF INF INF 0 4
INF INF INF INF 0
Optimized traffic routes:
Shortest route from A to B: A -> B

图4-2  城市道路网络的可视化图

标签:自驾,dist,Warshall,range,距离,算法,Floyd,False,INF
From: https://blog.csdn.net/asd343442/article/details/140334674

相关文章

  • 【智能算法改进】一种混合多策略改进的麻雀搜索算法
    目录1.算法原理2.改进点3.结果展示4.参考文献5.代码获取1.算法原理【智能算法】麻雀搜索算法(SSA)原理及实现2.改进点精英反向学习策略将精英反向学习策略应用到初始化阶段,通过反向解的生成与精英个体的选择,不仅使算法搜索范围得到扩大,提高了全局搜索的能力......
  • Open3D点云算法与点云深度学习案例汇总(长期更新)
    目录引言Open3D算法汇总Open3D快速安装测试点云资料一、点云的读写与显示二、KDtree和八叉树的应用三、点云特征提取四、点云滤波算法五、点云配准算法六、点云分割算法(待更新)七、常用操作八、数据转换九、常用小工具三维点云深度学习PointNet++引言  ......
  • C++中各类常用算法的总结以及使用
    1.常用算法文章目录1.常用算法1.常用遍历算法1.for_each2.transform2.常用查找算法1.find2.find_if3.adjacent_find4.binary_search5.count6.count_if3.常用排序算法1.sort2.random_shuffle3.merge4.reverse4.常用拷贝和替换算法1.copy2.replace3.repla......
  • 数据结构第19节 排序算法(1)
    冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。冒泡排序步骤详解假设我们有以下数组:int[]arr={64,34,25,12,22,11,90}......
  • 研0 冲刺算法竞赛 day14 P1957 口算练习题
    思路:分别考虑以运算符或数字开头,为运算符,直接读入后面两个数字;为数字,在读入一个数字即可代码:#include<iostream>#include<cstring>#include<cstdio>usingnamespacestd;intmain(){ intN; cin>>N; charc[10],str[55],f; while(N--) { cin>>c; int......
  • 算法题-字符串序列判断
    题目描述:        输入两个字符串S和L,都只包含英文小写字母。S长度<=100,L长度<=500,000。判定S是否是L的有效字串。        判定规则:S中的每个字符在L中都能找到(可以不连续),且S在L中字符的前后顺序与S中顺序要保持一致。(例如,S="ace"是L="abcde"的一个子序列且......
  • 【NOI】C++算法设计入门之贪心
    文章目录前言一、概念1.导入2.概念2.1贪心算法的核心思想2.2贪心算法的步骤2.3贪心算法的应用场景二、例题讲解问题:1372.活动选择问题:1456.淘淘捡西瓜问题:1551-任务调度问题:1561.买木头三、总结五、感谢前言贪心算法,如同成语"得陇望蜀"所描述的那样,总是......
  • PCA(主成分分析)--降维的基础算法
    一.原理简介PCA主成分分析,是一种使用较为广泛的数据降维算法,主要思想是将n维数据特征映射到k维上,这k维全新的正交数据特征称为主成分;PCA的工作就是从原始的空间中顺序地找一组相互正交的坐标轴,新的坐标轴的选择与数据本身是密切相关的。其中,第一个新坐标轴选择是原始数据......
  • 【打卡】006 P6 VGG-16算法-Pytorch实现人脸识别
    >-**......
  • 代码随想录算法训练营第五天 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数
    代码随想录算法训练营第五天|242.有效的字母异位词349.两个数组的交集202.快乐数1.两数之和最近有点忙,哈希表章节的博客可能没有以前那么多图和那么详细了。不过忙完这段时间我可能会回来补的。有效字母异位词题目链接/文章讲解/视频讲解:https://programmercar......