贪心算法之Dijkstra

三角不等式:

单源最短路径:

对于给定的一个源顶点s∈V,对所有v∈V找出最短路径权重为δ(s,v),如果所有边权重wu,v)是非负的,则s到所有点的最短路径肯定存在。

思想:

1. 有一个顶点集合S,从s到他的最短路径是未知的。

2. 在每一步,添加从sv∈V-S的路径是最短的vS

3. 更新顶点邻接表中到v的距离

算法如下:

最后结果如下:

算法分析如下:

如果对所有的(uv)∈Ewuv=1,则它变成了广度优先搜索(Breadth-first-search

算法如下:

验证算法的正确性:

代码如下:

# This Python file uses the following encoding: utf-8
#############################################
debug=0
MAX_NUM=10000
v_num=6
#S 放 最短路径结点添加过程
S=[]#[{'index': 1, 'val': 0},...]
#dist放各个步骤临时dist值
dist=[]
edge=[
    [0,30,15,MAX_NUM,MAX_NUM,MAX_NUM],
    [5,0,MAX_NUM,MAX_NUM,20,30],
    [MAX_NUM,10,0,MAX_NUM,MAX_NUM,15],
    [MAX_NUM,MAX_NUM,MAX_NUM,0,MAX_NUM,MAX_NUM],
    [MAX_NUM,MAX_NUM,MAX_NUM,10,0,MAX_NUM],
    [MAX_NUM,MAX_NUM,MAX_NUM,30,10,0]
]
#############################################
def init(start):
    if(debug):
        print("[init]")
    S.append({'index':start,'val':0})
    i=0
    while(i<v_num):
        dist.append(edge[start-1][i])
        i=i+1

######################
def v_in_S(v):
    i=0
    while(i<len(S)):
        if(v==S[i]['index']):
            return "YES"
        i=i+1
    
    return "NO"

######################
def get_min():
    if(debug):
        print("[get_min]")
    if(len(dist)<1):
        return {'index':-1,'val':0}#这里该直接exit(1)的,这里返回值,是方便调试而已
    i=0
    min_val=MAX_NUM
    min_index=0
    while(i<len(dist)):
        if(v_in_S(i+1)=="NO"):
            if(dist[i] < MAX_NUM and dist[i] > 0 and min_val>dist[i]):
                min_val=dist[i]
                min_index=i
        i=i+1
    return {'index':min_index+1,'val':min_val}


######################
def update_dist():
    tmp_index=S[len(S)-1]['index']
    tmp_val=S[len(S)-1]['val']
    if(debug):
        print("[update_dist]","tmp_index=",tmp_index,";tmp_val=",tmp_val)    
    i=0
    while(i<v_num):
        if(v_in_S(i+1)=="NO"):
            i_dist=tmp_val+edge[tmp_index-1][i]
            if(debug):
                print("i=",i,";i_dist=",i_dist)
            if(dist[i]>i_dist):
                dist[i]=i_dist
        i=i+1
    if(debug):
        print("after update dist:dist=",dist)
    
######################
def process():
    if(debug):    
        print("[process]")
    i=0
    S_len=len(S)
    while(v_num != S_len and i<v_num):
        min_vertex=get_min()
        if(debug):
            print("i=",i,";min_vertex=",min_vertex)        
            print("len(S)=",len(S),";S=",S)
        if(min_vertex['index']>0):
            if(debug):
                print("----BEFORE append:   len(S)=",len(S),";S=",S)
            S.append(min_vertex)
            if(debug):
                print("====AFTER append:   len(S)=",len(S),";S=",S)            
            update_dist()
            
        i=i+1
        S_len=len(S)

######################
def py_Dijkstra(start):
    init(start)
    print("初始条件:\n","\tstart=",start,"\n\tS=",S,"\n\tdist=",dist)
    process()
    print("结果:\n","\tS=",S,"\n\tdist=",dist)
    
#############################################
if(__name__=="__main__"):
	py_Dijkstra(1)

以上代码转自:http://blog.csdn.net/playboyno/article/details/7832437

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值