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制作钉钉加密/解密工具
Dec 07 Python
sublime text 3配置使用python操作方法
Jun 11 Python
Django使用httpresponse返回用户头像实例代码
Jan 26 Python
深入理解Django的中间件middleware
Mar 14 Python
django 使用 request 获取浏览器发送的参数示例代码
Jun 11 Python
python3.x提取中文的正则表达式示例代码
Jul 23 Python
python实现微信打飞机游戏
Mar 24 Python
Python爬取YY评级分数并保存数据实现过程解析
Jun 01 Python
python自动化办公操作PPT的实现
Feb 05 Python
python 利用openpyxl读取Excel表格中指定的行或列教程
Feb 06 Python
python实现简单文件读写函数
Feb 25 Python
Python使用MapReduce进行简单的销售统计
Apr 22 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
PHPMailer 中文使用说明小结
2010/01/22 PHP
php中显示数组与对象的实现代码
2011/04/18 PHP
php实现的css文件背景图片下载器代码
2014/11/11 PHP
ThinkPHP 整合Bootstrap Ajax分页样式
2016/12/23 PHP
javascript 子窗体父窗体相互传值方法
2010/05/31 Javascript
javascript 图片裁剪技巧解读
2012/11/15 Javascript
下拉菜单点击实现连接跳转功能的js代码
2013/05/19 Javascript
js中同步与异步处理的方法和区别总结
2013/12/25 Javascript
Javascript前端UI框架Kit使用指南之Kitjs简介
2014/11/28 Javascript
让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
2014/12/12 Javascript
深入理解JavaScript程序中内存泄漏
2016/03/17 Javascript
全面解析标签页的切换方式
2016/08/21 Javascript
JavaScript实现格式化字符串函数String.format
2016/12/16 Javascript
vue中将网页打印成pdf实例代码
2017/06/15 Javascript
AngularJS 实现点击按钮获取验证码功能实例代码
2017/07/13 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
30分钟快速实现小程序语音识别功能
2018/11/27 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
Python中使用urllib2模块编写爬虫的简单上手示例
2016/01/20 Python
Django 如何获取前端发送的头文件详解(推荐)
2017/08/15 Python
python抓取网页中链接的静态图片
2018/01/29 Python
python学习入门细节知识点
2018/03/29 Python
Python 创建空的list,以及append用法讲解
2018/05/04 Python
Python中应该使用%还是format来格式化字符串
2018/09/25 Python
python 在屏幕上逐字显示一行字的实例
2018/12/24 Python
python实现输入任意一个大写字母生成金字塔的示例
2019/10/27 Python
基于Python的OCR实现示例
2020/04/03 Python
英国排名第一的在线宠物用品商店:Monster Pet Supplies
2018/05/20 全球购物
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
厨房领班竞聘演讲稿
2014/04/23 职场文书
小学少先队辅导员述职报告
2015/01/10 职场文书
2016年党员干部公开承诺书
2016/03/24 职场文书
go开发alertmanger实现钉钉报警
2021/07/16 Golang
【DOTA2】高能暴走TK秀!PSG LGD vs ASTER - DPC 2022 WINTER TOUR CN
2022/04/02 DOTA
怎么禁用Win11输入法 最新Win11输入法关闭教程
2022/08/05 数码科技