1. 程式人生 > >沒事擼點演算法——dijkstra演算法(python)

沒事擼點演算法——dijkstra演算法(python)

    資料結構地提出是為了更好地解決資料儲存問題,圖資料結構的提出是為了解決生活中的複雜網路問題。

    在Python中,圖的表示方式一般使用字典以及列表完成。

#使用字典列表展現圖
graph={
       1:{2:1,3:12},
       2:{3:9,4:3},
       3:{5:5},
       4:{3:4,5:13,6:15},
       5:{6:4},
       6:{6:0}
       }

Dijkstra演算法一般是用於解決求解最短路徑問題,屬於盲目搜尋演算法。

原理:不斷求解起始節點到其他節點的最短路徑成本。

First:

引入cost字典,表示對於起始點到每一個其他節點的成本。eg:cost[2]=1。表示起始點(這裡設定為節點1)到節點2的成本需要1。

引入visted列表,記錄已訪問的節點。eg:起始visted=[1];

引入Parents字典,記錄已求解最短路徑節點的前一個節點。eg:假設至3節點的最短路徑為1-2-4-3,則parents[3]=4;

Second:演算法流程(以上面的網路圖為例)

cost初始值為1節點到各個節點的成本

1 2 3 4 5 6
0 1 12 999(無窮) 999(無窮) 999(無窮)

可以得出1-2的最短路徑成本即為1。因為1節點到2節點僅有一條路徑最短,如果1節點先到其他節點之後再返回2節點,必然成本大於1,所以1-2為2節點的最低成本路徑。此時將2節點放置visted中。

接下來,由於節點2已經解出1-2的最短路徑,計算2節點的出度(2-3,2-4)由1-2-3和1-2-4的成本分別為10、4小於之前的成本12、999,對cost字典進行更新。

1 2 3 4 5 6
0 1 10 4 999 999

此時,cost成本最小的為節點4,最短路徑為1-2-4,將4放入visted列表中,記錄parents[4]=2。

再看4的出度,對cost列表進行更新,尋找成本最小節點,記入visted列表中,同時記錄當前最短路徑節點的前一個節點,知道所有節點全部被訪問,即全部進入visted列表中,結束演算法。

全部程式碼:

# -*- coding: utf-8 -*-
"""
Created on Tue Oct 30 08:46:14 2018

@author: 24367
"""
# find the shortest node(not visted) to add in the list(visted)
def find_shortest_node(cost):
        minDist=999
        node=None
        for item in cost.keys():
            if (cost[item]<minDist)&(item not in visted):
                minDist=cost[item]
                node=item
        return node
        

#Create Graph for the route plan
graph={
       1:{2:1,3:12},
       2:{3:9,4:3},
       3:{5:5},
       4:{3:4,5:13,6:15},
       5:{6:4},
       6:{6:0}
       }
#記錄初始權值
cost={1:0,2:1,3:12,4:999,5:999,6:999}
#記錄當前最短路徑的前一個節點
parents={1:None,2:1,3:2,4:2,5:3,6:5}
#記錄已經訪問過的節點
visted=[1]
node=find_shortest_node(cost)
while (node):
    for i in graph[node]:
        newCost=cost[node]+graph[node][i];
        if(newCost<cost[i]):
            #更新cost權值以及記錄最短路徑前節點
            cost[i]=newCost
            parents[i]=node
    visted.append(node)#將最短路徑節點新增至已訪問列表中
    node=find_shortest_node(cost)
#輸出最短路徑
parent=parents[6]
while(parent):
    print(parent)
    parent=parents[parent]