SPFA优化算法-SLF_Swap
SPFA优化算法-SLF_Swap
SPFA他死了
出于众所周知的原因,SPFA他死了。但是我们可以通过一些简单的优化来挽回一点点(对于存心针对优化卡SPFA的数据依然没有办法)。
首先 SPFA 的最坏时间复杂度是 $O(n^2)$ 的,对于堆优化 Dijkstra 的 $O(n\log n)$ 是被完爆的。而优化实际上是让队列接近于优先队列的 $\log n$ 级别。
- SLF(Small Label First) 优化 使用双端队列,每当插入元素时,与队首距离进行比较,若插入元素距离小于队首距离则从队首插入,否则从队尾插入。
- LLL(Large Label Last) 优化 同样使用双端队列,维护目前队列中元素到起点的距离的平均值,若大于平均值则从队尾插入,否则从队首插入。
但是上面两种是很容易被卡的,因此容错SLF和MCFX就出现了。
- 容错SLF 定义容错值,当插入元素距离减去容错值小于队首距离时从队尾插入,否则从队首插入。
- MCFX优化 定义一个区间,当入队节点的入队次数属于这个区间的时候,从队首插入,否则从队尾插入。
随后总算来到了今天的重头戏 SLF_Swap 。
SLF_Swap 在队列改变时判断如果队首距离大于队尾距离则交换首尾元素。
代码示例如下:
1
2
3
4
5
6
7
8
9
10
11
void SLF_Swap() {
if (!q.empty() && dis[q.front()] > dis[q.back()]) {
int x = q.front();
int y = q.back();
q.pop_front();
q.pop_back();
q.push_front(y);
q.push_back(x);
return;
}
}
当然还有一些随机化的优化,比如打乱边序,随机首尾入队,随机打乱队列之类,但是这些都比较玄学,能不能过纯看运气。
写在最后
这是本站的第一篇博客,感觉要庆祝一下。
但是不知道写什么就把自己几年前初学时候写的放上来。
本文由作者按照 CC BY 4.0 进行授权
本文今日阅读量: 加载中... 次 本文总阅读量 加载中... 次
