转载:大佬博客

最近想到了许多优化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

转载于:https://www.cnblogs.com/wmq12138/p/10367009.html

队列优化dijsktra(SPFA)的玄学优化相关推荐

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

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

  2. 【BZOJ4289】Tax,堆优化dijsktra的最短路问题

    Time:2016.08.05 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 今天模拟题T1 时间全花在这上面了 我以后要因为艹正解而暴力没打完就去吃* n,m<=10时 直 ...

  3. BZOJ 4152 浅谈堆优化的SPFA算法

    世界真的很大 其实这道题一看就能想到最短路 关键是怎么建边 看一下数据,200000个点 每个点两两建边的话肯定会超时 好像说多了先看一下题吧: description 给定平面上的n个点,定义(x1 ...

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

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

  5. 洛谷P5071 [YNOI2015]此时此刻的光辉 莫队+玄学优化+卡常QWQ

    题目链接:传送门 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到未来,此时此 ...

  6. 单调队列 → 常用于动态规划问题的优化

    [算法解析] 单调队列是指在队尾入队出队,在队首出队,且其元素具有单调性的特殊队列.其中,在队尾入队出队的操作是用来维护单调队列的单调性,在队首出队的操作是用来维护单调队列的大小.单调队列常用于动态规 ...

  7. struts启动时加载_iOS优化篇之App启动时间优化

    原文:橘子不酸丶http://www.zyiner.com/article/5 前言 最近由于体验感觉我们的app启动时间过长,因此做了APP的启动优化.本次优化主要从三个方面来做了启动时间的优化,m ...

  8. 内存优化 · 基础论 · 初识 Android 内存优化

    [小木箱成长营]内存优化系列文章: 内存优化 · 工具论 · 常见的 Android 内存优化工具和框架 内存优化 · 方法论 · 揭开内存优化神秘面纱 内存优化 · 实战论 · 内存优化实践与应用 ...

  9. 【Linux 性能优化系列】Linux 性能优化 -- CPU 性能篇(三) Linux 软中断

    [Linux 性能优化系列]Linux 性能优化 -- CPU 性能篇(三) Linux 软中断 [1]相关概念 [1.1]中断 中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力:为了减少 ...

最新文章

  1. ubuntu 16.04 分辨率只有800×600问题解决
  2. 如何逼疯一名数学系学生?
  3. git下载安装、验证、企业实战单机、多人协作
  4. Java虚拟机-垃圾回收器
  5. POJ2182 HDU2711 Lost Cows【树状数组+线段树】
  6. IT部门不应忽略的12种数据
  7. 约瑟夫环c语言不用链表,C语言基于循环链表解决约瑟夫环问题的方法示例
  8. 蒋文华《博弈论》笔记及视频摘录
  9. rtl8188eu无线网卡驱动linux,rtl8188eu驱动下载-rtl8188eu无线网卡驱动程序v1.0 官方版 - 极光下载站...
  10. 打印机脱机了的修复方法
  11. kaggel竞赛之员工离职分析
  12. 键盘定位板图纸_DIY如何自制专属GH60机械键盘教程【步骤详解】
  13. OpenCV定位二维码的三个定位点
  14. 一维信号小波阈值去噪
  15. RxSwift使用教程
  16. WICC 广州高峰对话:为开发者标注「航海地图」
  17. python计算银行余额_Python 小案例实战 —— 简易银行存取款查询系统
  18. V4L2视频采集与H264编码1—V4L2采集JPEG数据
  19. C++ 洗牌算法的实现
  20. 大气顶层反射率无量纲_农作物种植面积遥感监测技术规程大蒜.doc

热门文章

  1. 使用Docx4j操作PPT指南系列(附一)
  2. 【0521模拟赛】小Z爱划水
  3. vscode snippet利器
  4. 有了jsRender,妈妈再也不用担心我用jq拼接DOM拼接的一团糟了、页面整齐了、其他伙伴读代码也不那么费劲了...
  5. html5之通讯API
  6. Oracle查询性能优化
  7. 【Spring源码分析系列】bean的加载
  8. 树形dp技巧,多叉树转二叉树
  9. Xcode文件被锁定:The file .xcodeproj could not be unlocked
  10. Android 访问WebService