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读取浮点数和读取文本文件示例
May 06 Python
python中使用urllib2获取http请求状态码的代码例子
Jul 07 Python
Python实现的多线程端口扫描工具分享
Jan 21 Python
Python字符串格式化输出方法分析
Apr 13 Python
Python 正则表达式入门(初级篇)
Dec 07 Python
Python实现脚本锁功能(同时只能执行一个脚本)
May 10 Python
python使用itchat库实现微信机器人(好友聊天、群聊天)
Jan 04 Python
python3中获取文件当前绝对路径的两种方法
Apr 26 Python
在ubuntu16.04中将python3设置为默认的命令写法
Oct 31 Python
Python开发网站目录扫描器的实现
Feb 21 Python
Python测试线程应用程序过程解析
Dec 31 Python
pycharm部署django项目到云服务器的详细流程
Jun 29 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入门学习知识点四 PHP正则表达式基本应用
2011/07/14 PHP
PHP开发中常用的十个代码样例
2016/02/02 PHP
浅谈php中urlencode与rawurlencode的区别
2016/09/05 PHP
自制轻量级仿jQuery.boxy对话框插件代码
2010/10/26 Javascript
文本框获得焦点和失去焦点的判断代码
2012/03/18 Javascript
JS常见问题整理(持续更新)
2013/08/06 Javascript
js与jquery获取父级元素,子级元素,兄弟元素的实现方法
2014/01/09 Javascript
详解jquery中$.ajax方法提交表单
2014/11/03 Javascript
jQuery实现按钮只点击一次后就取消点击事件绑定的方法
2015/06/26 Javascript
深入理解(function(){... })();
2016/08/16 Javascript
JavaScript数据结构链表知识详解
2016/11/21 Javascript
Vue.js中用webpack合并打包多个组件并实现按需加载
2017/02/17 Javascript
JavaScript实现简单的星星评分效果
2017/05/18 Javascript
CentOS 安装NodeJS V8.0.0的方法
2017/06/15 NodeJs
Vue打包后出现一些map文件的解决方法
2018/02/13 Javascript
vue移动端弹框组件的实例
2018/09/25 Javascript
vue input实现点击按钮文字增删功能示例
2019/01/29 Javascript
通过cordova将vue项目打包为webapp的方法
2019/02/02 Javascript
Vue项目总结之webpack常规打包优化方案
2019/06/06 Javascript
java和js实现的洗牌小程序
2019/09/30 Javascript
JavaScript进阶(二)词法作用域与作用域链实例分析
2020/05/09 Javascript
JavaScript 实现拖拽效果组件功能(兼容移动端)
2020/11/11 Javascript
elementUI同一页面展示多个Dialog的实现
2020/11/19 Javascript
python中私有函数调用方法解密
2016/04/29 Python
使用python读取csv文件快速插入数据库的实例
2018/06/21 Python
python利用小波分析进行特征提取的实例
2019/01/09 Python
查看python安装路径及pip安装的包列表及路径
2019/04/03 Python
Python OS模块实例详解
2019/04/15 Python
numpy.meshgrid()理解(小结)
2019/08/01 Python
Python爬虫JSON及JSONPath运行原理详解
2020/06/04 Python
利用python为PostgreSQL的表自动添加分区
2021/01/18 Python
小学国庆节活动方案策划书
2014/09/16 职场文书
申报材料格式
2014/12/30 职场文书
亮剑观后感
2015/06/05 职场文书
深入理解python协程
2021/06/15 Python
Redis 报错 error:NOAUTH Authentication required
2022/05/15 Redis