【DayDayUp】【算法_图_最短路_之二_SPFA最劣、Dij堆优化&Johnson(结点对最短路)】(待续)

【坚持不能偷懒】

——好吧,已经偷懒很久了……

——M边数、N点数


关于SPFA的一些想法:

SPFA实际上是一种看脸迭代法

在SPFA过程中,一旦出现某个在真实最短路上出现过的点

因为它的权值已经达到了最优,所以在以后的过程中,不会再次出现

——关于Dij的heap优化——

DIJ的heap优化,每次均以最优来迭代,但消耗了寻找最优的时间(logN)

Dij的操作有两个 1、删除最优权值 2、给结点降权

常规的堆优化 操作1和2的复杂度均为logN

而1需要N次,2需要M次 所以复杂度为 (N+M)logN

假设每次对一条边权的查询,都会对一个点更新,则需要M次,所以MlogN

斐波那契堆 在对结点降权的操作中,其摊还复杂度为 O(1)

那么使用斐波那契堆的Dij,能优化到 NlogN + M * 1 的复杂度

————————————


而SPFA则看脸,以消除这个寻找最优的过程

每次遍历一遍队列的时间是M

但如果每次(次为遍历一遍队列的过程)寻找出的最优点均在队尾

且每次都会把剩余所有点标记flag

则达到最劣情况 N*M


举个例子:

把点记为 1 2 3 ... N

搜索 1 to N 的路径时

实际最优路是 1 - N-1 - N-2 - N-3 ... N

且 最优路径边权 均为 0

除最优边权外,其余边权为

1 —— 2^(N+K)

N - 1 —— 2^(N+K-1)

N - 2 —— 2^(N+K-2)

……

如此,每次搜索,队列中所有点flag均会置为1

但会搜索 N 次

——————一些优化的设想——————

1,SPFA不能保证搜索到目的点时,就已经最优

所以需要迭代至不能迭代为止

但当前获得的最短路,可以作为剪枝依据,若一个点的更新值劣于当前最短路

则忽略其影响

2,如果考虑针对如上情况,或许可以如同快速排序的选点,采取随机化策略


Ps:注意到SPFA中,产生的浪费操作为,当 A to B 更新后,A to B to C 也会更新

如此产生的影响,我也不知道怎么消除……

——————————————————




结点对之间的最短路

Johnson算法达到 O(NNlgN + MN)

来获取任意两点间最短路


如果图中无负权,则可以直接对每个点采用DijHeap来搜索

N * MlgN (斐波那契堆则为 NNlgN)

但如果图中出现的负权

仍然可以做出一定调整后采取相同策略


如果给每个点赋任意固定权重 h(i)

对于u,v两点,最短路权记为w(u,v)

记 W(u,v) = w(u,v) + h(u) - h(v)

那么 以W找出的最短路 和 原图最短路,一致

待续




——部分内容参考自《算法导论第3版》,推荐阅读原书





你可能感兴趣的:(算法_搜索)