• 最优路径算法合集(附python源码)(原创)


    主要的最优(最短)路径算法:

    一、深度优先算法;二、广度优先算法;三、Dijstra最短路径;四、floyd最短路径(待);

    一、深度优先算法

      图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。

      它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

      无向无权值网络

    data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]]

       

     1 def depth_first_search(data, data_index):   # 有向、无向都可以满足要求
     2     d1 = [data_index[0]]
     3     index_now = 0
     4 
     5     for i in range(len(data_index) - 1):  # 只需要再寻找剩余的数值即可
     6         state = 1
     7         for j in range(len(data[index_now])):  # 遍历可行路径
     8             if data[index_now][j] == 1:  # 如果该路径可行,则直接判断
     9                 if data_index[j] not in d1:  # 判断原始输出中是否已有
    10                     d1.append(data_index[j])# 无,则加入
    11                     index_now = j
    12                     state = 0
    13                     break
    14         if state:
    15             for k in d1[-2::-1]:    # 到达叶子后的操作
    16                 index_now = data_index.index(k)
    17                 for j in range(len(data[index_now])):  # 遍历可行路径
    18                     if data[index_now][j] == 1:  # 如果该路径可行,则直接判断
    19                         if data_index[j] not in d1:  # 判断原始输出中是否已有
    20                             d1.append(data_index[j])  # 无,则加入
    21                             index_now = j
    22                             break
    23                 if index_now != data_index.index(k):
    24                     break
    25 
    26         # print(d1)
    27     return d1
    28 
    29 if __name__ == "__main__":
    30     data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0],
    31             [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]]
    32     data_w = [[0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0],
    33               [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0]]
    34     data_index = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
    35     # print(data_index.index('F'))
    36     d1 = depth_first_search(data_w, data_index)
    37     print(d1)
    View Code

     输入(无向图):

    data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]]

    输出:

    ['A', 'C', 'B', 'D', 'F', 'G', 'E']

    二、广度优先算法

      

      广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS。

      它的思想是:从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。

      换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为1,2...的顶点。

       

     1 def breadth_first_search(data, data_index):  # 无向图、有向图都可以的
     2     d1 = [data_index[0]]
     3     index_now = [0]
     4     while len(d1) != len(data_index):
     5         index_mid = []
     6         for i in index_now:  # i 为当前 父节点
     7             for j in range(len(data[i])):  # 查询父节点的子节点
     8                 if data[i][j] == 1:
     9                     if data_index[j] not in d1:
    10                         d1.append(data_index[j])
    11                         index_mid.append(j)
    12         index_now = index_mid
    13         print(d1)
    14     return d1
    15 
    16 
    17 if __name__ == "__main__":
    18     data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0],
    19             [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]]
    20     data_w = [[0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0],
    21               [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0]]
    22     data_index = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
    23     # print(data_index.index('F'))
    24     d1 = breadth_first_search(data_w, data_index)
    25     # print(d1)
    View Code

     输入(有向图):

    data_w = [[0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0]]

    输出:

    ['A', 'B', 'C', 'E', 'F', 'D', 'G']

    三、Dijstra最短路径(迪杰斯特拉算法)

    参考视频:https://www.bilibili.com/video/av25829980?from=search&seid=7854146334299589449

      迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

      OSPF协议 :Open Shortest Path First开放式最短路径优先,底层是迪杰斯特拉算法,是链路状态路由选择协议,它选择路由的度量标准是带宽,延迟。

            

     1 def priority_queue(data, d0):  # 自建优先队列格式
     2     state = 1
     3     for i in range(len(data)):
     4         if d0[1] < data[i][1]:
     5             data.insert(i, d0)
     6             state = 0
     7             break
     8     if state:
     9         data.append(d0)
    10     return data
    11 
    12 
    13 def dijkstra_search(data, data_index, index):
    14     parent = {}  # 字典映射,更新前级节点
    15     queue = []  # 优先队列
    16     queue_out = [[data_index[index], data[index][index], 0]]  # 输出队列
    17 
    18     while len(queue_out) < len(data_index):
    19         root_node = data_index.index(queue_out[-1][0])  # 当前最优节点
    20         # print(root_node)
    21         for i in range(len(data_index)):  # 遍历所有的可能性
    22             if data[root_node][i] != -1:  # 检查是否可直连,是
    23                 if data_index[i] not in [x[0] for x in queue_out]:
    24                     queue = priority_queue(queue,
    25                                            [data_index[i], data[root_node][i] + queue_out[-1][1], queue_out[-1][0]])
    26         # print(queue)    # 检查优先队列的情况 [['C', 1], ['B', 5]]
    27 
    28         for i in range(len(queue)):  # 0,1
    29             # print(queue[i][0])
    30             if queue[i][0] not in [x[0] for x in queue_out]:
    31                 parent[queue[i][0]] = queue[i][-1]
    32                 queue_out.append(queue[i])
    33                 del queue[i]
    34                 break
    35 
    36         # print(queue)
    37         # print('queue_out',queue_out)
    38     return queue_out, parent
    39 
    40 
    41 if __name__ == "__main__":
    42 
    43     data_weight = [[0, 5, 1, -1, -1, -1], [5, 0, 2, 1, -1, -1], [1, 2, 0, 4, 8, -1], [-1, 1, 4, 0, 3, 6],
    44                    [-1, -1, 8, 3, 0, -1], [-1, -1, -1, 6, -1, -1]]
    45     data_index = ['A', 'B', 'C', 'D', 'E', 'F']
    46     # print(data_index.index('F'))
    47     d1, d2 = dijkstra_search(data_weight, data_index, 3)
    48     print(d1)
    49     print(d2)
    50 
    51     target = 'A'
    52     for i in d1:
    53         if i[0] == target:
    54             print('路径最短距离为:', i[1])
    55 
    56     key = target
    57     d3 = [target]
    58     while key in d2.keys():
    59         d3.insert(0, d2[key])
    60         key = d2[key]
    61     print('最优路线为:', d3)
    View Code

    输入:

    data_weight = [[0, 5, 1, -1, -1, -1], [5, 0, 2, 1, -1, -1], [1, 2, 0, 4, 8, -1], [-1, 1, 4, 0, 3, 6], [-1, -1, 8, 3, 0, -1], [-1, -1, -1, 6, -1, -1]]
    data_index = ['A', 'B', 'C', 'D', 'E', 'F']
    d1, d2 = dijkstra_search(data_weight, data_index, 0)

    输出:

    路径最短距离为: 10
    最优路线为: ['A', 'C', 'B', 'D', 'F']

    四、floyd最短路径

    !!!还没看这个算法!!!

  • 相关阅读:
    (转)水经注谷歌地图的级别与对应比例尺及分辨率探究
    oracle 单表导出导入
    案例情景--在一次Oracle 数据库导出时 EXP-00008;ORA-00904:EXP-00000: oracle不同版本导入导出规则
    权衡微服务
    ASP.NET Core HTTP 管道中的那些事儿
    ASP.NET Core 中间件之压缩、缓存
    .NET Core 首例 Office 开源跨平台组件(NPOI Core)
    ASP.NET Core 之 Identity 入门(三)
    Entity Framework Core 1.1 升级通告
    ASP.NET Core 1.1.0 Release Notes
  • 原文地址:https://www.cnblogs.com/Mufasa/p/10554860.html
Copyright © 2020-2023  润新知