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聚类算法之DBSACN实例分析
Nov 20 Python
Python实现新浪博客备份的方法
Apr 27 Python
python 列表,数组,矩阵两两转换tolist()的实例
Apr 04 Python
Python SQL查询并生成json文件操作示例
Aug 17 Python
Win10下python 2.7.13 安装配置方法图文教程
Sep 18 Python
python学习之hook钩子的原理和使用
Oct 25 Python
python将视频转换为全字符视频
Apr 26 Python
Python 继承,重写,super()调用父类方法操作示例
Sep 29 Python
Python使用进程Process模块管理资源
Mar 05 Python
Python数据模型与Python对象模型的相关总结
Jan 26 Python
Pycharm 设置默认解释器路径和编码格式的操作
Feb 05 Python
Python还能这么玩之用Python做个小游戏的外挂
Jun 04 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
Zend Framework教程之Zend_Config_Xml用法分析
2016/03/23 PHP
详解PHP发送邮件知识点
2018/05/06 PHP
PHP数组访问常用方法解析
2020/09/05 PHP
javascript动态改变img的src属性图片不显示的解决方法
2010/10/20 Javascript
基于JQuery实现CheckBox全选全不选
2011/06/27 Javascript
JavaScript 判断日期格式是否正确的实现代码
2011/07/04 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
2012/08/14 Javascript
JQuery拖拽元素改变大小尺寸实现代码
2012/12/10 Javascript
js/jQuery对象互转(快速操作dom元素)
2013/02/04 Javascript
js处理自己不能定义二维数组的方法详解
2014/03/03 Javascript
node.js中的fs.statSync方法使用说明
2014/12/16 Javascript
理解javascript中try...catch...finally
2015/12/25 Javascript
JavaScript仿支付宝密码输入框
2015/12/29 Javascript
jQuery实现的文字hover颜色渐变效果实例
2016/02/20 Javascript
手机端点击图片放大特效PhotoSwipe.js插件实现
2016/08/24 Javascript
jQuery纵向导航菜单效果实现方法
2016/12/19 Javascript
学习使用jQuery表单验证插件和日历插件
2017/02/13 Javascript
js中获取键盘按下键值event.keyCode、event.charCode和event.which的兼容性详解
2017/03/15 Javascript
JS中正则表达式全局匹配模式 /g用法详解
2017/04/01 Javascript
JavaScript实现选中文字提示新浪微博分享效果
2017/06/15 Javascript
基于vue2实现左滑删除功能
2017/11/28 Javascript
利用angular、react和vue实现相同的面试题组件
2018/02/19 Javascript
详解Vue CLI3配置解析之css.extract
2018/09/14 Javascript
Vue 理解之白话 getter/setter详解
2019/04/16 Javascript
JS Generator 函数的含义与用法实例总结
2020/04/08 Javascript
Vue 同步异步存值取值实现案例
2020/08/05 Javascript
antd vue 刷新保留当前页面路由,保留选中菜单,保留menu选中操作
2020/08/06 Javascript
javascript canvas实现简易时钟例子
2020/09/05 Javascript
Python RuntimeError: thread.__init__() not called解决方法
2015/04/28 Python
python实现的简单窗口倒计时界面实例
2015/05/05 Python
将字典转换为DataFrame并进行频次统计的方法
2018/04/08 Python
Html5移动端获奖无缝滚动动画实现示例
2018/06/25 HTML / CSS
Ancheer官方户外和运动商店:销售电动自行车
2019/08/07 全球购物
兵马俑导游词
2015/02/02 职场文书
李强优秀员工观后感
2015/06/16 职场文书
运动员加油词
2015/07/18 职场文书