zoukankan      html  css  js  c++  java
  • 最短路径问题-Dijkstra算法的python实现

    迪杰斯特拉(Dijkstra)算法主要是针对没有负值的有向图,求解其中的单一起点到其他顶点的最短路径算法。

    1 算法原理

      迪杰斯特拉(Dijkstra)算法是一个按照路径长度递增的次序产生的最短路径算法。下图为带权值的有向图,作为程序中的实验数据。

      2016_10_19400635-3825-4ce7-84ee-a7f46f7f56d2

      其中,带权值的有向图采用邻接矩阵graph来进行存储,在计算中就是采用n*n的二维数组来进行存储,v0-v5表示数组的索引编号0-5,二维数组的值表示节点之间的权值,若两个节点不能通行,比如,v0->v1不能通行,那么graph[0,1]=+∞ (采用计算机中最大正整数来进行表示)。那如何求解从v0每个v节点的最短路径长度呢?

      

      首先,引进一个辅助数组cost,它的每个值cost[i]表示当前所找到的从起始点v0到终点vi的最短路径的权值(长度花费),该数组的初态为:若从v0到vi有弧,则cost[i]为弧上的权值,否则置cost[i]为+∞ 。

      显然,长度为:cost[j]=Min_i(graph[0,i] | v_i in V) 的路径就是从v0出发的长度最短的一条最短路径。此路径为(v_0,v_j) ,那么下次长度次短的路径必定是弧(v_0,v_i)上的权值cost[i](v_i in V),或者是cost[k](v_k in S)和弧(v_k,v_i)的权值之和。其中V:待求解最短路径的节点j集合;S:已求解最短路径的节点集合。

    2 算法流程

      根据上面的算法原理分析,下面描述算法的实现流程。

    1. 初始化:初始化辅助数组cost,从v0出发到图上其余节点v的初始权值为:cost[i]=graph[0,i]  |  v_i in V ;初始化待求节点S集合,它的初始状态为始点,V集合,全部节点-始节点。

    2. 选择节点v_j ,使得cost[j]=Min ( cost[i] | v_i in V -S ) ,v_j  就是当前求的一条从v0出发的最短路径的终点,修改S集合,使得 S=S + V_j ,修改集合V = V - V_j。

    3. 修改从v0出发到节点V-S上任一顶点 v_k 可达的最短路径,若cost[j]+graph[j,k]<cost[k] ,则修改cost[k]为:cost[k]=cost[j]+graph[j,k] 。

    4. 重复操作2,3步骤,直到求解集合V中的所有节点为止。

      其中最短路径的存储采用一个path整数数组,path[i]的值记录vi的前一个节点的索引,通过path一直追溯到起点,就可以找到从vi到起始节点的最短路径。比如起始节点索引为0,若path[3]=4, path[4]=0;那么节点v2的最短路径为,v0->v4->v3。

    3 算法实现

      采用python语言对第2节中的算法流程进行实现,关键代码如下。

    3.1 最短路径代码

     1 #!/bin/python
     2 # -*- coding:utf-8 -*-
     3 
     4 def dijkstra(graph, startIndex, path, cost, max):
     5     """
     6     求解各节点最短路径,获取path,和cost数组,
     7     path[i] 表示vi节点的前继节点索引,一直追溯到起点。
     8     cost[i] 表示vi节点的花费
     9     """
    10     lenth = len(graph)
    11     v = [0] * lenth
    12     # 初始化 path,cost,V
    13     for i in range(lenth):
    14         if i == startIndex:
    15             v[startIndex] = 1
    16         else:
    17             cost[i] = graph[startIndex][i]
    18             path[i] = (startIndex if (cost[i] < max) else -1)
    19     # print v, cost, path
    20     for i in range(1, lenth):
    21         minCost = max
    22         curNode = -1
    23         for w in range(lenth):
    24             if v[w] == 0 and cost[w] < minCost:
    25                 minCost = cost[w]
    26                 curNode = w
    27         # for 获取最小权值的节点
    28         if curNode == -1: break
    29         # 剩下都是不可通行的节点,跳出循环
    30         v[curNode] = 1
    31         for w in range(lenth):
    32             if v[w] == 0 and (graph[curNode][w] + cost[curNode] < cost[w]):
    33                 cost[w] = graph[curNode][w] + cost[curNode] # 更新权值
    34                 path[w] = curNode # 更新路径
    35         # for 更新其他节点的权值(距离)和路径
    36     return path
    37 
    38 if __name__ == '__main__':
    39     max = 2147483647
    40     graph = [
    41         [max, max, 10, max, 30, 100],
    42         [max, max, 5, max, max, max],
    43         [max, max, max, 50, max, max],
    44         [max, max, max, max, max, 10],
    45         [max, max, max, 20, max, 60],
    46         [max, max, max, max, max, max],
    47         ]
    48     path = [0] * 6
    49     cost = [0] * 6
    50     print dijkstra(graph, 0, path, cost, max)

    4 运行结果

    1 [0, -1, 0, 4, 0, 3]
  • 相关阅读:
    angularjs的$on、$emit、$broadcast
    angularjs中的路由介绍详解 ui-route(转)
    ionic入门教程-ionic路由详解(state、route、resolve)(转)
    Cocos Creator 加载使用protobuf第三方库,因为加载顺序报错
    Cocos Creator 计时器错误 cc.Scheduler: Illegal target which doesn't have uuid or instanceId.
    Cocos Creator 构造函数传参警告 Can not instantiate CCClass 'Test' with arguments.
    Cocos Creator 对象池NodePool
    Cocos Creator 坐标系 (convertToWorldSpaceAR、convertToNodeSpaceAR)
    Cocos Creator 常驻节点addPersistRootNode
    Cocos Creator 配合Tiled地图的使用
  • 原文地址:https://www.cnblogs.com/mayunting/p/10426705.html
Copyright © 2011-2022 走看看