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 返回汉字的汉语拼音
Feb 27 Python
Python中在脚本中引用其他文件函数的实现方法
Jun 23 Python
Python打印输出数组中全部元素
Mar 13 Python
python读取文本绘制动态速度曲线
Jun 21 Python
Python使用pyodbc访问数据库操作方法详解
Jul 05 Python
Python程序包的构建和发布过程示例详解
Jun 09 Python
Win10 安装PyCharm2019.1.1(图文教程)
Sep 29 Python
在Django中实现添加user到group并查看
Nov 18 Python
PyCharm 2019.3发布增加了新功能一览
Dec 08 Python
使用TensorFlow-Slim进行图像分类的实现
Dec 31 Python
使用OpenCV获取图像某点的颜色值,并设置某点的颜色
Jun 02 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
Nov 27 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
星际争霸中的热键
2020/03/04 星际争霸
php实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
php批量删除超链接的实现方法
2015/10/19 PHP
Yii2框架实现数据库常用操作总结
2017/02/08 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
2018/04/20 PHP
总结PHP代码规范、流程规范、git规范
2018/06/18 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
IE中直接运行显示当前网页中的图片 推荐
2006/08/31 Javascript
js 页面执行时间计算代码
2009/03/04 Javascript
DOM和XMLHttpRequest对象的属性和方法整理
2012/01/04 Javascript
jquery实现的图片点击滚动效果
2014/04/29 Javascript
使用不同的方法结合/合并两个JS数组
2014/09/18 Javascript
详解Node.js读写中文内容文件操作
2018/10/10 Javascript
layer弹出层自适应高度,垂直水平居中的实现
2019/09/16 Javascript
javascript实现切割轮播效果
2019/11/28 Javascript
JS函数进阶之继承用法实例分析
2020/01/15 Javascript
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
python字符串对其居中显示的方法
2015/07/11 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
Python字符串的全排列算法实例详解
2019/01/07 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
python 如何对logging日志封装
2020/12/02 Python
python uuid生成唯一id或str的最简单案例
2021/01/13 Python
利用纯CSS3实现动态的自行车特效源码
2017/01/20 HTML / CSS
IE10 Error.stack 让脚本调试更加方便快捷
2013/04/22 HTML / CSS
canvas实现圆形进度条动画的示例代码
2017/12/26 HTML / CSS
Sarenza德国:法国最大的时尚鞋和包包网上商店
2019/06/08 全球购物
大学学年自我鉴定
2013/10/28 职场文书
个人查摆问题整改措施
2014/10/04 职场文书
工伤事故证明
2014/10/20 职场文书
党的群众路线教育实践活动领导班子整改方案
2014/10/25 职场文书
2015国庆节66周年演讲稿
2015/03/20 职场文书
2015年领导干部廉洁自律工作总结
2015/05/26 职场文书
2015年高三年级组工作总结
2015/07/21 职场文书
MySQL 存储过程的优缺点分析
2021/05/20 MySQL
nginx 配置缓存
2022/05/11 Servers