转载:大佬博客

最近想到了许多优化spfa的方法,这里想写个日报与大家探讨下

前置知识:spfa(不带任何优化)

由于使用较多 STLSTL ,本文中所有代码的评测均开启 O_2O2​ 优化

对一些数组的定义:

dis[i]dis[i] : 起点到 ii 的最短路径(目前)

inq[i]inq[i] : ii 是否存在队列当中

现在进入正题


1.一些简单的优化(?)

SLF(Small Label First)优化 在使用queue作为spfa的辅助数据结构时,将队列替换为双端队列,每当插入元素 nownow时,与队首进行比较,若 dis[q.front()] > dis[now]dis[q.front()]>dis[now] ,将 nownow 从队首插入,否则从队尾插入。

LLL(Large Label Last)优化 同样使用双端队列,维护目前队列中元素到起点的距离的平均值(即 ∑^{tail}_{i =head}dis[que[i]]/q.size()∑i=headtail​dis[que[i]]/q.size() ),设该数为 kk ,若 dis[now] > kdis[now]>k ,则从队尾插入,否则从队首插入。

由于这两种优化过于简单,不给出具体代码实现。

使用效果:只能让你的spfa跑的快一点,适用于常数大的同学。至于卡了spfa的题,仍旧没有什么用处。

QQ :为什么这两种优化有用?

AA :即使图经过了特殊构造(如网格图),但边权大部分随机的情况下。 SLFSLF 能使得更可能更新出节点最优解的节点最先进行更新,减少无用迭代次数。而 LLLLLL 优化我认为说实话用处不大,因为只要走上了一条权值特别大的边,这个优化就和没有一样了。


2.一些升级过后的优化方式

容错后的SLF 定义容错值 valval ,当满足 dis[now] > dis[q.front()] + valdis[now]>dis[q.front()]+val 时从队尾插入,否则从队首插入。

mcfx优化 定义区间 [l,r][l,r] ,当入队节点的入队次数属于这个区间的时候,从队首插入,否则从队尾插入。

Swap-SLF 若队列改变且 dis[q.front()] > dis[q.back()]dis[q.front()]>dis[q.back()] ,交换队首队尾

代码实现以及评测

容错SLF+MCFX :https://www.luogu.org/record/show?rid=14511935

swap-SLF :https://www.luogu.org/recordnew/show/14512493

(这几个优化已经能过数据不刁钻的卡spfa的题,至于lg的模板...fstqwq就是看着这几个优化来卡的...)

QQ :为什么这几种优化有用?

AA :具体我也没有在网上找到,我说说自己理解的吧。容错SLF可以让你的程序不陷入局部最优解,与模拟退火类似;而mcfx优化是这样的,如过某个节点出发的大多数边都只能更新一个次解(说白了就是这个点如果是出题人用来故意让你经过多次的节点,并且每次更新会导致一次特别长的迭代,类似菊花图的根),那么它在队列中的优先级就会降低,就像你知道出题人用这个点来卡你,你竟然还把它最先拿来最先更新,肯定是不够好的;至于swap-SLF....我也没有搞懂为什么这个优化能比普通的SLF快辣么多(ComeIntoPower说这可以让队列更接近优队)...


3.一些玄学的优化

边序随机 将读入给你的边随机打乱后进行spfa

队列随机 每个节点入队时,以1 / 2的概率从队首入队,1 / 2的概率从队尾入队。

队列随机优化版 每 CC 次入队后,将队列元素随机打乱。

使用方法:一般配合上面的优化,当然如果你使用了队列随机...那么你只能靠rp啦。

边序随机代码实现:

//如果你和我一样是用vector + pair存图的话,那么只需要加上这一行语句

for(int i = 1 ; i <= n ; ++i) random_shuffle(G[i].begin() , G[i].end()); 

//以及开头加上srand(time(NULL));

队列随机优化版+边序随机代码实现:

https://www.luogu.org/record/show?rid=14090021


4.更改使用的数据结构

priorty_queue || zkw-segment-tree

当正权边上的时候,这两个数据结构优化的spfa与dijkstra相同...

(即使您的代码允许节点多次入队,但是也没什么用,因为一个节点最多进入一次队列)

而负权边的时候,这个算法又被称为允许多次入队的dijkstra,但是很危险,有可能被卡成指数级!

stack

dfs实现的spfa,被提出于姜碧野的论文,事实上,它用来判断负环可能十分快速(没必要进行多余的 NN 次迭代)。但是如果是求最短路,一般不如队列版本spfa。为什么会这样呢?因为spfa_dfs一个次解就是一个 O(N)O(N) 的迭代,一种图可以轻而易举的卡爆它。

所以我们采用IDDFS逐渐放宽深度的方式,这样子spfa_dfs也能赶上spfa_bfs


参考文献:

[1] : fstqwq的知乎回答

https://www.zhihu.com/question/292283275/answer/484871888

[2] : 姜碧野 《迭代求解的利器--spfa算法的优化及其应用》

