python实现狄克斯特拉算法

 更新时间:2021年04月07日 11:39:28   作者:果然还是我比较shuai  
这篇文章主要介绍了python实现狄克斯特拉算法。想了解数据结构和算法朋友可以参考下

数据结构

1、路由信息

dictRoute = {}
dictRoute[nodeId] = {}
dictRoute[nodeId][nebrId] = distance
操作:
①根据nodeId找到该node的路由信息
②根据nebrId找到某一条路由的距离

2、节点信息

dictNode = {}
dictNode[nodeId] = [shortDis, fatherId, bIsCheck]
操作:
①找到nodes中最短距离的节点
②查找节点的shortDis,根据情况更新shortDis、fatherId
③检查过的节点,更新bIsCheck

功能实现

/* 找到最短距离节点的Id,已经检查的不计算在内 */
def FindShortNodeId(dictNode):
return shortNodeId

/* dikstra算法流程 */
1、找到最短距离节点Id,并标记已检查过 (如果节点Id不存在,表示查找完成)
2、得到最短距离节点的距离
3、轮询最短距离节点的邻居节点
4、计算邻居节点的新距离、得到原最短距离,进行比较
5、如果新距离 < 原距离,则更新邻居节点最短距离
概括为两步:步骤1 (1)- 找到当前最短距离节点
步骤2(2~5) - 更新最短距离节点邻居节点信息

代码实现

import os
import sys

'''
信息输入:
1、节点数目、路由数目
2、路由信息 
3、开始节点、结束节点
'''
nodeNum = 0 # 节点数目
routeNum = 0 # 路由数目
listRoute = [] # 临时存储输入的路由信息
listNodeId = []# 临时存储节点id 

nodeIdStart = ''
nodeIdEnd = ''
dictRoute = {} # 解析后的路由信息
dictNode = {} # 节点信息
# 输入节点数目、路由数目
strInput = input()
list0 = strInput.split(' ')
nodeNum = int(list0[0])
routeNum = int(list0[1])

# 输入路由信息
for index in range(routeNum):
 strInput = input()
 listRoute.append(strInput)
 
# 输入开始节点、结束节点
strInput = input()
list0 = strInput.split(' ')
nodeIdStart = list0[0]
nodeIdEnd = list0[1]

# 解析得到节点Id
listNodeId.append(nodeIdStart)
listNodeId.append(nodeIdEnd)
for index in listRoute:
 list0 = index.split(' ')
 nodeIdA = list0[0]
 nodeIdB = list0[1]
 if nodeIdA not in listNodeId:
  listNodeId.append(nodeIdA) 
 if nodeIdB not in listNodeId:
  listNodeId.append(nodeIdB) 

# 初始化路由信息字典、节点信息字典
for nodeId in listNodeId:
 # 节点字典信息
 dictNode[nodeId] = [10000, '', False] # 最短距离、父节点、是否检查过
 # 每个路由字典创建
 dictRoute[nodeId] = {}
dictNode[nodeIdStart][0] = 0

# 初始化路由信息
for index in listRoute:
 list0 = index.split(' ')
 nodeIdA = list0[0]
 nodeIdB = list0[1]
 dictRoute[nodeIdA][nodeIdB] = int(list0[2])
 dictRoute[nodeIdB][nodeIdA] = int(list0[2])
 
# 打印输入信息
def PrintInputInfo():
 print('nodeNum routeNum:')
 print(str(nodeNum) + ' ' + str(routeNum))
 print('nodeStart nodeEnd')
 print(nodeIdStart+' '+nodeIdEnd)
 print('route info:')
 for nodeId in dictRoute.keys():
  for nebrId in dictRoute[nodeId].keys():
   print(nodeId+'->'+nebrId+' = '+str(dictRoute[nodeId][nebrId]))
 print('node info:')
 for nodeId in dictNode.keys():
  print(nodeId+':'+str(dictNode[nodeId][0])+' '+dictNode[nodeId][1]+' '+str(dictNode[nodeId][2]))

#PrintInputInfo()

'''
狄克斯特拉实现
'''
# 找到最短距离节点id
def FindShortNodeId(dictNode):
 shortNodeId = ''
 shortDis = 10000
 for nodeId in dictNode.keys():
  if dictNode[nodeId][0] < shortDis and dictNode[nodeId][2] == False:
   shortNodeId = nodeId
   shortDis = dictNode[nodeId][0]
 return shortNodeId
 
