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基于sftp及rsa密匙实现远程拷贝文件的方法
Sep 21 Python
浅谈Python爬取网页的编码处理
Nov 04 Python
Python 多线程不加锁分块读取文件的方法
Dec 11 Python
Scrapy框架爬取西刺代理网免费高匿代理的实现代码
Feb 22 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
Jul 04 Python
python实现DEM数据的阴影生成的方法
Jul 23 Python
django重新生成数据库中的某张表方法
Aug 28 Python
python学生管理系统的实现
Apr 05 Python
Python使用20行代码实现微信聊天机器人
Jun 05 Python
DataFrame 数据合并实现(merge,join,concat)
Jun 14 Python
conda安装tensorflow和conda常用命令小结
Feb 20 Python
用python 绘制茎叶图和复合饼图
Feb 26 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基础知识:类与对象(1)
2006/12/13 PHP
curl实现站外采集的方法和技巧
2014/01/31 PHP
详解php语言最牛掰的Laravel框架
2017/11/20 PHP
node.js应用后台守护进程管理器Forever安装和使用实例
2014/06/01 Javascript
ECMAScript 5中的属性描述符详解
2015/03/02 Javascript
深入探究使JavaScript动画流畅的一些方法
2015/06/30 Javascript
nodejs爬虫抓取数据之编码问题
2015/07/03 NodeJs
使用HTML+CSS+JS制作简单的网页菜单界面
2015/07/27 Javascript
前端学习笔记style,currentStyle,getComputedStyle的用法与区别
2016/05/28 Javascript
jquery判断类型是不是number类型的实例代码
2016/10/07 Javascript
js实现对table的增加行和删除行的操作方法
2016/10/13 Javascript
Bootstrap和Java分页实例第二篇
2016/12/23 Javascript
微信小程序表单验证错误提示效果
2017/05/19 Javascript
react-router中的属性详解
2017/06/01 Javascript
Bootstrap table使用方法汇总
2017/11/17 Javascript
axios 封装上传文件的请求方法
2018/09/26 Javascript
JS数组属性去重并校验重复数据
2020/01/10 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
python 文件操作api(文件操作函数)
2016/08/28 Python
shell命令行,一键创建 python 模板文件脚本方法
2018/03/20 Python
使用python实现快速搭建简易的FTP服务器
2018/09/12 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
2019/01/19 Python
Python实现定时执行任务的三种方式简单示例
2019/03/30 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
pytorch+lstm实现的pos示例
2020/01/14 Python
Python while循环使用else语句代码实例
2020/02/07 Python
Pytorch环境搭建与基本语法
2020/06/03 Python
python中count函数知识点浅析
2020/12/17 Python
美国乡村商店:Plow & Hearth
2016/09/12 全球购物
电影T恤、80年代T恤和80年代服装:TV Store Online
2020/01/05 全球购物
文秘专业大学生求职信
2013/11/10 职场文书
酒店公关部经理岗位职责
2013/11/24 职场文书
市场营销工作计划书
2014/09/15 职场文书
selenium.webdriver中add_argument方法常用参数表
2021/04/08 Python
laravel添加角色和模糊搜索功能的实现代码
2021/06/22 PHP
SQL解决未能删除约束问题drop constraint
2022/05/30 SQL Server