Dijkstra算法求解图中最短路径距离

前言:这里是自学内容,讲解的是用python来实现Dijkstra算法,算是入门求解图中最短路径问题的典型案例。


算法简介:

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

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

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

Dijkstra算法实现过程:

1)寻找未被遍历的节点中权值最下的节点

2)将寻找到的最小权值节点更新为已被遍历,在运筹学中记录为被固定标号,其余为临时性标号

3)更新权值,算法将起始的节点定位于当前寻找到的最小权值节点处

4)通过比较节点处向其他节点联通时所产生的权值与初始权值做比较,更新权值

def dijkstra(graph, startIndex, path, cost, max):                                                      
    """                                                                                                
    求解各节点最短路径,获取path,和cost数组,                                                                          
    path[i] 表示vi节点的前继节点索引,一直追溯到起点。                                                                     
    cost[i] 表示vi节点的花费                                                                                  
    V[i] 用于记录是否被标过号                                                                                    
    """                                                                                                
    lenth = len(graph)                                                                                 
    v = [0] * lenth                                                                                    
    # 初始化 path,cost,V                                                                                  
    for i in range(lenth):                                                                             
        if i == startIndex:                                                                            
            v[startIndex] = 1                                                                          
        else:                                                                                          
            cost[i] = graph[startIndex][i]                                                             
            path[i] = (startIndex if (cost[i] < max) else -1)                                          
    print (v, cost, path)                                                                              
    for i in range(1, lenth):                                                                          
        print("-------------","第{0}次".format(i))                                                       
        minCost = max                                                                                  
        curNode = -1                                                                                   
        for w in range(lenth):                                                                         
            if v[w] == 0 and cost[w] < minCost:                                                        
                minCost = cost[w]                                                                      
                curNode = w                                                                            
                print("最小成本",minCost)                                                                  
                print("当前节点",curNode)                                                                  
        # for 获取最小权值的节点                                                                                
        if curNode == -1: break                                                                        
        # 剩下都是不可通行的节点,跳出循环                                                                             
        v[curNode] = 1                                                                                 
        print("已经遍历的节点",v)                                                                             
        for w in range(lenth):                                                                         
            if v[w] == 0 and (graph[curNode][w] + cost[curNode] < cost[w]):                            
                cost[w] = graph[curNode][w] + cost[curNode] # 更新权值                                     
                path[w] = curNode # 更新路径                                                               
                print("更新权值",cost)                                                                     
                print("前级节点",path)                                                                     
                                                                                                       
        # for 更新其他节点的权值(距离)和路径                                                                         
    return path ,cost                                                                                  
                                                                                                       
if __name__ == '__main__':                                                                             
    max = 2147483647                                                                                   
    graph = [                                                                                          
        [max, max, 10, max, 30, 100],                                                                  
        [max, max, 5, max, max, max],                                                                  
        [max, max, max, 50, max, max],                                                                 
        [max, max, max, max, max, 10],                                                                 
        [max, max, max, 20, max, 60],                                                                  
        [max, max, max, max, max, max],                                                                
        ]                                                                                              
    path = [0] * 6                                                                                     
    cost = [0] * 6                                                                                     
    print (dijkstra(graph, 0, path, cost, max))                                                         



********************************************************************************
[1, 0, 0, 0, 0, 0] [0, 2147483647, 10, 2147483647, 30, 100] [0, -1, 0, -1, 0, 0]
------------- 第1次
最小成本 10
当前节点 2
已经遍历的节点 [1, 0, 1, 0, 0, 0]
更新权值 [0, 2147483647, 10, 60, 30, 100]
前级节点 [0, -1, 0, 2, 0, 0]
------------- 第2次
最小成本 60
当前节点 3
最小成本 30
当前节点 4
已经遍历的节点 [1, 0, 1, 0, 1, 0]
更新权值 [0, 2147483647, 10, 50, 30, 100]
前级节点 [0, -1, 0, 4, 0, 0]
更新权值 [0, 2147483647, 10, 50, 30, 90]
前级节点 [0, -1, 0, 4, 0, 4]
------------- 第3次
最小成本 50
当前节点 3
已经遍历的节点 [1, 0, 1, 1, 1, 0]
更新权值 [0, 2147483647, 10, 50, 30, 60]
前级节点 [0, -1, 0, 4, 0, 3]
------------- 第4次
最小成本 60
当前节点 5
已经遍历的节点 [1, 0, 1, 1, 1, 1]
------------- 第5次
([0, -1, 0, 4, 0, 3], [0, 2147483647, 10, 50, 30, 60])

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

且行且安~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值