# 狄克斯特拉算法
shortNodeId = FindShortNodeId(dictNode)
while shortNodeId:
 if shortNodeId == nodeIdEnd:
  break;
 dictNode[shortNodeId][2] = True
 shortDis = dictNode[shortNodeId][0]
 for nebrId in dictRoute[shortNodeId].keys():
  newDis = dictRoute[shortNodeId][nebrId] + shortDis
  if newDis < dictNode[nebrId][0]:
   dictNode[nebrId][0] = newDis
   dictNode[nebrId][1] = shortNodeId
 shortNodeId = FindShortNodeId(dictNode)
 
# 打印结果
listRst = []
nodeId = nodeIdEnd
while nodeId:
 listRst.append(nodeId)
 nodeId = dictNode[nodeId][1]
listRst.reverse()

strRst = ''
for nodeId in listRst:
 if nodeId == listRst[-1]:
  strRst += nodeId
 else:
  strRst += nodeId + '->'

if dictNode[nodeIdEnd][1] == '':
 print('cant reach '+nodeIdEnd)
else:
 print(strRst)
 print(dictNode[nodeIdEnd][0])

测试用例及验证

Case1
输入:
6 4
1 2 2
1 3 4
2 5 3
5 6 2
2 6

输出:

Case2
输入:
4 5
S A 6
S B 2
B A 3
A E 1
B E 5
S E

输出:

Case3(找不到终点)
输入:
6 6
S A 2
S B 1
A C 4
A B 1
B D 2
C D 3
S End

输出:

Case4
输入:
6 8
S A 5
S B 1
A C 1
A B 1
B D 5
C D 1
D End 1
C End 3
S End

输出:

以上就是python实现狄克斯特拉算法的详细内容,更多关于python狄克斯特拉的资料请关注脚本之家其它相关文章!

相关文章

  • 解决pycharm19.3.3安装pyqt5找不到designer.exe和pyuic.exe的问题

    解决pycharm19.3.3安装pyqt5找不到designer.exe和pyuic.exe的问题

    这篇文章给大家介绍了pycharm19.3.3安装pyqt5&pyqt5-tools后找不到designer.exe和pyuic.exe以及配置QTDesigner和PyUIC的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-04-04
  • Python多进程的使用详情

    Python多进程的使用详情

    本篇重点介绍Python多进程的使用,主要介绍其的一些方法及进程的创建等,想进一步了解的小伙伴请跟小编一起进入下文吧
    2021-09-09
  • Python数据结构之递归方法详解

    Python数据结构之递归方法详解

    这篇文章主要为大家介绍了递归的基本概念以及如何构建递归程序。通过本章的学习,大家可以理解递归的基本概念,了解递归背后蕴含的编程思想以及掌握构建递归程序的方法,需要的可以参考一下
    2022-04-04
  • pycharm中导入模块错误时提示Try to run this command from the system terminal

    pycharm中导入模块错误时提示Try to run this command from the system ter

    这篇文章主要介绍了pycharm中导入模块错误时提示Try to run this command from the system terminal问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • tensorflow实现KNN识别MNIST

    tensorflow实现KNN识别MNIST

    这篇文章主要为大家详细介绍了tensorflow实现KNN识别MNIST,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • pandas中DataFrame字典互转的实现

    pandas中DataFrame字典互转的实现

    在数据处理和分析中,Pandas是一个非常强大的Python库,本文主要介绍了pandas中DataFrame字典互转的实现,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04
  • Python在终端通过pip安装好包以后在Pycharm中依然无法使用的问题(三种解决方案)

    Python在终端通过pip安装好包以后在Pycharm中依然无法使用的问题(三种解决方案)

    这篇文章主要介绍了Python在终端通过pip安装好包以后在Pycharm中依然无法使用的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 讲解Python 中的 with 关键字

    讲解Python 中的 with 关键字

    这篇文章主要介绍了讲解Python 中的with关键字,文章基于python的相关资料展开 with 语句的一些基本概念和用法及其底层工作原理,下文更多内容感兴趣的小伙伴可以参考一下
    2022-05-05
  • python递归计算N!的方法

    python递归计算N!的方法

    这篇文章主要介绍了python递归计算N!的方法,涉及Python递归计算阶乘的技巧,非常简单实用,需要的朋友可以参考下
    2015-05-05
  • LyScript实现计算片段Hash并写出Excel的示例代码

    LyScript实现计算片段Hash并写出Excel的示例代码

    本案例将学习运用LyScript计算特定程序中特定某些片段的Hash特征值,并通过xlsxwriter这个第三方模块将计算到的hash值存储成一个excel表格,感兴趣的可以跟随小编一起学习一下
    2022-09-09

最新评论