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中使用摄像头实现简单的延时摄影技术
Mar 27 Python
用map函数来完成Python并行任务的简单示例
Apr 02 Python
Ruby元编程基础学习笔记整理
Jul 02 Python
python读取oracle函数返回值
Jul 18 Python
numpy自动生成数组详解
Dec 15 Python
Python生成短uuid的方法实例详解
May 29 Python
Flask实现图片的上传、下载及展示示例代码
Aug 03 Python
python分块读取大数据,避免内存不足的方法
Dec 10 Python
python验证身份证信息实例代码
May 06 Python
Python中的With语句的使用及原理
Jul 29 Python
Python利用zhdate模块实现农历日期处理
Mar 31 Python
python套接字socket通信
Apr 01 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
在DC的漫画和电影中,蝙蝠侠的宿敌,小丑的真名是什么?
2020/04/09 欧美动漫
PHP下编码转换函数mb_convert_encoding与iconv的使用说明
2009/12/16 PHP
array_multisort实现PHP多维数组排序示例讲解
2011/01/04 PHP
使用php方法curl抓取AJAX异步内容思路分析及代码分享
2014/08/25 PHP
PHP加密解密类实例代码
2016/07/20 PHP
Yii框架中jquery表单验证插件用法示例
2016/10/18 PHP
使用PHP访问RabbitMQ消息队列的方法示例
2018/06/06 PHP
PHP+redis实现的悲观锁机制示例
2018/06/12 PHP
PHP中上传文件打印错误错误类型分析
2019/04/14 PHP
Laravel 修改默认日志文件名称和位置的例子
2019/10/17 PHP
不懂JavaScript应该怎样学
2008/04/16 Javascript
jQuery元素选择器用法实例
2014/12/23 Javascript
js中取得变量绝对值的方法
2015/01/03 Javascript
Node.js Addons翻译(C/C++扩展)
2016/06/12 Javascript
jQuery 生成svg矢量二维码
2016/08/09 Javascript
微信小程序 教程之wxapp视图容器 swiper
2016/10/19 Javascript
web前端页面生成exe可执行文件的方法
2018/02/08 Javascript
vue利用v-for嵌套输出多层对象,分别输出到个表的方法
2018/09/07 Javascript
用python分割TXT文件成4K的TXT文件
2009/05/23 Python
Python中的列表知识点汇总
2015/04/14 Python
详解Python中的__new__、__init__、__call__三个特殊方法
2016/06/02 Python
Python3.遍历某文件夹提取特定文件名的实例
2018/04/26 Python
初探利用Python进行图文识别(OCR)
2019/02/26 Python
纯CSS3+DIV实现小三角形边框效果的示例代码
2020/08/03 HTML / CSS
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
Fabletics官网:美国运动服饰品牌,由好莱坞女演员凯特·哈德森创立
2019/10/19 全球购物
如何开发一个JQuery插件
2016/07/28 面试题
自考毕业自我鉴定
2014/03/18 职场文书
领导班子四风表现材料
2014/08/23 职场文书
2014年政协工作总结
2014/12/09 职场文书
销售员岗位职责范本
2015/04/11 职场文书
nginx里的rewrite跳转的实现
2021/03/31 Servers
Oracle以逗号分隔的字符串拆分为多行数据实例详解
2021/07/16 Oracle
ROS系统将python包编译为可执行文件的简单步骤
2021/07/25 Python
Nginx跨域问题解析与解决
2022/08/05 Servers
Java获取字符串编码格式实现思路
2022/09/23 Java/Android