zoukankan      html  css  js  c++  java
  • python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边

     1 # Bellman-Ford核心算法
     2 # 对于一个包含n个顶点,m条边的图, 计算源点到任意点的最短距离
     3 # 循环n-1轮,每轮对m条边进行一次松弛操作
     4 
     5 # 定理:
     6 # 在一个含有n个顶点的图中,任意两点之间的最短路径最多包含n-1条边
     7 # 最短路径肯定是一个不包含回路的简单路径(回路包括正权回路与负权回路)
     8 # 1. 如果最短路径中包含正权回路,则去掉这个回路,一定可以得到更短的路径
     9 # 2. 如果最短路径中包含负权回路,则每多走一次这个回路,路径更短,则不存在最短路径
    10 # 因此最短路径肯定是一个不包含回路的简单路径,即最多包含n-1条边,所以进行n-1次松弛即可
    11 
    12 
    13 G = {1:{1:0, 2:-3, 5:5},
    14      2:{2:0, 3:2},
    15      3:{3:0, 4:3},
    16      4:{4:0, 5:2},
    17      5:{5:0}}
    18 
    19 
    20 
    21 def getEdges(G):
    22     """ 输入图G,返回其边与端点的列表 """
    23     v1 = []     # 出发点         
    24     v2 = []     # 对应的相邻到达点
    25     w  = []     # 顶点v1到顶点v2的边的权值
    26     for i in G:
    27         for j in G[i]:
    28             if G[i][j] != 0:
    29                 w.append(G[i][j])
    30                 v1.append(i)
    31                 v2.append(j)
    32     return v1,v2,w
    33 
    34 class CycleError(Exception):
    35     pass
    36 
    37 def Bellman_Ford(G, v0, INF=999):
    38     v1,v2,w = getEdges(G)
    39     
    40     # 初始化源点与所有点之间的最短距离
    41     dis = dict((k,INF) for k in G.keys())
    42     dis[v0] = 0
    43 
    44     # 核心算法
    45     for k in range(len(G)-1):   # 循环 n-1轮
    46         check = 0           # 用于标记本轮松弛中dis是否发生更新
    47         for i in range(len(w)):     # 对每条边进行一次松弛操作
    48             if dis[v1[i]] + w[i] < dis[v2[i]]:
    49                 dis[v2[i]] = dis[v1[i]] + w[i]
    50                 check = 1
    51         if check == 0: break
    52     
    53     # 检测负权回路
    54     # 如果在 n-1 次松弛之后,最短路径依然发生变化,则该图必然存在负权回路
    55     flag = 0
    56     for i in range(len(w)):             # 对每条边再尝试进行一次松弛操作
    57         if dis[v1[i]] + w[i] < dis[v2[i]]: 
    58             flag = 1
    59             break
    60     if flag == 1:
    61 #         raise CycleError()
    62         return False
    63     return dis
    64 
    65 v0 = 1
    66 dis = Bellman_Ford(G, v0)
    67 print dis.values()
  • 相关阅读:
    文件上传跨域解决方案-jQuery-File-Upload
    求数列的的增幅,已知起始列和结束列,中间阶梯数
    mud那些坑 find_object问题
    jquery mCustomScrollbar使用
    JS的Date对象
    JS获取当前日期
    Go数组求和
    Go九九乘法表
    Go语言基础之time包
    Go语言基础之流程控制
  • 原文地址:https://www.cnblogs.com/hanahimi/p/4692658.html
Copyright © 2011-2022 走看看