python实现最短路径的实例方法


Posted in Python onJuly 19, 2020

最短路径问题(python实现)

解决最短路径问题:(如下三种算法)

(1)迪杰斯特拉算法(Dijkstra算法)
(2)弗洛伊德算法(Floyd算法)
(3)SPFA算法

第一种算法:

Dijkstra算法

广度优先搜索解决赋权有向图或者无向图的单源最短路径问题.是一种贪心的策略

算法的思路

声明一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T,初始时,原点s的路径权重被赋为0(dis[s]=0)。若对于顶点s存在能直接到达的边(s,m),则把dis[m]设为w(s, m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大。初始时,集合T只有顶点s。

然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,OK,此时完成一个顶点,再看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值,然后,又从dis中找出最小值,重复上述动作,直到T中包含了图的所有顶点。

第二种算法:

Floyd算法

原理:

Floyd算法(弗洛伊德算法)是一种在有向图中求最短路径的算法。它是一种求解有向图中点与点之间最短路径的算法。
用在拥有负权值的有向图中求解最短路径(不过不能包含负权回路)

流程:

有向图中的每一个节点X,对于图中过的2点A和B,

如果有Dis(AX)+ Dis(XB)< Dis(AB),那么使得Dis(AB)=Dis(AX)+Dis(XB)。

当所有的节点X遍历完后,AB的最短路径就求出来了。

示例一:

#-*- coding:utf-8 -*-
 #python实现Floyd算法
 
N = 4 
_=float('inf')   #无穷大 
 graph = [[ 0, 2, 6, 4],[ _, 0, 3, _],[ 7, _, 0, 1],[ 5, _,12, 0]] 
 path = [[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1]]    #记录路径,最后一次经过的点
def back_path(path,i,j):      #递归回溯
while(-1 != path[i][j]):
   back_path(path,i,path[i][j])
    back_path(path,path[i][j],j)
   print path[i][j],14    
 return;
  return;
print "Graph:\n",graph
for k in range(N):
 for i in range(N):
   for j in range(N):
      if graph[i][j] > graph[i][k] + graph[k][j]:
       graph[i][j] = graph[i][k] + graph[k][j]
      path[i][j] = k
 print "Shortest distance:\n",graph
 print "Path:\n",path
 print "Points pass-by:"
 for i in range(N):
 for j in range(N):
   print "%d -> %d:" % (i,j),
    back_path(path,i,j)
    print "\n",

示例二:

#!usr/bin/env python#encoding:utf-8
'''
功能:使用floyd算法求最短路径距离
'''
import random
import time
def random_matrix_genetor(vex_num=10):  
  '''
  随机图顶点矩阵生成器
  输入:顶点个数,即矩阵维数  
  '''
  data_matrix=[]  
  for i in range(vex_num):
    one_list=[]    
    for j in range(vex_num):
      one_list.append(random.randint(1, 100))
    data_matrix.append(one_list)  
    return data_matrixdef floyd(data_matrix):  
    '''
  输入:原数据矩阵,即:一个二维数组
  输出:顶点间距离  '''
  dist_matrix=[]
  path_matrix=[]
  vex_num=len(data_matrix) 
  for h in range(vex_num):
    one_list=['N']*vex_num
    path_matrix.append(one_list)
    dist_matrix.append(one_list)  
  for i in range(vex_num):    
    for j in range(vex_num):
      dist_matrix=data_matrix
      path_matrix[i][j]=j  
  for k in range(vex_num):    
    for i in range(vex_num):      
      for j in range(vex_num):        
        if dist_matrix[i][k]=='N' or dist_matrix[k][j]=='N':
          temp='N'
        else:
          temp=dist_matrix[i][k]+dist_matrix[k][j]        
        if dist_matrix[i][j]>temp:
          dist_matrix[i][j]=temp
          path_matrix[i][j]=path_matrix[i][k]  
  return dist_matrix, path_matrixdef main_test_func(vex_num=10):  
   '''
   主测试函数
   '''
  data_matrix=random_matrix_genetor(vex_num)
  dist_matrix, path_matrix=floyd(data_matrix)  
  for i in range(vex_num):    
  for j in range(vex_num):      
  print '顶点'+str(i)+'----->'+'顶点'+str(j)+'最小距离为:', dist_matrix[i][j]
if __name__ == '__main__':
  data_matrix=[['N',1,'N',4],[1,'N',2,'N'],['N',2,'N',3],[4,'N',3,'N']]
  dist_matrix, path_matrix=floyd(data_matrix)  
  print dist_matrix  
  print path_matrix
 
  time_list=[] 
  print '------------------------------节点数为10测试情况------------------------------------'
  start_time0=time.time()
  main_test_func(10)
  end_time0=time.time()
  t1=end_time0-start_time0
  time_list.append(t1)  
  print '节点数为10时耗时为:', t1 
  print '------------------------------节点数为100测试情况------------------------------------'
  start_time1=time.time()
  main_test_func(100)
  end_time1=time.time()
  t2=end_time1-start_time1
  time_list.append(t2)  
  print '节点数为100时耗时为:', t2 
  print '------------------------------节点数为1000测试情况------------------------------------'
  start_time1=time.time()
  main_test_func(1000)
  end_time1=time.time()
  t3=end_time1-start_time1
  time_list.append(t3)  
  print '节点数为100时耗时为:', t3 
  print '--------------------------------------时间消耗情况为:--------------------------------'
  for one_time in time_list:    
  print one_time

示例三:

import numpy as np
Max   = 100
v_len  = 4
edge  = np.mat([[0,1,Max,4],[Max,0,9,2],[3,5,0,8],[Max,Max,6,0]])
A    = edge[:]
path  = np.zeros((v_len,v_len)) 
 
def Folyd():  
  for i in range(v_len):    
    for j in range(v_len):      
      if(edge[i,j] != Max and edge[i,j] != 0):
        path[i][j] = i 
  print 'init:'
  print A,'\n',path  
  for a in range(v_len):    
    for b in range(v_len):      
      for c in range(v_len):        
        if(A[b,a]+A[a,c]<A[b,c]):
          A[b,c] = A[b,a]+A[a,c]
          path[b][c] = path[a][c]  
  print 'result:'      
  print A,'\n',path        
 
if __name__ == "__main__":
  Folyd()

第三种算法:

SPFA算法是求解单源最短路径问题的一种算法,由理查德·贝尔曼(Richard Bellman) 和 莱斯特·福特 创立的。有时候这种算法也被称为 Moore-Bellman-Ford 算法,因为 Edward F. Moore 也为这个算法的发展做出了贡献。它的原理是对图进行V-1次松弛操作,得到所有可能的最短路径。

其优于迪科斯彻算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达 O(VE)。但算法可以进行若干种优化,提高了效率。

思路:

我们用数组dis记录每个结点的最短路径估计值,用邻接表或邻接矩阵来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

Python 相关文章推荐
python使用三角迭代计算圆周率PI的方法
Mar 20 Python
python爬虫实现教程转换成 PDF 电子书
Feb 19 Python
python 第三方库的安装及pip的使用详解
May 11 Python
python实现多进程代码示例
Oct 31 Python
python绘制热力图heatmap
Mar 23 Python
对python requests发送json格式数据的实例详解
Dec 19 Python
PyQt5实现五子棋游戏(人机对弈)
Mar 24 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
Mar 07 Python
python字典与json转换的方法总结
Dec 28 Python
python 下划线的多种应用场景总结
May 12 Python
Python 中的Sympy详细使用
Aug 07 Python
python中Pyqt5使用Qlabel标签播放视频
Apr 22 Python
python等待10秒执行下一命令的方法
Jul 19 #Python
python怎么删除缓存文件
Jul 19 #Python
python实现从ftp上下载文件的实例方法
Jul 19 #Python
python中关于数据类型的学习笔记
Jul 19 #Python
Python趣味实例,实现一个简单的抽奖刮刮卡
Jul 18 #Python
用python给csv里的数据排序的具体代码
Jul 17 #Python
python如何删除列为空的行
Jul 17 #Python
You might like
php的urlencode()URL编码函数浅析
2011/08/09 PHP
php数组函数序列之array_pop() - 删除数组中的最后一个元素
2011/11/07 PHP
php中OR与|| AND与&amp;&amp;的区别总结
2013/10/26 PHP
thinkphp模板输出技巧汇总
2014/11/24 PHP
PHP开发api接口安全验证操作实例详解
2020/03/26 PHP
laravel与thinkphp之间的区别与优缺点
2021/03/02 PHP
javascript中&quot;/&quot;运算符常见错误
2010/10/13 Javascript
Javascript根据指定下标或对象删除数组元素
2012/12/21 Javascript
jQuery 遍历- 关于closest() 的方法介绍以及与parents()的方法区别分析
2013/04/26 Javascript
JS读取XML文件示例代码
2013/11/15 Javascript
Javascript和Java获取各种form表单信息的简单实例
2014/02/14 Javascript
jQuery拖动div、移动div、弹出层实现原理及示例
2014/04/08 Javascript
谈谈我对JavaScript DOM事件的理解
2015/12/18 Javascript
JS对象是否拥有某属性如何判断
2017/02/03 Javascript
BootStrap自定义popover,点击区域隐藏功能的实现
2018/01/23 Javascript
微信小程序实现的一键连接wifi功能示例
2019/04/24 Javascript
BootStrap表单验证中的非Submit类型按钮点击时触发验证的坑
2019/09/05 Javascript
基于Nuxt.js项目的服务端性能优化与错误检测(容错处理)
2019/10/23 Javascript
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
2020/08/31 Javascript
Python跳出循环语句continue与break的区别
2014/08/25 Python
Python 出现错误TypeError: ‘NoneType’ object is not iterable解决办法
2017/01/12 Python
Java及python正则表达式详解
2017/12/27 Python
python3操作微信itchat实现发送图片
2018/02/24 Python
详解Python如何生成词云的方法
2018/06/01 Python
pytorch随机采样操作SubsetRandomSampler()
2020/07/07 Python
pytorch 把图片数据转化成tensor的操作
2021/03/04 Python
日本航空官方网站:JAL
2019/06/19 全球购物
如何转换一个字符串到enum值
2014/04/12 面试题
人力资源行政经理自我评价
2013/10/23 职场文书
责任书范本
2014/08/25 职场文书
2014教师“四风问题”对照检查材料思想汇报
2014/09/16 职场文书
杭白菊导游词
2015/02/10 职场文书
演讲稿之开卷有益
2019/08/07 职场文书
员工保密协议范本,您一定得收藏!很有用!
2019/08/08 职场文书
MySQL 隔离数据列和前缀索引的使用总结
2021/05/14 MySQL
Arthas排查Kubernetes中应用频繁挂掉重启异常
2022/02/28 MySQL