zoukankan      html  css  js  c++  java
  • Johnson算法学习笔记

    (Johnson)算法学习笔记。

    在最短路的学习中,我们曾学习了三种最短路的算法,(Bellman-Ford)算法及其队列优化(SPFA)算法,(Dijkstra)算法。这些算法可以快速的求出单源最短路,即一个源点的最短路.

    (Floyd)算法,这个及其简短的算法,可以以(O(n^3))的复杂度算出任意一对点之间的最短路。

    我们发现,(floyd)算法的时间复杂度和边的数量没有多大的关系,也就是说,(floyd)使用的最优条件是稠密图。

    那么问题来了,如果我们面对一个点数非常多但是边数较少的图,我们该用什么算法呢?


    (johnson)出现了。

    (johnson)算法是一类用来处理多源最短路的算法,它的复杂度是(O(n*m*log_n))

    简单的来说,(johnson)算法是糅合的两大单源最短路算法的算法。

    (dijkstra)算法在算法界是一个公认非常好用的算法,只可惜其限制条件过多,必须没用负边才可以使用。

    (SPFA)就没有那么多限制了,它只用保证数据中不会出现负环即可,可是由于(spfa)算法及其不稳定,及其容易被卡成(O(n*m))的复杂度。

    (johnson)算法就利用了两大算法的优点。


    首先(johnson)先利用(SPFA)将所有的边处理一下,将负边权全都转成正边权。

    然后再每个点暴力跑(dijkatra)求出最短路。

    第二步利用(dijkstra)跑最短路是十分显然好懂的,问题就是第一步将负边改为正边。

    我们知道,直接将所有的负边加上一个极大值是错误的,我们要给所有的边加上一个合适的值。

    那么这个值是什么呢?

    我们先增加一个超级源,把所有点和它相连即可。

    然后,我们来以超级源为源点跑一遍(spfa)

    然后我们对于每一条边加上(spaf)跑完后的(dis[0][u]-dis[0][v])

    最后,把所有的(dis[u][v])减去(dis[0][u]-dis[u][v])还原。


    让我们来证明其正确性:

    1.边权不为负数。

    由于(dis[0][u]+w(u,v)>=dis[0][j])

    所以必有(dis[0][u]-dis[0][j]+w(u,v)>=0)

    所以边权必定大于等于(0),可以用(dijkstra)跑。

    2.还原的正确性。

    我们有一条集合为({A_1,A_2,A_3,,,,A_p})的最短路。

    我们对边权进行修改后,最短路改变的值为:(dis[0][A_1]-dis[0][A_2]+dis[0][A_2]-...-dis[0][A_p])

    即:(dis[0][A_1]-dis[0][A_p])

    所以,当我们修改一些权值时,任意两点之间的最短路改变的值是一个定值,即(dis[0][u]-dis[v])

    在最后的(dis[u][v])上减掉即可。

  • 相关阅读:
    PAIRING WORKFLOW MANAGER 1.0 WITH SHAREPOINT 2013
    Education resources from Microsoft
    upgrade to sql server 2012
    ULSViewer sharepoint 2013 log viewer
    Top 10 Most Valuable Microsoft SharePoint 2010 Books
    讨论 Setsockopt选项
    使用 Alchemy 技术编译 C 语言程序为 Flex 可调用的 SWC
    Nagle's algorithm
    Nagle算法 TCP_NODELAY和TCP_CORK
    Design issues Sending small data segments over TCP with Winsock
  • 原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11379992.html
Copyright © 2011-2022 走看看