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 BeautifulSoup使用方法详解
Nov 21 Python
零基础写python爬虫之爬虫框架Scrapy安装配置
Nov 06 Python
Python正则表达式非贪婪、多行匹配功能示例
Aug 08 Python
Django框架的使用教程路由请求响应的方法
Jul 03 Python
Python中的函数式编程:不可变的数据结构
Oct 08 Python
漂亮的Django Markdown富文本app插件的实现
Jan 02 Python
在Python中过滤Windows文件名中的非法字符方法
Jun 10 Python
Pycharm新手教程(只需要看这篇就够了)
Jun 18 Python
python 杀死自身进程的实现方法
Jul 01 Python
详解Python用三种方式统计词频的方法
Jul 29 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
Dec 31 Python
使用python把xmind转换成excel测试用例的实现代码
Oct 12 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防CC攻击实现代码
2011/12/29 PHP
列举PHP的Yii 2框架的开发优势
2015/07/03 PHP
Laravel中注册Facades的步骤详解
2016/03/16 PHP
thinkphp3.2实现上传图片的控制器方法
2016/04/28 PHP
PHP命令行执行整合pathinfo模拟定时任务实例
2016/08/12 PHP
var与Javascript变量隐式声明
2009/09/17 Javascript
select、radio表单回显功能实现避免使用jquery载入赋值
2013/06/08 Javascript
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
jQuery中click事件用法实例
2014/12/26 Javascript
快速掌握Node.js中setTimeout和setInterval的使用方法
2016/03/21 Javascript
jQuery实现立体式数字动态增加(animate方法)
2016/12/21 Javascript
vue实现消息的无缝滚动效果的示例代码
2017/12/05 Javascript
详解webpack打包时排除其中一个css、js文件或单独打包一个css、js文件(两种方法)
2018/10/26 Javascript
微信小程序绘制图片发送朋友圈
2019/07/25 Javascript
在Vue项目中用fullcalendar制作日程表的示例代码
2019/08/04 Javascript
[49:56]VG vs Optic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python基于Socket实现的简单聊天程序示例
2017/08/05 Python
Python中循环后使用list.append()数据被覆盖问题的解决
2018/07/01 Python
Python 3 判断2个字典相同
2019/08/06 Python
如何在python中实现线性回归
2020/08/10 Python
Html5实现如何在两个div元素之间拖放图像
2013/03/29 HTML / CSS
纪伊国屋新加坡网上书店:Kinokuniya新加坡
2017/12/29 全球购物
Harrods美国:英国最大的百货公司
2018/11/04 全球购物
Zatchels官网:英国剑桥包品牌
2021/01/12 全球购物
幼儿园小班植树节活动方案
2014/03/04 职场文书
我们的节日清明节活动方案
2014/03/05 职场文书
实习报告评语
2014/04/26 职场文书
灰雀教学反思
2014/04/28 职场文书
学校欢迎标语
2014/06/18 职场文书
竞聘演讲稿开场白
2014/08/25 职场文书
小学教师暑期培训方案
2014/08/28 职场文书
满月酒邀请函
2015/01/30 职场文书
2015年学校财务工作总结
2015/05/19 职场文书
创业计划书之少年玩具店
2019/09/05 职场文书
Python 机器学习工具包SKlearn的安装与使用
2021/05/14 Python
灵能百分百第三季什么时候来?
2022/03/15 日漫