Python实现Dijkstra算法

yipeiwu_com7年前Python基础

Dijkstra算法

迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

迪杰斯特拉算法是求从某一个起点到其余所有结点的最短路径,是一对多的映射关系,是一种贪婪算法

示例:

算法

算法实现流程思路:
迪杰斯特拉算法每次只找离起点最近的一个结点,并将之并入已经访问过结点的集合(以防重复访问,陷入死循环),然后将刚找到的最短路径的结点作为中间结点来更新相邻结点的路径长度,这样循环找到图中一个个结点的最短路径。

"""
输入
graph 输入的图
src 原点
返回
dis 记录源点到其他点的最短距离
path 路径
"""
import json
def dijkstra(graph,src):
  if graph ==None:
    return None
  # 定点集合
  nodes = [i for i in range(len(graph))] # 获取顶点列表,用邻接矩阵存储图
  # 顶点是否被访问
  visited = []
  visited.append(src)
  # 初始化dis
  dis = {src:0}# 源点到自身的距离为0
  for i in nodes:
    dis[i] = graph[src][i]
  path={src:{src:[]}} # 记录源节点到每个节点的路径
  k=pre=src
  while nodes:
    temp_k = k
    mid_distance=float('inf') # 设置中间距离无穷大
    for v in visited:
      for d in nodes:
        if graph[src][v] != float('inf') and graph[v][d] != float('inf'):# 有边
          new_distance = graph[src][v]+graph[v][d]
          if new_distance <= mid_distance:
            mid_distance=new_distance
            graph[src][d]=new_distance # 进行距离更新
            k=d
            pre=v
    if k!=src and temp_k==k:
      break
    dis[k]=mid_distance # 最短路径
    path[src][k]=[i for i in path[src][pre]]
    path[src][k].append(k)

    visited.append(k)
    nodes.remove(k)
    print(nodes)
  return dis,path
if __name__ == '__main__':
  # 输入的有向图,有边存储的就是边的权值,无边就是float('inf'),顶点到自身就是0
  graph = [ 
    [0, float('inf'), 10, float('inf'), 30, 100],
    [float('inf'), 0, 5, float('inf'), float('inf'), float('inf')],
    [float('inf'), float('inf'), 0, 50, float('inf'), float('inf')],
    [float('inf'), float('inf'), float('inf'), 0, float('inf'), 10],
    [float('inf'), float('inf'), float('inf'), 20, 0, 60],
    [float('inf'), float('inf'), float('inf'), float('inf'), float('inf'), 0]]
  dis,path= dijkstra(graph, 0) # 查找从源点0开始带其他节点的最短路径
  print(dis)
  print(json.dumps(path, indent=4))


总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对【听图阁-专注于Python设计】的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

Php多进程实现代码

php多进程实现 PHP有一组进程控制函数(编译时需要–enable-pcntl与posix扩展),使得php能在nginx系统中实现跟c一样的创建子进程、使用exec函数执行程序、处理...

Python序列之list和tuple常用方法以及注意事项

sequence 序列 sequence(序列)是一组有顺序的对象的集合。序列可以包含一个或多个元素,也可以没有任何元素。 我们之前所说的基本数据类型,都可以作为序列的对象。对象还可以是...

Python 调用 Outlook 发送邮件过程解析

Python 调用 Outlook 发送邮件过程解析

微软 Office 提供基于 COM 接口的编程。Python 通过 pywin32 可以方便地调用各组件。如果下载和安装 pywin32 有困难,可以到 Sourceforge 的镜像...

Java实现的执行python脚本工具类示例【使用jython.jar】

本文实例讲述了Java实现的执行python脚本工具类。分享给大家供大家参考,具体如下: 这里java中执行python脚本工具类,需要使用jython.jar java中执行pytho...

pycharm创建scrapy项目教程及遇到的坑解析

pycharm创建scrapy项目教程及遇到的坑解析

前言 最近学习scrapy爬虫框架,在使用pycharm安装scrapy类库及创建scrapy项目时花费了好长的时间,遇到各种坑,根据网上的各种教程,花费了一晚上的时间,终于成功,其中也...