前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【狂热算法篇】探寻图论幽径:Bellman - Ford 算法的浪漫征程(通俗易懂版)

【狂热算法篇】探寻图论幽径:Bellman - Ford 算法的浪漫征程(通俗易懂版)

作者头像
用户11458826
发布于 2025-04-01 01:08:04
发布于 2025-04-01 01:08:04
13202
代码可运行
举报
文章被收录于专栏:杀马特杀马特
运行总次数:2
代码可运行

本篇带大家探究的是Bellman-Ford算法;从基本理解,画图分析展示,再到最后的代码实现,以及为何要这样实现代码,等一些细节问题做解释,相关题型应用,非常值得哟,尤其是刚入门的小白学习;干货满满,通俗易懂;欢迎大家点赞收藏阅读呀!!!

一·本算法背景:

在图论与计算机科学领域,求解最短路径问题是一个基础且关键的任务,它在众多实际场景中有着广泛的应用,如交通路线规划、通信网络优化、物流配送路径选择等。Bellman - Ford 算法作为一种经典的单源最短路径算法,能够在存在负权边的图中找到从源点到其他各顶点的最短路径,或判断图中是否存在负权回路,在解决复杂网络路径问题时发挥着重要作用。

但是它不像我们的FLoyd算法一样是多源可以求出每个点到某个点的最短路径;相比之下对dijkstra算法而下可以处理负边权(但都对负边环没办法)。

Floyd传送门:【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)-CSDN博客

dijkstra传送门:【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)-CSDN博客

二·算法核心思想及实例模拟操作:

Bellman - Ford 算法基于松弛操作的思想。

松弛操作是指对图中每条边所连接的两个顶点的距离进行比较和更新,尝试找到更短的路径。

其核心在于不断尝试通过其他顶点来缩短源点到目标顶点的距离,直到无法再进行优化或者确定存在负权回路。

从直观上理解,就像在一个地图(图)中,我们要从一个起点(源点)到达各个目的地(其他顶点),每次检查所有可能的路线(边),看是否能通过经过某个中间地点(中间顶点)来缩短从起点到目的地的距离。

说白了;就是对所有的边进行n-1次松弛操作;就可以把最终的源点到每个点的最短源点距更新出来。

个人认为相比上面的两个算法而言它更侧重于边;即我们每次是按照边为主来保存它的起始点,终止点,以及权重(也就是下面我们按照边给它封装成了类)。

这里我们还是需要三张表来记录,某点到源点的最短路径dist;边的相关信息;记录前驱结点方便找最短路径:

dist

edge

pre

某点到源点的最短路径dist

边的相关信息

记录某点前驱结点

以数组为例

设计成了结构体

数组为例

下面根据上面说的核心步骤;我们举例子来模拟一下:

储存edge的相关信息表:

u(起始点)

v(终止点)

w(边权)

1

3

-2

3

2

3

2

1

2

1

2

5

下面我们就根据表对它n-1次松弛:

三.算法详细步骤:

下面我们分四步来对代码进行差分过程;进行相关代码剖析书写操作:

3.1初始化:

这里的初始化其实是对我们的edge;也就是初始化边的数据;如果我们设置了pre的前驱节点保存来后序找到这条最短源点路径的一路上的节点是哪些;以及dist数组初始化;因此还要对它也初始化:

定义的储存边的相关信息:

完成初始化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (int i = 0; i < m; i++) 
	//单向边和双向边适用:
cin >> edge_group[i]._u >> edge_group[i]._v >> edge_group[i]._w;

还有前驱节点的表也要初始化:

其次,就是dist源点距数组:

这里由于我们点的编号是从1开始(一般);因此初始化的是1-n区间:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fill(dist+1, dist + n+1, maxi);//初始化dist要注意:我们从1-n的点的编号;也就是初始化这个区间([迭代器))

3.2对所有边进行松弛n-1次:

