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之集合(set)
Sep 24 Python
Python Sql数据库增删改查操作简单封装
Apr 18 Python
python实现折半查找和归并排序算法
Apr 14 Python
Python基于socket模块实现UDP通信功能示例
Apr 10 Python
Python 对输入的数字进行排序的方法
Jun 23 Python
python实现KNN分类算法
Oct 16 Python
Python编写一个验证码图片数据标注GUI程序附源码
Dec 09 Python
python中count函数简单用法
Jan 05 Python
pycharm设置当前工作目录的操作(working directory)
Feb 14 Python
django美化后台django-suit的安装配置操作
Jul 12 Python
浅谈Python 钉钉报警必备知识系统讲解
Aug 17 Python
Python通过m3u8文件下载合并ts视频的操作
Apr 16 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作的文本留言本的例子(二)
2006/10/09 PHP
其他功能
2006/10/09 PHP
mysql limit查询优化分析
2008/11/12 PHP
php进程daemon化的正确实现方法
2018/09/06 PHP
JavaScript与C# Windows应用程序交互方法
2007/06/29 Javascript
通过判断JavaScript的版本实现执行不同的代码
2010/05/11 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
js获取指定时间的前几秒
2017/04/05 Javascript
JS+HTML5实现上传图片预览效果完整实例【测试可用】
2017/04/20 Javascript
详解vue.js下引入百度地图jsApi的两种方法
2018/07/27 Javascript
jstree中的checkbox默认选中和隐藏示例代码
2019/12/29 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
[01:04:22]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 IG vs EG
2018/04/01 DOTA
Python3实现生成随机密码的方法
2014/08/23 Python
Python的Flask框架中SQLAlchemy使用时的乱码问题解决
2015/11/07 Python
Python开发中爬虫使用代理proxy抓取网页的方法示例
2017/09/26 Python
深入理解python中函数传递参数是值传递还是引用传递
2017/11/07 Python
用Python实现最速下降法求极值的方法
2019/07/10 Python
详解pandas绘制矩阵散点图(scatter_matrix)的方法
2020/04/23 Python
使用 prometheus python 库编写自定义指标的方法(完整代码)
2020/06/29 Python
python3中布局背景颜色代码分析
2020/12/01 Python
CSS3 rgb and rgba(透明色)的使用详解
2020/09/25 HTML / CSS
基于 HTML5 的 WebGL 3D 版俄罗斯方块的示例代码
2018/05/28 HTML / CSS
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
戴森台湾线上商城:Dyson Taiwan
2018/05/21 全球购物
彪马土耳其官网:PUMA土耳其
2019/07/14 全球购物
中专毕业生自荐信
2013/11/16 职场文书
课程设计心得体会
2013/12/28 职场文书
财务简历的自我评价
2014/03/05 职场文书
《荷花》教学反思
2014/04/16 职场文书
竞选宣传委员演讲稿
2014/05/24 职场文书
学生实习证明范文
2014/09/28 职场文书
仓管员岗位职责范本
2015/04/01 职场文书
导游词之西安骊山
2019/12/20 职场文书
剖析后OpLog订阅MongoDB的数据变更就没那么难了
2022/02/24 MongoDB