Python实现dijkstra算法

Posted A-L-Kun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python实现dijkstra算法相关的知识,希望对你有一定的参考价值。

文章目录

dijkstra算法

一、 简介

1、 概念

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。注意该算法要求图中不存在负权边。

问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。(单源最短路径)

二、 实现原理

1、 动图演示

2、 思路解析

S集合U集合
选A为起点,S=A
此时的最短路径
A->A=0
以A为中心点,从A开始查找
U=B, C, D, E, F
A->B=10
A->D=4
A->E, F, C= ∞ \\infty
d(AD)最短
选入D,此时S=A, D
此时最短路径
A->A=0
A->D=4
以D为中间点,从A->D这条最短路径进行查找
U=B, C, E, F
A->D->B=6 < 10
A->D->E=10
A->D->C=19
A->D->F= ∞ \\infty
d(ADB)最短
选入B,此时S=A, D, B
此时最短路径
A->A=0
A->D=4
A->D->B=6
以B为中间点,从A->D->B这条路径进行查找
U=C, E, F
A->D->B->C=14<19
A->D->B->E=12>10
A->D->B->F= ∞ \\infty
d(ADE)最短
选入E,此时S=A, D, B, E
此时最短路径
A->A=0
A->D=4
A->D->B=6
A->D->E=10
以E为中间点,从A->D->E这条路径进行查找
U=C, F
A->D->E->C=11<14
A->D->E->F=22
d(ADEC)最短
选入C,此时S=A, D, B, E, C
此时最短路径
A->A=0
A->D=4
A->D->B=6
A->D->E=10
A->D->E->C=11
以C为中间点,从A->D->E->C这条路径进行查找
U=F
A->D->E->C->F=16
发现最短路径为A->D->E->C->F
选入F,此时S=A, D, B, E, C, F
此时最短路径
A->A=0
A->D=4
A->D->B=6
A->D->E=10
A->D->E->C=11
A->D->E->C->F=16
以F为中间点,从A->D->E->C->F这条路径进行查找
集合为空,查找完毕

最后,我们得出

路径距离
A->A0
A->D4
A->D->B6
A->D->E10
A->D->E->C11
A->D->E->C->F16

三、 代码实现

1、 构建矩阵

我们使得与节点有直接接触的节点的距离为确定值,没有直接接触的节点为无穷大,然后构建一个二维矩阵

ABCDEF
A010 ∞ \\infty 4 ∞ \\infty ∞ \\infty
B100826 ∞ \\infty
C ∞ \\infty 801515
D421506 ∞ \\infty
E ∞ \\infty 616012
F ∞ \\infty ∞ \\infty 5 ∞ \\infty 120

2、 算法实现

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "demo02.py"
__email__ = "liu.zhong.kun@foxmail.com"
MAX = float('inf')

def dijkstra(matrix, start_node):
    matrix_length = len(matrix)  # 矩阵一维数组的长度,即节点的个数

    used_node = [False] * matrix_length  # 访问过的节点数组

    distance = [MAX] * matrix_length  # 最短路径距离数组

    distance[start_node] = 0  # 初始化,将起始节点的最短路径修改成0

    # 将访问节点中未访问的个数作为循环值,其实也可以用个点长度代替。
    while used_node.count(False):
        min_value = MAX
        min_value_index = -1

        # 在最短路径节点中找到最小值,已经访问过的不在参与循环。
        # 得到最小值下标,每循环一次肯定有一个最小值
        for index in range(matrix_length):
            if not used_node[index] and distance[index] < min_value:
                min_value = distance[index]
                min_value_index = index

        # 将访问节点数组对应的值修改成True,标志其已经访问过了
        used_node[min_value_index] = True

        # 更新distance数组。
        # 以B点为例:distance[x] 起始点达到B点的距离。
        # distance[min_value_index] + matrix[min_value_index][index] 是起始点经过某点达到B点的距离,比较两个值,取较小的那个。
        for index in range(matrix_length):
            distance[index] = min(distance[index], distance[min_value_index] + matrix[min_value_index][index])

    return distance

matrix_ = [
    [0,10,MAX,4,MAX,MAX],
    [10,0,8,2,6,MAX],
    [MAX,8,10,15,1,5],
    [4,2,15,0,6,MAX],
    [MAX,6,1,6,0,12],
    [MAX,MAX,5,MAX,12,0]
]
ret = dijkstra(matrix_, 0)
print(ret)

以上是关于Python实现dijkstra算法的主要内容,如果未能解决你的问题,请参考以下文章

python 实现dijkstra算法求解最短路径

[Python]贪心算法-Dijkstra-实现

Dijkstra算法(原理及python,c++实现)

Python-Dijkstra的算法实现

Python+爬虫+Dijkstra 算法实现北京地铁换乘方案

python 改进的Dijkstra算法的Python实现(https://gist.github.com/econchick/4666413)