也就是我们遍历n-1遍对它的edge所有边进行松弛;发现有可以借助u到达v的就更新dist[v]:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (int i = 1; i <= n - 1; i++) {

	//全边松弛操作:
	for (auto a : edge_group) {
		/只要存在负边权就需要特判:
		if (dist[a._u] != maxi&&dist[a._u] + a._w < dist[a._v]) {
			//这里一定要提前特判是否源点可以到达u这个位置;正数权无所谓;但是如果出现负数;很有可能源点无法到达
			//u,它就会加上uv的权(负数);那么有可能导致就小于distv了;这就会更新;此时就出现了错误。
			pre[a._v] = a._u;//保存前驱
			dist[a._v] = dist[a._u] + a._w;
		
		}
	}

3.3退出小优化:

松弛操作对应位置check检查:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (int i = 1; i <= n - 1; i++) {
	bool ck = 0;//如果少于n-1对全边进行松弛就完成了最短路径确定就可以提前return就好
	//全边松弛操作:
	for (auto a : edge_group) {
		/只要存在负边权就需要特判:
		if (dist[a._u] != maxi&&dist[a._u] + a._w < dist[a._v]) {
			//这里一定要提前特判是否源点可以到达u这个位置;正数权无所谓;但是如果出现负数;很有可能源点无法到达
			//u,它就会加上uv的权(负数);那么有可能导致就小于distv了;这就会更新;此时就出现了错误。
			pre[a._v] = a._u;//保存前驱
			dist[a._v] = dist[a._u] + a._w;
			ck = 1;
		}
	}

3.4检查负环:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (auto a : edge_group)//判断是否存在负环;如果存在那么不存在最短路径也就是说
	//;n-1次全边松弛无法达到最短路径;即对全边继续进行松弛还能更新dist就是存在负环
	if (dist[a._u] != maxi && dist[a._u] + a._w < dist[a._v]) return 0;

四.代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int maxi = 0x3f3f3f3f;
const int N = 1e6 + 1;
int dist[N], n, m;
int pre[N];//前驱节点
class edge {//储存边相关信息
public: edge(int u,int v,int w) :_u(u),_v(v),_w(w) {}
	int _u,  _v,  _w;//此边的初始点,终止点,边权。
private:

};
vector<edge>edge_group;//先定义edge再搞数组防止找不到;还未初始化

bool Bellman_Ford(int s,int n) {//n个点
	fill(dist+1, dist + n+1, maxi);//初始化dist要注意:我们从1-n的点的编号;也就是初始化这个区间([迭代器))
	dist[s] = 0;
	for (int i = 1; i <= n - 1; i++) {
		bool ck = 0;//如果少于n-1对全边进行松弛就完成了最短路径确定就可以提前return就好
		//全边松弛操作:
		for (auto a : edge_group) {
			/只要存在负边权就需要特判:
			if (dist[a._u] != maxi&&dist[a._u] + a._w < dist[a._v]) {
				//这里一定要提前特判是否源点可以到达u这个位置;正数权无所谓;但是如果出现负数;很有可能源点无法到达
				//u,它就会加上uv的权(负数);那么有可能导致就小于distv了;这就会更新;此时就出现了错误。
				pre[a._v] = a._u;//保存前驱
				dist[a._v] = dist[a._u] + a._w;
				ck = 1;
			}
		}
		if (!ck) return 1;//进行判断是否可提前返回
	}
	for (auto a : edge_group)//判断是否存在负环;如果存在那么不存在最短路径也就是说
		//;n-1次全边松弛无法达到最短路径;即对全边继续进行松弛还能更新dist就是存在负环
		if (dist[a._u] != maxi && dist[a._u] + a._w < dist[a._v]) return 0;

	return 1;//正好n-1次松弛返回

}

void init_pre() {

	for (int i = 1; i <= n; i++)pre[i] = i;
}
int getpath(int x) {
	pre[x] == x ? x : getpath(pre[x]);
	cout << x << " ";
	return x;
}


int main() {
	cin >> n >> m;
	edge_group = vector<edge>(m,edge(0,0,0));//完成匿名初始化
	//edge_group.resize(m,edge(0,0,0));
	//绑定边的先关信息:
	for (int i = 0; i < m; i++) 
		//单向边和双向边适用:
	cin >> edge_group[i]._u >> edge_group[i]._v >> edge_group[i]._w;

	init_pre();


   // 调用 Bellman-Ford 算法
bool flag = Bellman_Ford(1, n);
if (flag) {
    if (dist[n] == maxi) cout << "unconnected" << endl;
	else {
		cout << dist[n] << endl;
		cout << "最短路径:" << endl;
		getpath(n);
	}
}
else {
    cout << "exist negative circle " << endl;
}
return 0;

}

五.例题应用及测试:

下面以一道含负权的为例:

题目传送门: 94. 城市间货物运输 I

解答代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int maxi = 0x3f3f3f3f;
const int N = 1e6 + 1;
int dist[N], n, m;
int pre[N];//前驱节点
class edge {//储存边相关信息
public: edge(int u,int v,int w) :_u(u),_v(v),_w(w) {}
	int _u,  _v,  _w;//此边的初始点,终止点,边权。
private:

};
vector<edge>edge_group;//先定义edge再搞数组防止找不到;还未初始化

bool Bellman_Ford(int s,int n) {//n个点
	fill(dist+1, dist + n+1, maxi);//初始化dist要注意:我们从1-n的点的编号;也就是初始化这个区间([迭代器))
	dist[s] = 0;
	for (int i = 1; i <= n - 1; i++) {
		bool ck = 0;//如果少于n-1对全边进行松弛就完成了最短路径确定就可以提前return就好
		//全边松弛操作:
		for (auto a : edge_group) {
			/只要存在负边权就需要特判:
			if (dist[a._u] != maxi&&dist[a._u] + a._w < dist[a._v]) {
				//这里一定要提前特判是否源点可以到达u这个位置;正数权无所谓;但是如果出现负数;很有可能源点无法到达
				//u,它就会加上uv的权(负数);那么有可能导致就小于distv了;这就会更新;此时就出现了错误。
				pre[a._v] = a._u;//保存前驱
				dist[a._v] = dist[a._u] + a._w;
				ck = 1;
			}
		}
		if (!ck) return 1;//进行判断是否可提前返回
	}
	for (auto a : edge_group)//判断是否存在负环;如果存在那么不存在最短路径也就是说
		//;n-1次全边松弛无法达到最短路径;即对全边继续进行松弛还能更新dist就是存在负环
		if (dist[a._u] != maxi && dist[a._u] + a._w < dist[a._v]) return 0;

	return 1;//正好n-1次松弛返回

}

void init_pre() {

	for (int i = 1; i <= n; i++)pre[i] = i;
}
int getpath(int x) {
	pre[x] == x ? x : getpath(pre[x]);
	cout << x << " ";
	return x;
}


int main() {
	cin >> n >> m;
	edge_group = vector<edge>(m,edge(0,0,0));//完成匿名初始化
	//edge_group.resize(m,edge(0,0,0));
	//绑定边的先关信息:
	for (int i = 0; i < m; i++) 
		//单向边和双向边适用:
	cin >> edge_group[i]._u >> edge_group[i]._v >> edge_group[i]._w;

	init_pre();


   // 调用 Bellman-Ford 算法
bool flag = Bellman_Ford(1, n);
if (flag) {
    if (dist[n] == maxi) cout << "unconnected" << endl;
	else {
		cout << dist[n] << endl;
		//cout << "最短路径:" << endl;
		//getpath(n);
	}
}
else {
    cout << "exist negative circle " << endl;
}
return 0;

}

成功AC:

来测试一下我们的路径是不是1 2 5 6吧:

来测试一下上面的模拟例子:

到达3的最短路径:

到达2的最短路径:

ok,也是没有问题的。

最后再判断一下是否存在负环:

还是可以跑完成的。

六·小细节及疑点剖析:

我们肯定在设计的过程会发现有一些疑问;下面博主总结了四个小疑问点;来解析一下:

6.1为什么进行n-1次全变松弛后就完成了最短源点距的更新:

6.1.2从图的路径结构角度分析:

1`在一个有 n 个顶点的带权有向图中,如果存在从源点 s 到顶点 v 的最短路径,那么这条路径最多包含 n - 1 条边。因为如果路径包含了 n 条或更多边,那么必然会有一个顶点在路径中出现至少两次,即存在环。 2`如果这个环的权值之和为非负,那么去掉这个环后得到的路径会更短,所以最短路径中不会包含权值非负的环;如果环的权值之和为负,那么就不存在最短路径,因为可以无限次绕这个负权环来使路径长度无限小。 3`因此,在不存在负权环的情况下,从源点到任意顶点的最短路径长度最长为 n - 1 条边,这就决定了算法最多需要 n - 1 次松弛操作来确定所有顶点的最短距离。

6.1.3从算法迭代过程分析:

1`第一次迭代,算法可以确定从源点 s 经过 1 条边能到达的顶点的最短距离,即找到了源点 s 到其直接邻居顶点的最短距离。 2`第二次迭代,算法会考虑从源点 s 经过 2 条边能到达的顶点,通过对第一次迭代得到的结果进行松弛操作,更新从源点 s 经过 2 条边到达的顶点的最短距离。 3`以此类推,第 k 次迭代可以确定从源点 s 经过最多 k 条边能到达的顶点的最短距离。 4`由于最短路径最长为 n - 1 条边,所以经过 n - 1 次迭代后,算法就可以确定从源点 s 到所有顶点的最短距离。

说白了就是:负环不考虑;正环可去掉(在获得最短路径的时候); 因此源点到达一个点获得最短路径的最长边一定是n-1;故我们如果我们进行一次全边松弛操作一定会得到这些点中;源点只需要走一条边就可达的点的dist完成填充;那么当再次全边松弛;此时就会借助上一次填的确定好的最短路径的点完成套用得到只需要两条边的点;依次类推到n-1次全边松弛;完成dist数组填充。

6.2为什么我们可以根据check数组提前完成对Bellman-Ford算法的调用:

因为我们最坏的情况是遍历完n-1遍对全边的松弛才会找到所有的源点距的最短路径;但是有时候可能不需要这么多次就可以完成dist数组的最终填充操作;因此我们会发现也就是剩下的遍历全边松弛操作只要无dist更新就说明完成了;可用check数组检查一下。

6.3为什么可以那样判断是否存在负环:

这就是我们Bellman-Ford算法和后序我们会讲的SPFA算法不同于其他最短路径算法的特处;它可以通过特性对负环(这一圈总和是负数的环);下面我们简单说明一下:

负环,它不是没有最短路径嘛(只要遍历环这条路径就会无限小)!因此我们当进行我们理论推导出来的n-1次全边松弛后;如果它存在负环;即当我们再次进行松弛还会发现最短路径;利用这个特性来检查负环:

如图:

验证了上述结论;负环可以一直松弛下去,并更新dist;因此上述判断可以使用作为负环判断条件。

6.4 为什么更新dist还要判断u点能否到达:

有负权的图需要注意;全正权无需考虑:

这里一定要提前特判是否源点可以到达u这个位置;正数权无所谓;但是如果出现负数;很有可能源点无法到达u,它就会加上uv的权(负数);那么有可能导致就小于distv了;这就会更新;此时就出现了错误。

比如:dsit[u]=无穷(源点不可达);而dist[v]=接近无穷(源点可达);而u-->v的权是负权假设为

-oo/2;这样就会更新dist[v];进行了错误的操作;因此要提前判断。

七.时间空间复杂度分析:

7.1时间复杂度:

其中n代表点个数;m代表边条数。

  1. 初始化距离数组的时间复杂度为o(n) ,因为需要对每个顶点的距离进行初始化。
  2. 松弛操作需要进行n-1 次迭代,每次迭代都要遍历所有的边 m,所以松弛操作的时间复杂度为O(nm) 。
  3. 检查负权回路时,需要再次遍历所有的边,时间复杂度为O(m) 。
  4. 总体时间复杂度为 O(nm),这使得 Bellman - Ford 算法在处理大规模图时效率较低,尤其是当边数和顶点数都很大时。

7.2空间复杂度:

  1. 算法需要存储边的信息,假设用数组或向量存储边,空间复杂度为O(m) 。
  2. 还需要存储每个顶点的最短距离估计值,空间复杂度为 O(n)。
  3. 总体空间复杂度为O(n+m)

八.算法优势与局限性:

8.1优势:

①能处理负权边

这是 Bellman - Ford 算法的一个显著优势。许多其他最短路径算法,如 Dijkstra 算法,只能处理边权非负的图。而 Bellman - Ford 算法可以在存在负权边的情况下正确计算最短路径,只要图中不存在负权回路。

②检测负权回路

算法不仅能计算最短路径,还能检测图中是否存在负权回路。这在一些实际应用中非常重要,例如在金融领域的套利问题中,负权回路可能代表着存在套利机会。

8.2局限性:

  1. 时间复杂度较高:如前所述,其时间复杂度为 O(nm),在处理大规模图时,计算量会非常大,运行效率较低。相比之下,Dijkstra 算法在使用优先队列优化后,时间复杂度可以降低到 O((n+m)*logn)<->或者nlogn,在边权非负的情况下性能更优。
  2. 对稀疏图效率较低:在稀疏图(边数n远小于m的图)中,Bellman - Ford 算法的性能也不如一些针对稀疏图优化的算法。

九.应用场景:

  1. 交通网络规划:在城市交通网络中,可能存在一些单向道路或收费不同的路段(对应图中的边权),可以使用 Bellman - Ford 算法计算从一个地点(源点)到其他各个地点的最短路径,考虑到某些路段可能因为交通拥堵、施工等原因导致通行成本增加(负权边),该算法能够更全面地处理这种复杂情况。
  2. 通信网络优化:在通信网络中,信号传输可能会受到各种因素的影响,导致不同链路的传输延迟不同(边权)。通过 Bellman - Ford 算法可以找到从一个节点到其他节点的最短延迟路径,即使存在一些干扰因素导致某些链路延迟增加(负权边),也能准确计算出最优路径。
  3. 经济决策分析:在经济学中,例如在计算投资回报时,可能存在一些成本和收益的复杂关系,某些决策可能会导致成本增加(负权边),而通过 Bellman - Ford 算法可以分析出从初始状态(源点)到不同目标状态的最优决策路径,帮助决策者做出更合理的选择。

十.个人小总结:

Bellman-Ford 算法通过 n - 1 次全边松弛操作,能够确保在不存在负权环的情况下,找到从源点到所有其他顶点的最短路径。如果在 n - 1 次松弛后,仍然存在可以松弛的边,那就说明图中存在负权环,此时算法可以检测到这种情况并进行相应处理。

对于代码实现可以简记:

n-1次全边松弛+check数组提前终止+负环判断+小细节(检查u点是否可达)(如点从1开始,dsit初始化操作)

适用简记:存在负权边的单源最短回路计算。

四种最短路径算法小总结:

这篇我们的Bellman_Ford(贝尔曼福德)算法就分享到此;下一篇博主将带大家剖析队列优化版的Bellman_Ford算法即SPFA算法;欢迎大家订阅呀!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Bellman-Ford算法--解决负权边问题
贝尔曼-福特算法(Bellman-Ford)是由理查德·贝尔曼(Richard Bellman) 和 莱斯特·福特 创立的,求解单源最短路径问题的一种算法。有时候这种算法也被称为 Moore-Bellman-Ford 算法,因为 Edward F. Moore 也为这个算法的发展做出了贡献。它的原理是对图进行V-1次松弛操作,得到所有可能的最短路径。其优于迪科斯彻算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达O(VE)。但算法可以进行若干种优化,提高了效率。
别团等shy哥发育
2023/04/23
9260
Bellman-Ford算法--解决负权边问题
单源最短路径之Bellman-Ford算法
贝尔曼-福特算法(Bellman-Ford)是由理查德·贝尔曼(Richard Bellman) 和 莱斯特·福特 创立的,求解单源最短路径问题的一种算法。有时候这种算法也被称为 Moore-Bellman-Ford 算法,因为 Edward F. Moore 也为这个算法的发展做出了贡献。它的原理是对图进行V-1次松弛操作(V是顶点数量),得到所有可能的最短路径。其优于Dijkstra算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达O(VE)。但算法可以进行若干种优化,提高了效率。
每天学Java
2020/06/01
1.9K0
出差(Bellman-Ford算法)
  A 国有 N 个城市, 编号为1…N 。小明是编号为 1 的城市中一家公司的员 工, 今天突然接到了上级通知需要去编号为 N 的城市出差。
别团等shy哥发育
2023/10/17
2880
出差(Bellman-Ford算法)
最短路算法实现与分析:Dijkstra算法,Floyed,Bellman-Ford, SPFA算法;
最短路算法:最短路径算法是图论研究中,一个经典算法问题;旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。
西湖醋鱼
2020/12/30
1.5K0
最短路算法实现与分析:Dijkstra算法,Floyed,Bellman-Ford, SPFA算法;
文心一言 VS 讯飞星火 VS chatgpt (354)-- 算法导论24.1 6题
六、假定G=(V,E)为一带权重的有向图,并且图中存在一个权重为负值的环路。给出一个有效的算法来列出所有属于该环路上的结点。请证明算法的正确性。如果要写代码,请用go语言。
福大大架构师每日一题
2024/09/25
800
文心一言 VS 讯飞星火 VS chatgpt (354)-- 算法导论24.1 6题
最短路径四大算法「建议收藏」
熟悉的最短路算法就几种:bellman-ford,dijkstra,spfa,floyd。 bellman-ford可以用于边权为负的图中,图里有负环也可以,如果有负环,算法会检测出负环。 时间复杂度O(VE); dijkstra只能用于边权都为正的图中。 时间复杂度O(n2); spfa是个bellman-ford的优化算法,本质是bellman-ford,所以适用性和bellman-ford一样。(用队列和邻接表优化)。 时间复杂度O(KE); floyd可以用于有负权的图中,即使有负环,算法也可以检测出来,可以求任意点的最短路径,有向图和无向图的最小环和最大环。 时间复杂度O(n3); 任何题目中都要注意的有四点事项:图是有向图还是无向图、是否有负权边,是否有重边,顶点到自身的可达性。 1、Dijkstra(单源点最短路) 这个算法只能计算单元最短路,而且不能计算负权值,这个算法是贪心的思想, dis数组用来储存起始点到其他点的最短路,但开始时却是存的起始点到其他点的初始路程。通过n-1遍的遍历找最短。每次在剩余节点中找dist数组中的值最小的,加入到s数组中,并且把剩余节点的dist数组更新。
全栈程序员站长
2022/09/06
6560
最短路径四大算法「建议收藏」
图详解第五篇:单源最短路径--Bellman-Ford算法
它的优点是可以解决有负权边的单源最短路径问题,而且可以用来判断是否有负权回路。 它也有明显的缺点,它的时间复杂度 O(N*E) (N是点数,E是边数)普遍是要高于Dijkstra算法O(N²)的。像这里如果我们使用邻接矩阵实现,那么遍历所有边的数量的时间复杂度就是O(N^3)。
YIN_尹
2024/01/23
1.5K0
图详解第五篇:单源最短路径--Bellman-Ford算法
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
其实还会有个二维path表方便我们 拿到两点及两点边之间的权,其次就是这里我们默认编号从1开始,但是数组下标确实0;我们就从1开始放入。
用户11458826
2025/02/02
500
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
文心一言 VS 讯飞星火 VS chatgpt (373)-- 算法导论24.4 5题
Bellman-Ford 算法本身就是一个用于解决差分约束系统问题的经典算法,其时间复杂度为 O(nm),其中 n 是顶点数(未知变量数),m 是边数(约束条件数)。因此,我们不需要对 Bellman-Ford 算法进行太多修改,只需确保它适用于差分约束系统问题即可。
福大大架构师每日一题
2024/10/21
900
文心一言 VS 讯飞星火 VS chatgpt (373)-- 算法导论24.4 5题
数据结构与算法——图最短路径
最短路径问题一直是图论研究的热点问题。例如在实际生活中的路径规划、地图导航等领域有重要的应用。关于求解图的最短路径方法也层出不穷,本篇文章将详细讲解图的最短路径经典算法。
五分钟学算法
2019/05/06
4.8K0
数据结构与算法——图最短路径
文心一言 VS 讯飞星火 VS chatgpt (391)-- 算法导论25.1 5题
五、说明如何将单源最短路径问题表示为矩阵和向量的乘积,并解释该乘积的计算过程如何对应 Bellman-Ford 算法?(请参阅24.1节。)。如果要写代码,请用go语言。
福大大架构师每日一题
2024/11/15
870
文心一言 VS 讯飞星火 VS chatgpt (391)-- 算法导论25.1 5题
文心一言 VS 讯飞星火 VS chatgpt (376)-- 算法导论24.4 8题
八、设 $Ax⩽b$ 为一个有 n 个变量和 m 个约束条件的差分约束系统。证明:在对应的约束图上运行 Bellman-Ford 算法将获得 $\sum_{i=1}^nx_i$ 的最大值,这里 $Ax⩽b$ 并且 $x_i⩽0$ 。如果要写代码,请用go语言。
福大大架构师每日一题
2024/10/25
890
文心一言 VS 讯飞星火 VS chatgpt (376)-- 算法导论24.4 8题
deepseek VS chatgpt (401)-- 算法导论25.3 1题
一、请在图25-2上使用Johnson算法来找到所有结点对之间的最短路径。给出算法计算出的 和值。如果要写代码,请用go语言。
福大大架构师每日一题
2025/02/19
480
deepseek VS chatgpt (401)-- 算法导论25.3 1题
最短路径算法汇总「建议收藏」
在有向连通图中,从任意顶点i到顶点j的最短路径,可以看做从顶点i出发,经过m个顶点中转,到达j的最短路程。最开始可以只允许经过”1”号顶点进行中转,接下来只允许经过”1”号顶点和”2”号顶点进行中转……允许经过”1”~”m”号顶点进行中转,求任意两顶点的最短路程。
全栈程序员站长
2022/09/02
1K0
文心一言 VS 讯飞星火 VS chatgpt (375)-- 算法导论24.4 7题
Bellman-Ford 算法通常用于在带权图中找到从单个源点到所有其他顶点的最短路径,并可以检测负权回路。差分约束系统(Difference Constraint Systems)可以表示为一系列形如 v_i - v_j \leq w 的不等式,它们可以通过将每个不等式看作图中的一条边来转化为图论问题。
福大大架构师每日一题
2024/10/23
1180
文心一言 VS 讯飞星火 VS chatgpt (375)-- 算法导论24.4 7题
文心一言 VS 讯飞星火 VS chatgpt (388)-- 算法导论24.5 8题
为了构造一个带权重有向图 G=(V,E) 的边的松弛操作的无限序列,使得每一步松弛操作都能对某一个最短路径估计值进行更新,我们可以利用 Bellman-Ford 算法的核心思想。Bellman-Ford 算法可以在带负权重边的图中找到最短路径,并且能检测负权重环路。
福大大架构师每日一题
2024/11/11
820
文心一言 VS 讯飞星火 VS chatgpt (388)-- 算法导论24.5 8题
文心一言 VS 讯飞星火 VS chatgpt (374)-- 算法导论24.4 6题
为了处理形式为 x_i = x_j + b_k 的相等约束,我们可以将其转换为差分约束系统中的两个不等式:
福大大架构师每日一题
2024/10/22
680
文心一言 VS 讯飞星火 VS chatgpt (374)-- 算法导论24.4 6题
数学建模--图论与最短路径
在数学建模中,图论及其算法在解决最短路径问题上具有重要应用。图论是研究图及其性质的学科,而图中的节点和边代表了现实世界中的各种元素及其相互关系。
用户11315985
2024/10/16
1370
单源最短路径算法[通俗易懂]
最短路径问题:如果从图中某一顶点(称为源点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边上的权值总和达到最小。当然这只是最基础的应用,关于单源最短路径还有很多变体:
全栈程序员站长
2022/09/01
1.8K0
单源最短路径算法[通俗易懂]
文心一言 VS 讯飞星火 VS chatgpt (377)-- 算法导论24.4 9题
为了证明 Bellman-Ford 算法在差分约束系统上运行能够获得 (max{x_i}-min{x_i}) 的最小值,并说明如何将其应用于安排建设工程的进度,我们可以按照以下步骤进行:
福大大架构师每日一题
2024/10/29
970
文心一言 VS 讯飞星火 VS chatgpt (377)-- 算法导论24.4 9题
推荐阅读
相关推荐
Bellman-Ford算法--解决负权边问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文