数据结构复习(python)——狄克斯特拉算法(Dijkstra)

学习材料

《算法图解》第7章

适用情景

找出从一个节点到另一个节点的最短(快)路径

准备工作

对一个带权图进行描述,可使用两个散列表(字典),其中一个散列表用来描述每个结点的指向及权值,对于一个节点指向两个及以上的节点的情况,可使字典嵌套;另一个散列表用来描述从“起点”开始到其他节点的距离,若起点未与某个节点直接相连,在初始时把这段距离置为无穷大。

举例:图及其对应散列表如下

               数据结构复习(python)——狄克斯特拉算法(Dijkstra)_第1张图片

graph={}
graph["start"]={}
graph["start"]["A"]=5
graph["start"]["B"]=2
graph["A"]={}
graph["A"]["C"]=4
graph["A"]["D"]=2
graph["B"]={}
graph["B"]["A"]=8
graph["B"]["D"]=7
graph["C"]={}
graph["C"]["fin"]=3
graph["C"]["D"]=6
graph["D"]={}
graph["D"]["fin"]=1
graph["fin"]={}
costs={}
costs["A"]=5
costs["B"]=2
costs["C"]=float('inf')
costs["D"]=float('inf')
costs["fin"]=float('inf')

为了记录最短路径,还需要一个散列表描述最短路径中的父子关系。

parents={}
parents["A"]="start"
parents["B"]="start"
parents["C"]=""
parents["D"]=""
parents["fin"]=""

执行算法时,将不断更新costs和parents。

算法流程

(1)找出costs中对应值最小的结点,且未被处理过(未在processed中)

(2)检查该节点的邻居,寻找是否有从起点开始经过该节点到其邻居的更短路径,若有,则更新其邻居在costs的对应值

(3)重复(1)(2),直到对每个节点都做过这件事

(4)计算最短路径

代码如下:

processed=[]

def find_lowest_cost_node(costs):
    lowest_cost=float('inf')
    lowest_cost_node=None
    for node in costs: #遍历所有节点
        cost=costs[node]
        if costnewcost: #如果经过当前节点前往该邻居更近
            costs[n]=newcost #则更新起点到该邻居的距离(所谓的该邻居的开销)
            parents[n]=node #同时将该邻居的父节点设置为当前节点
    processed.append(node) #当前节点标记为已处理
    node=find_lowest_cost_node(costs) #找出下一个在costs中的最小开销节点,进入下一轮循环

输出最短路径及最短距离(测试):

def lowest_path(parents):
    record=["fin",]
    child=parents["fin"]
    while child != "start":
        record.append(child)
        child=parents[child]
    record.append("start")
    record.reverse()
    return record

def tatal_weight(record):
    record1=record[1::]
    sum=0
    for i in range(len(record1)):
        sum=sum+graph[record[i]][record1[i]]
    return sum


print(lowest_path(parents))
print(tatal_weight(lowest_path(parents)))

输出结果

['start', 'A', 'D', 'fin']
8

算法弊端

(1)不能用于有负权值的图,因为在该算法中,已处理过的点意味着从起点到该点的开销已是最小,且不会再对该点进行处理,但负权值可能会拉低这个最小开销。

(2)不能使用于有环图。只适用于有向无环图

(3)有负权值的图可使用贝尔曼—福德算法,非加权图可使用广度优先搜索算法。

 

你可能感兴趣的:(数据结构)