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黑帽编程 3.4 跨越VLAN详解
Sep 28 Python
python difflib模块示例讲解
Sep 13 Python
Python基于csv模块实现读取与写入csv数据的方法
Jan 18 Python
python 读入多行数据的实例
Apr 19 Python
Python 中的Selenium异常处理实例代码
May 03 Python
解决Pycharm运行时找不到文件的问题
Oct 29 Python
Python安装与基本数据类型教程详解
May 29 Python
PyTorch中Tensor的数据统计示例
Feb 17 Python
Python叠加矩形框图层2种方法及效果
Jun 18 Python
Python不支持 i ++ 语法的原因解析
Jul 22 Python
python 多进程和协程配合使用写入数据
Oct 30 Python
如何利用python 读取配置文件
Jan 06 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 操作符与控制结构
2012/03/07 PHP
php长字符串定义方法
2012/07/12 PHP
Laravel 5 学习笔记
2015/03/06 PHP
php中动态调用函数的方法
2015/03/16 PHP
PHP中静态变量的使用方法实例分析
2016/12/01 PHP
JQueryEasyUI datagrid框架的基本使用
2013/04/08 Javascript
顶部缓冲下拉菜单导航特效的JS代码
2013/08/27 Javascript
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
Jquery操作js数组及对象示例代码
2014/05/11 Javascript
jQuery实现类似淘宝网图片放大效果的方法
2015/07/08 Javascript
基于jQuery实现简单的折叠菜单效果
2015/11/23 Javascript
浅析JavaScript中浏览器的兼容问题
2016/04/19 Javascript
JavaScript lodash常见用法系列小结
2016/08/24 Javascript
原生js实现放大镜效果
2017/01/11 Javascript
javascript中mouseenter与mouseover的异同
2017/06/06 Javascript
webpack构建vue项目的详细教程(配置篇)
2017/07/17 Javascript
详解Vue demo实现商品列表的展示
2019/05/07 Javascript
JavaScript console的使用方法实例分析
2020/04/28 Javascript
浅谈Python中的数据类型
2015/05/05 Python
Python3 pip3 list 出现 DEPRECATION 警告的解决方法
2019/02/16 Python
Python简易版图书管理系统
2019/08/12 Python
Tensorflow 多线程与多进程数据加载实例
2020/02/05 Python
pycharm设置当前工作目录的操作(working directory)
2020/02/14 Python
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
印尼旅游网站:via
2017/11/12 全球购物
德国领先的大尺码和超大尺码男装在线零售商:Bigtex
2019/06/22 全球购物
物业管理计划书
2014/01/10 职场文书
西安交大自主招生自荐信
2014/01/27 职场文书
五好关工委申报材料
2014/05/31 职场文书
员工工作及收入证明
2014/10/28 职场文书
财务出纳岗位职责
2015/03/31 职场文书
2015年学校食堂工作总结
2015/04/22 职场文书
2016优秀毕业生个人事迹材料
2016/02/29 职场文书
详解JSON.parse和JSON.stringify用法
2022/02/18 Javascript
青岛市的收音机研制与生产
2022/04/07 无线电
Nginx如何获取自定义请求header头和URL参数详解
2022/07/23 Servers