bellman-ford算法优化

bellman-ford算法网上介绍比较多,这里就不再复述,可参考https://blog.csdn.net/qq_40984919/article/details/80489441,或者搜索其他的博客文章。

原算法描述为:

BELLMAN-FORD(G, w, s)
	n <- |V[G]|
	p <- array[n]
	d <- array[n]
	for each v in V[G]
		do d[v] <- ∞
			p[v] <- NIL
	d[s] <- 0
	for i<-1 to n-1
		do for each edge(u,v) in E[G]
			do if d[v] > d[u]+w(u,v)
				then d[v] <- d[u]+w(u,v)
					p[v] <- u
	for each edge(u,v) in E[G]
		do if d[v] > d[u]+w(u,v)
			then return FALSE
	return TRUE

通过分析可以知道,是经过了n-1次松弛后判断是否达到最优来判断是否存在负权值回路,而最优的判断其实和松弛的判断是一样的。

因此对松弛操作添加一个标记,来记录是否达到最优,那么当不存在负权值回路的情况下,可能就不用遍历n次。重点标注下是可能不用遍历n次;对于离散的边或者排好序的边拥有比较好的收益,往往只需遍历较少的次数就能得到结果。

当然如果存在负权值回路,依然还是要遍历n次。

修改后的算法如下:

BELLMAN-FORD(G, w, s)
	n <- |V[G]|
	p <- array[n]
	d <- array[n]
	for each v in V[G]
		do d[v] <- ∞
			p[v] <- NIL
	d[s] <- 0
	for i<-1 to n-1
        incomplete <- false
		do for each edge(u,v) in E[G]
			do if d[v] > d[u]+w(u,v)
				then d[v] <- d[u]+w(u,v)
					p[v] <- u
                    incomplete <- true
        if not incomplete
            then return TRUE
    for each edge(u,v) in E[G]
		do if d[v] > d[u]+w(u,v)
            return FALSE
	return TRUE

通过添加一个未完成标记判断是否修改过权值,如果出现了权值更小的路径,就标记为未完成;每对所有的边完成松弛完就判断是否有修改,一旦没有修改,后面即使循环再多次,也不可能还会修改,这样就能判断存在最短路径,可以立即返回。

当存在负权值回路时,就永远都会出现更小权值边,因此只需要保持和原算法一样的循环次数就行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值