算法导论 第二十四章 单源最短路径

本文探讨了单源最短路径问题,特别是在存在负权重但无负权环的情况下的解决方案。介绍了BELLMAN_FORD算法和Dijkstra算法,详细阐述了算法实现及其时间复杂度。同时,解释了差分约束系统与最短路径的关系,以及如何通过松弛操作满足约束条件。最后,简要提及了最短路径性质的证明。
摘要由CSDN通过智能技术生成

def:单源最短路径既从节点s出发到其他的所有能到达的节点的的最短路径。



对于存在权重为负数的边,只要这边不形成环,或者整个环路的权重大于零则可以认为最短路径依然有解。

我们使用前驱子图来表现最短路径



我们使用如下代码来表示图与最短路径:

class Vertex:  
    def __init__(self, u):  
        self.value = u
        self.vertexs = []
        self.isInGraph = False
        self.pi = None
        self.d = float("inf")
  
class Edge:  
    def __init__(self, u, v, w):  
        self.fromV = u  
        self.toV = v
        self.weight = w

class Graph:
    def __init__(self):  
        self.vertexs = []
        self.edges = []

def weight(edges, u, v):
    for e in edges:
        if e.fromV == u and e.toV == v:
            return e.weight
    
    return None

def INITGRAPH(G, edges):
    for e in edges:
        if not e.fromV.isInGraph:
            G.vertexs.append(e.fromV)
            e.fromV.isInGraph = True
        if not e.toV.isInGraph:
            G.vertexs.append(e.toV)
            e.toV.isInGraph = True
        
        G.edges.append(e)
        e.fromV.vertexs.append(e.toV)
        #e.toV.vertexs.append(e.fromV)
初始化与松弛操作(初始化最短路径与前驱子图,改进最短路径估计与前驱子图):

def INITIALIZE_SINGLE_SOURCE(G, s):
    for v in G.vertexs:
        v.d = float("inf")
    s.d = 0

def RELAX(u, v, edges):
    if v.d > u.d + weight(edges, u, v):
        v.d = u.d + weight(edges, u, v)
        v.pi = u
        print(u.value, v.value, v.d)
并具有如下性质:

24.1 BELLMAN_FORD算法

def BELLMAN_FORD(G, s):
    INITIALIZE_SINGLE_SOURCE(G, s)
    for i in range(1, len(G.vertexs)-1):
        for edge in G.edges:
            RELAX(edge.fromV, edge.toV, G.edges)
    for edge in G.edges:
        if edge.toV.d > edge.fromV.d + weight(edges, edge.fromV, edge.toV):
            return False
    return True

if __name__ == "__main__":
    s = Vertex('s')
    t = Vertex('t')
    x = Vertex('x')
    y = Vertex('y')
    z = Vertex('z')

    edges = []
    edges.append(Edge(x, t, -2))
    edges.append(E
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值