最短路径算法GydF4y2Ba
最短路径算法是一组为解决最短路径问题而设计的算法。最短路径问题是大多数人都很熟悉的问题给定两个点,A和B,它们之间的最短路径是什么?然而,在计算机科学中,最短路径问题可以有不同的形式,因此需要不同的算法来解决它们。GydF4y2Ba
为了简单和通用性,最短路径算法通常在某些输入图上运行,GydF4y2Ba .这个图是由一组顶点组成的,GydF4y2Ba ,和边缘,GydF4y2Ba ,它们之间的联系。如果边具有权值,则图称为加权图。有时这些边是双向的,图称为无向的。有时在图中甚至可以有循环。对于特定的图形类型,每一个细微的差异都使得一种算法比另一种算法更有效。下面是一个例子。GydF4y2Ba
还有不同类型的最短路径算法。也许你需要找到点A和B之间的最短路径,但也许你需要找到点A和图中所有其他点之间的最短路径。GydF4y2Ba
最短路径算法有很多应用。如前所述,谷歌或苹果地图等地图软件使用最短路径算法。它们对道路网、运营和物流研究也很重要。最短路径算法对于计算机网络也非常重要,比如互联网。GydF4y2Ba
任何帮助你选择路线的软件都使用某种形式的最短路径算法。谷歌地图,例如,让您放置一个起点和一个终点,并将为您解决最短路径问题。GydF4y2Ba
类型的图表GydF4y2Ba
图有许多变体。第一个特性是其边的方向性。边可以是单向的,也可以是双向的。如果它们是单向的,则该图形称为aGydF4y2Ba导演GydF4y2Ba图表如果它们是双向的(意味着它们都是双向的),则该图形称为aGydF4y2Ba没有目标的GydF4y2Ba图表在某些边是定向边而其他边不是定向边的情况下,应将双向边替换为满足相同功能的2条定向边。该图现在已完全定向。GydF4y2Ba
图的第二属性与边缘的重量有关。边缘可以没有重量,并且在这种情况下,调用图形GydF4y2Ba未加权GydF4y2Ba.如果边缘确实有权重,则据说该图形GydF4y2Ba加重GydF4y2Ba.这里有一个额外的警告:图可以允许有负权边。负权边的包含禁止了某些最短路径算法的使用。GydF4y2Ba
图的第三个影响算法可用性的属性是圈的存在性。循环定义为任何路径GydF4y2Ba 通过图表,GydF4y2Ba ,访问同一个顶点,GydF4y2Ba ,不止一次。所以,如果一个图有任何一条路径,其中有一个圈,那么这个图被称为GydF4y2Ba循环GydF4y2Ba.GydF4y2Ba非循环GydF4y2Ba图,没有圈的图,允许在使用算法时有更多的自由。GydF4y2Ba
最短路径算法的类型GydF4y2Ba
最短路径算法有两种主要类型:单源最短路径算法和全对最短路径算法。这两种类型的算法都以各自的方式表现得最好。由于增加了复杂性,所有pairs算法运行时间更长。所有最短路径算法都返回可用于查找最短路径的值,即使这些返回值在不同的路径中有所不同GydF4y2Ba类型GydF4y2Ba或者从一个算法到另一个算法。GydF4y2Ba
单一GydF4y2Ba
单源最短路径算法的工作原理如下:GydF4y2Ba
给定一个图GydF4y2Ba 顶点,GydF4y2Ba ,边缘GydF4y2Ba 带权函数GydF4y2Ba ,和单个源顶点,GydF4y2Ba ,从返回最短路径GydF4y2Ba 到所有其他顶点GydF4y2Ba .GydF4y2Ba
如果算法的目标是找出两个给定顶点之间的最短路径,GydF4y2Ba 和GydF4y2Ba ,当找到最短路径时,算法可以简单地停止。因为没有办法决定先“完成”哪个顶点,所以所有求解两个给定顶点之间最短路径的算法都有相同的最坏情况GydF4y2Ba时间复杂度GydF4y2Ba为单源最短路径算法。GydF4y2Ba
这种范式也适用于GydF4y2Basingle-destination最短路径GydF4y2Ba问题通过反转图中的所有边,可以将单目标问题简化为单源问题。因此,给定一个目标顶点,GydF4y2Ba ,这个算法会找到最短路径GydF4y2Ba启动GydF4y2Ba在所有其他的顶点上GydF4y2Ba .GydF4y2Ba
全对GydF4y2Ba
全对最短路径算法遵循以下定义:GydF4y2Ba
给定一个图GydF4y2Ba 顶点,GydF4y2Ba ,边缘GydF4y2Ba 带权函数GydF4y2Ba 从中返回最短路径GydF4y2Ba 到GydF4y2Ba 对所有GydF4y2Ba 在GydF4y2Ba .GydF4y2Ba
对于全对问题最常见的算法是GydF4y2BaFloyd-Warshall算法GydF4y2Ba.该算法返回一个值矩阵GydF4y2Ba ,每个细胞GydF4y2Ba 是最短路径到顶点的距离GydF4y2Ba 到顶点GydF4y2Ba .路径重构可以找到实现最短路径的实际路径,但这不是基本算法的一部分。GydF4y2Ba
算法GydF4y2Ba
Bellman-Ford算法解决了一般情况下的单源问题,其中边可以具有负权重,并且图是有向的。如果图形是无向的,则必须通过在每个方向上包含两条边来对其进行修改,以使其具有方向性。GydF4y2Ba
Bellman-Ford的特性是它可以检测到从源可达的负权环,这意味着不存在最短路径。如果存在负权环,则一条路径可以在该循环上无限运行,路径成本降低为GydF4y2Ba .GydF4y2Ba
如果没有负重循环,则Bellman-Ford返回最短路径的重量以及路径本身。GydF4y2Ba
Dijkstra算法利用GydF4y2Ba宽度搜索GydF4y2Ba(这不是单源最短路径算法)来解决单源问题。它在图上有一个约束:不能有负权边。然而,对于这个约束,Dijkstra大大改进了Bellman-Ford的运行时。GydF4y2Ba
Dijkstra算法有时也用于解决所有对的最短路径问题,只需在所有顶点上运行该算法即可GydF4y2Ba .同样,这要求所有边的权值都是正的。GydF4y2Ba
拓扑排序GydF4y2Ba
对于有向无环图(DAG),出现了一个非常有用的工具来寻找最短路径。通过执行GydF4y2Ba拓扑排序GydF4y2Ba在图中的顶点上,最短路径问题在线性时间可解决。GydF4y2Ba
拓扑排序是对所有顶点进行排序,使每个边GydF4y2Ba 在GydF4y2Ba ,GydF4y2Ba 来到之前GydF4y2Ba 在订购中。在DAG中,最短路径总是明确的,因为即使存在负重边缘,也可以没有负重循环。GydF4y2Ba
Floyd-Warshall算法解决了全对最短路径问题。它使用一个GydF4y2Ba动态规划GydF4y2Ba这样做的方法。Floyd-Warshall可能存在负边权。GydF4y2Ba
Floyd-Warshall利用了以下观察:A到C的最短路径是A到B的最短路径加上B到C的最短路径GydF4y2Ba或者GydF4y2Ba这是已经找到的从A到C的最短路径。这可能看起来微不足道,但正是它允许Floyd Warshall以经典的动态编程方式从较小的最短路径构建最短路径。GydF4y2Ba
虽然Floyd-Warshall适用于密集图(意味着许多边缘),但Johnson的算法最适合稀疏图(意味着很少的边)。在稀疏图表中,与Floyd-Warshall相比,Johnson的算法具有较低的渐近运行时间。GydF4y2Ba
Johnson的算法利用了重新加权的概念,并在多个顶点上使用Dijkstra的算法,在完成边的重新加权后找到最短路径。GydF4y2Ba
算法比较GydF4y2Ba
下面列出了最短路径算法的运行时间。GydF4y2Ba
另见:GydF4y2Ba大O符号GydF4y2Ba.GydF4y2Ba
算法GydF4y2Ba | 运行时GydF4y2Ba |
贝尔曼福特GydF4y2Ba | |
迪杰斯特拉(列表)GydF4y2Ba | |
拓扑排序GydF4y2Ba | |
Floyd-WarshallGydF4y2Ba | |
约翰逊的GydF4y2Ba | *GydF4y2Ba |
*此运行时假定实现使用GydF4y2Ba斐波纳契堆积GydF4y2Ba.GydF4y2Ba
通常,使用哪种算法的问题不是留给个人的;它仅仅是被操作的图和被解决的最短路径问题的一个函数。GydF4y2Ba
对于具有负权边的图,单源最短路径问题需要Bellman-Ford才能解决。对于稠密图和全对问题,应该使用Floyd-Warshall。GydF4y2Ba
然而,有一些细微的差别。对于稀疏图和全对问题,使用约翰逊算法可能是显而易见的。然而,如果没有负边权值,那么实际上使用Dijkstra算法更好GydF4y2Ba二元堆GydF4y2Ba在实现。从每个顶点运行Dijsktra会产生更好的结果。GydF4y2Ba
从空间复杂性的角度来看,许多算法都是相同的。例如,贝尔曼·福特(Bellman Ford)和迪克斯特拉(Dijkstra)在最基本的形式上是完全相同的,因为它们使用相同的图形表示法。然而,当使用诸如斐波那契或二进制堆之类的高级数据结构加速这些算法时,执行该算法所需的空间就会增加。与算法一样,空间常常被用来换取速度。GydF4y2Ba
改进GydF4y2Ba
随着时间的推移,这些算法得到了改进。例如,Dijkstra算法最初是使用列表实现的,运行时为GydF4y2Ba .但是,当使用二进制堆时,运行时间GydF4y2Ba 已经实现了。当使用fibonacci堆时,可以实现一种实现GydF4y2Ba 而另一个人可以GydF4y2Ba 哪里GydF4y2Ba 是边权重的有界常数。GydF4y2Ba
Bellman-Ford已经在GydF4y2Ba .如果在正确类型的图(稀疏)上使用,这个实现可以是有效的。GydF4y2Ba