【数模—图论】最短路径

一、图论基本概念

点表示事物,连接两点的线表示关系。

图的数学表达:G (V(G), E(G) )

其中,V指图的顶点集,E指图的边集。

做图网址:https://csacademy.com/app/graph_editor/

无向图权重邻接矩阵

        1) 对称矩阵

        2)主对角线元素为0

        3)D_{ij}表示i到j节点的权重

节点个数1234
10inf33
2inf0inf5
33inf02
43520

      

二、DIJKATRA迪杰斯特拉

算法思路:

①两个集合:集合a用来存放已经找到最短路径的点

                      集合b用来存放还未找到最短路径的点

                      (P S:一开始,只有源点在集合a中)

                      (P S:在代码中可以用flag=True/False来表示是否在集合a中)

②dis[n]数组:用来存放源点到各个点的距离

    road[n][n]:用来存放m条有向边(eg. road[3][4] 表示点3到点4的距离)

算法实现:

        ①查找从源点出发的有向线段,录入 dis[i]

        ②查找 dis 中最小值(在集合b中的点),并把此点(记为pre)加入到集合a中

        ③查找从 pre 出发的有向线段,比较 dis[i] 和 dis[pre]+road[pre][i] 的大小,更新 dis[i]

        ④直至 集合b 的点都加入到 集合a 中

局限性:不能处理有负权重的图

三、Bellman Ford贝尔曼福特

适用场景:具有负权重的有向图

与Dij的区别:不再区分为是否已经访问,每循环一次更新所有节点信息。

四、代码实现

def dijkstra(graph,start):    #graph表示点线相连权重
    distances = {vertex: float('infinity') for vertex in graph}
    distances[start] = 0      #源点到自身为0,未连接线段为inf无穷

    parent = {vertex: None for vertex in graph}
    priority_queue = [(0,start)]    # 初始化父亲节点,未访问任何节点所以全部设置为 None

    while priority_queue:
        # 弹出堆中距离最小的节点
        current_distance, current_vertex = heapq.heappop(priority_queue)
        # print("距离最小的节点是:",current_distance, current_vertex, "更新后的队列:",priority_queue)

        # 如果当前距离已经大于已知的最短距离,则跳过
        if current_distance > distances[current_vertex]:
            continue

        # 更新相邻节点的距离
        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight
            # print("相邻节点的距离:",neighbor,distance)

            # 如果找到更短的路径,则更新距离,并将节点加入优先队列
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                parent[neighbor] = current_vertex
                heapq.heappush(priority_queue, (distance, neighbor))
                # print("加入后的队列:",priority_queue)
    return distances, parent

函数返回值:从起始点到每个节点的最短距离,和每个节点对应的父亲节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值