(3-2)Bellman-Ford算法:Bellman-Ford算法的核心思想

3.2  Bellman-Ford算法的核心思想

Bellman-Ford算法的核心思想是通过不断对图中的边进行松弛操作,逐步更新节点的最短路径估计值,直至获得最终的最短路径。

3.2.1  图的表示方法

Bellman-Ford算法可以适用于图的不同表示方法,其中邻接矩阵和邻接表是两种常见的表示方式。下面分别介绍在这两种表示方法,展示使用Bellman-Ford算法找到图中最短路径的方法。

1. 邻接矩阵(Adjacency Matrix)

邻接矩阵是一个二维数组,其中矩阵的行和列分别代表图中的节点,矩阵的元素表示节点之间的边的关系。

  1. 表示方式:若存在边 (i, j),则矩阵的第 i 行第 j 列的元素为1。若不存在边 (i, j),则矩阵的第 i 行第 j 列的元素为0。
  2. 优点:查找两个节点之间是否有边的关系非常高效,时间复杂度为O(1)。
  3. 缺点:对于稀疏图(边相对较少)而言,矩阵中大部分元素为0,造成空间浪费。

例如下面的邻接矩阵举例:

   0  1  2  3

0  0  1  1  0

1  1  0  1  1

2  1  1  0  0

3  0  1  0  0

2. 邻接表(Adjacency List)

邻接表是由若干个链表构成的集合,其中每个链表表示图中一个节点及其相邻节点。

  1. 表示方式:对于每个节点,用一个链表存储其相邻的节点。
  2. 优点:对于稀疏图而言,邻接表更为节省空间,因为只存储存在的边。遍历节点的相邻节点更为高效,时间复杂度取决于节点的度数。
  3. 缺点:查找两个节点之间是否有边的关系的时间复杂度较高,需要遍历链表。

例如下面的邻接表举例:

0: 1  2

1: 0  2  3

2: 0  1

3: 1

在实际应用中,选择邻接矩阵还是邻接表取决于图的规模、密度以及算法的需求。邻接矩阵适合表示稠密图,而邻接表适合表示稀疏图。

3.2.2  Bellman-Ford算法的原理

Bellman-Ford算法的关键在于通过不断更新节点的最短路径估计值,逐步逼近最优解。Bellman-Ford的最优子结构性质保证了每次迭代后的局部最优解可以被整体最优解所包含。接下来我们举个例子,展示Bellman-Ford算法的实现过程,请看下面的例图3-8。

图3-8  例图

(1)首先,在上面的例图中设置指定的源顶点A为0,将所有的距离初始化为无限∞,但是到源本身的距离除外,如图3-8所示。因为图中的顶点总数为6,所以所有的边都必须处理5次。

图3-8  源顶点A和距离

(2)开始第一次迭代,找到加权图中从源节点到其他所有节点的最短路径。在每次迭代中,检查所有边,如果通过当前路径到达目标节点的距离比之前计算的距离更短,则更新目标节点的距离。在第一次迭代后,节点的距离值根据给定的规则进行更新。例如,在第一次迭代后,A到B的距离由无穷大变为6,A到C的距离由无穷大变为1,以此类推。

在第一次迭代后,路径可能是:

(A, B)

(A, C)

(A, D)

(B, E)

(C, B)

(C, E)

(D, C)

(D, F)

(E, F)

此时,根据规则进行距离更新。如果满足条件 distance[u] + 边uv的权重 < distance[v],则用 distance[u] + 边uv的权重 替换 distance[v]。在第一次迭代后数值会发生如下变化,效果如图3-8所示。

A   B   C   D   E   F

0   ∞   ∞   ∞   ∞   ∞

6   -1  3   -1  5   3

-   2   3   5   5   4

图3-8  在第一次迭代后的值

(3)在第二次迭代后继续执行重复相同的步骤,如果值发生变化,则继续更新。在每次迭代中,根据规则 distance[u] + 边uv的权重 < distance[v] 进行更新。在第二次迭代后,数值发生如下变化,效果如图3-8所示。

A   B   C   D   E   F

0   ∞   ∞   ∞   ∞   ∞

6   -1  3   -1  5   3

-   2   3   5   5   4

0   1   3   5   1   4

图3-8  在第二次迭代后的值

(4)在第三次迭代后,数值再次发生变化。继续重复相同的步骤,如果值发生变化,则继续更新。在每次迭代中,根据规则 distance[u] + 边uv的权重 < distance[v] 进行更新。在第三次迭代后,数值发生如下变化,效果如图3-8所示。

A   B   C   D   E   F

0   ∞   ∞   ∞   ∞   ∞

6   -1  3   -1  5   3

-   2   3   5   5   4

0   1   3   5   1   4

1   0   3   5   0   3

图3-8  在第三次迭代后的值

这表示在经过第三次迭代后,距离数组的值再次发生了变化。这个过程会一直重复,直到不再发生变化为止。此时可以观察到在经过第三次迭代后,距离已经最小化,并且在之后的迭代中没有发生变化。尽管算法再次执行,但距离没有更新。这说明在这个例子中,总共进行了三次迭代。这个算法的时间复杂度是 O(E.V),其中 E 是边的数量,V 是顶点的数量。

(5)经过第五次迭代后,最短路径和距离如下所示,这可以看出从源A到每个顶点的最短路径距离。效果如图3-8所示。

A 0

B 1

C 3

D 5

E 0

F 3

图3-8  源A到每个顶点的最短路径距离

3.2.3  Bellman-Ford算法的实现步骤

Bellman-Ford算法是一种单源最短路径算法,用于在加权图中找到从源节点到每个其他节点的最短路径,它通过迭代地放松最短路径权重直到找到所有路径来实现。算法开始时将源节点的距离设置为0,将所有其他节点的距离设置为无穷大。然后,它逐一放松图的边,更新每个节点的距离,直到所有距离都被更新。算法然后检查图中是否存在负循环,如果找到一个,它返回错误。如果未发现负循环,则找到了从源节点到所有其他节点的最短路径。如果图中有V个顶点,则迭代的次数将是|V|-1。

Bellman-Ford算法的主要实现步骤如下所示。

(1)初始化:将源节点的最短路径估计值设为0,其他节点的最短路径估计值设为正无穷大。

(2)边的松弛操作:对图中的每一条边进行松弛操作。对于边(u, v),如果通过u节点可以获得比当前已知的最短路径估计值更短的路径,则更新节点v的最短路径估计值为通过u到v的路径长度。

(3)迭代:重复边的松弛操作步骤,总共进行|V|-1次迭代,其中|V|是节点数。这是因为在一般情况下,最短路径不会包含超过|V|-1条边。

(4)检测负权环:如果在进行|V|-1次迭代后仍然存在可以更新的最短路径,说明图中存在负权环。负权环可以无限降低路径长度,使得算法无法收敛。

未完待续

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值