python编写的最短路径算法


Posted in Python onMarch 25, 2015

一心想学习算法,很少去真正静下心来去研究,前几天趁着周末去了解了最短路径的资料,用python写了一个最短路径算法。算法是基于带权无向图去寻找两个点之间的最短路径,数据存储用邻接矩阵记录。首先画出一幅无向图如下,标出各个节点之间的权值。

python编写的最短路径算法

其中对应索引:

A ——> 0

B——> 1

C——> 2

D——>3

E——> 4

F——> 5

G——> 6

邻接矩阵表示无向图:

python编写的最短路径算法

算法思想是通过Dijkstra算法结合自身想法实现的。大致思路是:从起始点开始,搜索周围的路径,记录每个点到起始点的权值存到已标记权值节点字典A,将起始点存入已遍历列表B,然后再遍历已标记权值节点字典A,搜索节点周围的路径,如果周围节点存在于表B,比较累加权值,新权值小于已有权值则更新权值和来源节点,否则什么都不做;如果不存在与表B,则添加节点和权值和来源节点到表A,直到搜索到终点则结束。

这时最短路径存在于表A中,得到终点的权值和来源路径,向上递推到起始点,即可得到最短路径,下面是代码:

# -*-coding:utf-8 -*-
class DijkstraExtendPath():
  def __init__(self, node_map):
    self.node_map = node_map
    self.node_length = len(node_map)
    self.used_node_list = []
    self.collected_node_dict = {}
  def __call__(self, from_node, to_node):
    self.from_node = from_node
    self.to_node = to_node
    self._init_dijkstra()
    return self._format_path()
  def _init_dijkstra(self):
    self.used_node_list.append(self.from_node)
    self.collected_node_dict[self.from_node] = [0, -1]
    for index1, node1 in enumerate(self.node_map[self.from_node]):
      if node1:
        self.collected_node_dict[index1] = [node1, self.from_node]
    self._foreach_dijkstra()
  def _foreach_dijkstra(self):
    if len(self.used_node_list) == self.node_length - 1:
      return
    for key, val in self.collected_node_dict.items(): # 遍历已有权值节点
      if key not in self.used_node_list and key != to_node:
        self.used_node_list.append(key)
      else:
        continue
      for index1, node1 in enumerate(self.node_map[key]): # 对节点进行遍历
        # 如果节点在权值节点中并且权值大于新权值
        if node1 and index1 in self.collected_node_dict and self.collected_node_dict[index1][0] > node1 + val[0]:
          self.collected_node_dict[index1][0] = node1 + val[0] # 更新权值
          self.collected_node_dict[index1][1] = key
        elif node1 and index1 not in self.collected_node_dict:
          self.collected_node_dict[index1] = [node1 + val[0], key]
    self._foreach_dijkstra()
  def _format_path(self):
    node_list = []
    temp_node = self.to_node
    node_list.append((temp_node, self.collected_node_dict[temp_node][0]))
    while self.collected_node_dict[temp_node][1] != -1:
      temp_node = self.collected_node_dict[temp_node][1]
      node_list.append((temp_node, self.collected_node_dict[temp_node][0]))
    node_list.reverse()
    return node_list
def set_node_map(node_map, node, node_list):
  for x, y, val in node_list:
    node_map[node.index(x)][node.index(y)] = node_map[node.index(y)][node.index(x)] = val
if __name__ == "__main__":
  node = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
  node_list = [('A', 'F', 9), ('A', 'B', 10), ('A', 'G', 15), ('B', 'F', 2),
         ('G', 'F', 3), ('G', 'E', 12), ('G', 'C', 10), ('C', 'E', 1),
         ('E', 'D', 7)]
  node_map = [[0 for val in xrange(len(node))] for val in xrange(len(node))]
  set_node_map(node_map, node, node_list)
  # A -->; D
  from_node = node.index('A')
  to_node = node.index('D')
  dijkstrapath = DijkstraPath(node_map)
  path = dijkstrapath(from_node, to_node)
  print path

运行结果:

python编写的最短路径算法

再来一例:

<!-- lang: python -->
# -*- coding: utf-8 -*-
import itertools
import re
import math

def combination(lst):  #全排序
  lists=[]
  liter=itertools.permutations(lst)
  for lts in list(liter):
    lt=''.join(lts)
    lists.append(lt)
  return lists

def coord(lst):   #坐标输入
  coordinates=dict()
  print u'请输入坐标:(格式为A:7 17)'
  p=re.compile(r"\d+")
  for char in lst:
    str=raw_input(char+':')
    dot=p.findall(str)
    coordinates[char]=[dot[0],dot[1]]
  print coordinates
  return coordinates

def repeat(lst):  #删除重复组合
  for ilist in lst:
    for k in xrange(len(ilist)):
      st=(ilist[k:],ilist[:k])
      strs=''.join(st)
      for jlist in lst:
        if(cmp(strs,jlist)==0):
          lst.remove(jlist)
    for k in xrange(len(ilist)):
      st=(ilist[k:],ilist[:k])
      strs=''.join(st)
      for jlist in lst:
        if(cmp(strs[::-1],jlist)==0):
          lst.remove(jlist)
    lst.append(ilist)
    print lst
  return lst