https://wenku.baidu.com/view/f22d0d36ee06eff9aef807e9.html

队列优化dijsktra(SPFA)的玄学优化的更多相关文章

  1. POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)

    POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意:  圣诞树是由n个节点和e个边构成的,点编号1-n. ...

  2. spfa的SLF优化

    spfa的SLF优化就是small label first 优化,当加入一个新点v的时候如果此时的dis[v]比队首dis[q.front()]还要小的话,就把v点加入到队首,否则把他加入到队尾,因为 ...

  3. 并不对劲的图论专题(三):SPFA算法的优化

    1.bzoj1489-> 这是个新套路. 我们希望找到最小的x,那么可以二分x,然后判断是否存在圈的边权的平均值小于等于x. 设圈的边权依次为w1,w2,w3,…,wk,平均值为p, 则有p= ...

  4. SPFA的小优化

    标签:闲扯 SPFA的小优化 1. 向队尾加入元素时,如果它比对首还优,就把把它直接和队首交换. 拿一个双端队列来实现 (手写 , head ,tail   STLdeque亲测及其慢) 这个小优化其 ...

  5. 关于SPFA算法的优化方式

    关于SPFA算法的优化方式 这篇随笔讲解信息学奥林匹克竞赛中图论部分的求最短路算法SPFA的两种优化方式.学习这两种优化算法需要有SPFA朴素算法的学习经验.在本随笔中SPFA朴素算法的相关知识将不予 ...

  6. 基于各种基础数据结构的SPFA和各种优化

    一.基于各种数据结构的SPFA 以下各个数据均为不卡SPFA的最短路模板:P3371 [模板]单源最短路径(弱化版)的测试时间 1.STL队列:用时: 1106ms / 内存: 8496KB #inc ...

  7. SPOJ 15. The Shortest Path 堆优化Dijsktra

    You are given a list of cities. Each direct connection between two cities has its transportation cos ...

  8. 性能优化系列三:JVM优化

    一.几个基本概念 GCRoots对象都有哪些 所有正在运行的线程的栈上的引用变量.所有的全局变量.所有ClassLoader... 1.System Class.2.JNI Local3.JNI Gl ...

  9. mysql性能优化-慢查询分析、优化索引和配置 (慢查询日志,explain,profile)

    mysql性能优化-慢查询分析.优化索引和配置 (慢查询日志,explain,profile) 一.优化概述 二.查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 ...

随机推荐

  1. PHP异常处理详解

      PHP异常处理详解 异常处理(又称为错误处理)功能提供了处理程序运行时出现的错误或异常情况的方法. 异常处理通常是防止未知错误产生所采取的处理措施.异常处理的好处是你不用再绞尽脑汁去考虑各种错误, ...

  2. ECC 算法

    一.简介 1)椭圆曲线密码学的初级读本 http://8btc.com/thread-1240-1-1.html 2)ECC加密算法入门介绍 http://www.pediy.com/kssd/ped ...

  3. 浅谈 js中parseInt函数的解析[转]

    首先还是从很热门的实例parseInt("09")==0说起. parseInt(number,type)这个函数后面如果不跟第2个参数来表示进制的话,默认是10进制. 比如说pa ...

  4. 【解决】SOUI向导生成项目(VC2013以上版本编译时)无法运行XP解决

    对于SOUI向导生成的项目,无法在XP运行(提示 不是有效的WIN32程序 ) 即便设置为: 也无效,使用eXeScope打开发现最低系统要求是6.0,也就是说最少要WINXP以上,例如WIN7才能运 ...

  5. OSG相机与视图

    转自:http://blog.csdn.net/wang15061955806/article/details/51603083 相机与视图     osg::Camera类用来管理OSG中的模型—— ...

  6. CodeForces 342C Cupboard and Balloons (几何问题)

    题意:给定一个 r 和 h,r 是上面那个半球的半径,h 是下面那个圆柱的高度,然后有一些半径为 r/2的气球,问你最多能放几个. 析:根据题意,很容易知道,先从下面往上放,两个两个的放,放到不能放的 ...

  7. PHP 5.2 5.3 5.4 5.5 memcache dll扩展

    在windows下PHP5.2版本的memcache扩展dll文件好找,5.3的可能不是很好找,这里提供PHP5.2.5.3.5.4.5.5的php_memcache.dll扩展,需要的可以下载. 全 ...

  8. 流程控制语句(if、for、while、do while、switch、 break、continue)

    3:流程控制语句    (1)顺序结构 从上往下,依次执行    (2)选择结构    按照不同的选择,执行不同的代码    (3)循环结构 做一些重复的代码 4:if语句    (1)三种格式   ...

  9. VS中ashx文件关键字没有高亮标记的解决办法

    VS --- 工具 --- 选项 --- 文本编辑器 --- 文件扩展名,只要在右侧添加 ashx ,选中MS-VS c# 保存后

  10. 关于validate的自定义样式

    $("#Form").validate({ rules: { name: "required" }, messages: { name: "请输入您的 ...