def count(lst,coordinates): #计算各路径
  way=dict()
  for str in lst:
    str=str+str[:1]
    length=0
    for i in range(len(str)-1):
      x=abs( float(coordinates[str[i]][0]) - float(coordinates[str[i+1]][0]) )
      y=abs( float(coordinates[ str[i] ][1]) - float(coordinates[ str[i+1] ][1]) )
      length+=math.sqrt(x**2+y**2)
    way[str[:len(str)-1]]=length
  return way

if __name__ =="__main__":
  print u'请输入图节点:'
  rlist=list(raw_input())
  coordinates=coord(rlist)

  list_directive = combination(rlist)
#  print "有方向完全图所有路径为:",list_directive
#  for it in list_directive:
#    print it
  print u'有方向完全图所有路径总数:',len(list_directive),"\n"

#无方向完全图
  list_directive=repeat(list_directive)
  list_directive=repeat(list_directive)
#  print "无方向完全图所有路径为:",list_directive
  print u'无方向完全图所有路径为:'
  for it in list_directive:
    print it
  print u'无方向完全图所有路径总数:',len(list_directive)

  ways=count(list_directive,coordinates)
  print u'路径排序如下:'
  for dstr in sorted(ways.iteritems(), key=lambda d:d[1], reverse = False ):
    print dstr
  raw_input()

以上就是本文给大家分享的全部内容了,希望大家能够喜欢,能够学习python有所帮助。

请您花一点时间将文章分享给您的朋友或者留下评论。我们将会由衷感谢您的支持!

Python 相关文章推荐
Python中的yield浅析
Jun 16 Python
讲解Python中的递归函数
Apr 27 Python
Python实现识别手写数字 简易图片存储管理系统
Jan 29 Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 Python
JSON文件及Python对JSON文件的读写操作
Oct 07 Python
Python读取txt某几列绘图的方法
Oct 14 Python
基于Python实现定时自动给微信好友发送天气预报
Oct 25 Python
Python简单I/O操作示例
Mar 18 Python
利用Django模版生成树状结构实例代码
May 19 Python
python网络编程 使用UDP、TCP协议收发信息详解
Aug 29 Python
django实现web接口 python3模拟Post请求方式
Nov 19 Python
使paramiko库执行命令时在给定的时间强制退出功能的实现
Mar 03 Python
python实现挑选出来100以内的质数
Mar 24 #Python
Python 的 Socket 编程
Mar 24 #Python
python获取标准北京时间的方法
Mar 24 #Python
python实现定时同步本机与北京时间的方法
Mar 24 #Python
Python随机生成一个6位的验证码代码分享
Mar 24 #Python
python判断字符串是否包含子字符串的方法
Mar 24 #Python
python使用datetime模块计算各种时间间隔的方法
Mar 24 #Python
You might like
PHP中的string类型使用说明
2010/07/27 PHP
ThinkPHP使用心得分享-分页类Page的用法
2014/05/15 PHP
php序列化函数serialize() 和 unserialize() 与原生函数对比
2015/05/08 PHP
CI(CodeIgniter)框架中URL特殊字符处理与SQL注入隐患分析
2019/02/28 PHP
PHP Trait代码复用类与多继承实现方法详解
2019/06/17 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
CSS JavaScript 实现菜单功能 改进版
2008/12/09 Javascript
jQuery 打造动态下滑菜单实现说明
2010/04/15 Javascript
getComputedStyle与currentStyle获取样式(style/class)
2013/03/19 Javascript
javascript根据像素点取位置示例
2014/01/27 Javascript
解决json日期格式问题的3种方法
2014/02/02 Javascript
jQuery中使用data()方法读取HTML5自定义属性data-*实例
2014/04/11 Javascript
JS经典正则表达式笔试题汇总
2016/12/15 Javascript
JavaScript获取ul中li个数的方法
2017/02/13 Javascript
JavaScript使用链式方法封装jQuery中CSS()方法示例
2017/04/07 jQuery
ionic 自定义弹框效果
2017/06/27 Javascript
详解从NodeJS搭建中间层再谈前后端分离
2018/11/13 NodeJs
微信小程序实现页面下拉刷新和上拉加载功能详解
2018/12/03 Javascript
原生js实现ajax请求和JSONP跨域请求操作示例
2020/03/14 Javascript
[02:44]2014DOTA2 国际邀请赛中国区预选赛 大神红毯秀
2014/05/25 DOTA
Python3 处理JSON的实例详解
2017/10/29 Python
Tensorflow使用tfrecord输入数据格式
2018/06/19 Python
详解关于Django中ORM数据库迁移的配置
2018/10/08 Python
django解决跨域请求的问题
2018/11/11 Python
python自动循环定时开关机(非重启)测试
2019/08/26 Python
Python面向对象之Web静态服务器
2019/09/03 Python
python3.4中清屏的处理方法
2020/07/06 Python
python实现scrapy爬虫每天定时抓取数据的示例代码
2021/01/27 Python
阿根廷票务网站:StubHub阿根廷
2018/04/13 全球购物
Ajax的优点和缺点
2014/11/21 面试题
美化环境标语
2014/06/20 职场文书
大专应届毕业生求职信
2014/07/15 职场文书
思想作风建设心得体会
2014/10/22 职场文书
2014年收银工作总结
2014/11/13 职场文书
老干部座谈会主持词
2015/07/03 职场文书
南阳市白酒市场的调查报告
2019/11/08 职场文书