算法:最短路径问题

    求图结构中连接两个给定顶点的最短路径长度

    本章将介绍找出加权图最短路径的一些算法

一、迪杰斯特拉最短路径算法(Dijkstra):

       Dijkstra算法是单源最短路径算法

1、使用优先队列的宽度优先搜索

        用优先队列替代了队列,BFS将顶点序号保存到队列,而Dijkstra会利用优先队列保存顶点序号和已找出的到目标顶点的最短距离。至于优先组队列,则会按照到顶点的最短距离排列各顶点。通过这种过程,在尚未访问的顶点中找出到起点的距离最短的顶点会变得更简单。

const int   MAX_V = 100;
int   V;
vector< pair<int, int> > adj[MAX_V];
vector<int>  dijkstra(int src) {
	vector<int>   dist(V, INF);
	dist[src] = 0;
	priority_queue<pair<int, int> > pq;
	pq.push(make_pair(0, src));
	while (!pq.empty()) {
		int   cost = -pq.top().first;
		int   here = pq.top().second;
		pq.pop();
		// if there are some more shorter path than the current path, then igorne the current path
		if (dist[here] < cost)  continue;
		//
		for (int i=0; i<adj[here].size(); ++i) {
			int there = adj[here][i].first;
			int nextDist = cost + adj[here][i].second;
			//
			if (dist[there] > nextDist) {
				dist[there] = nextDist;
				pq.push(make_pair(-nextDist, there));
			}
		}//
	}
}
二、贝尔曼-福特最短路径算法(Bellman-Ford)

      求某个起点到其他顶点的最短距离时,dijkstra算法最有用。不过,对带有负权边的图结构,dijkstra将无法保障其正确性。为了解决这种问题,Bellman-Ford应运而生。与dijkstra算法相同,bellman-ford算法也是单源最短路径算法,但它能够对带有负权边的图结构找出最短路径。

       Bellman-Ford首先会预测出从起点到各顶点之间最短距离的上限值,然后通过迭代运算的方式逐渐减少预测值和实际最短距离之间的误差。而dijkstra算法基于宽度优先搜索,每次对某个顶点进行最短距离的计算。很显然,两种算法具有完全不同的运算过程。Bellman-Ford在执行过程中会生成数组upper[],该数组将保存起点到各顶点的最知距离的上限。随着算法的执行,此数组当中的数值会慢慢变小,算法结束时会会变成最短距离。

vector<int>  bellmanFord(int src) {
	vector<int>   upper(V, INF);
	upper[src] = 0;
	bool updated;
	//
	for (int iter=0; iter<V; iter++) {
		updated = false;
		for (int here=0; here<V; here++) {
			for (int i=0; i<adj[here].size(); i++) {
				int there = adj[here][i].first;
				int cost = adj[here][i].second;
				//
				if (upper[there] > upper[here] + cost) {
					upper[there] = upper[here] + cost;
					updated = true;
				}
			}
		}//
		if (!updated) break;
	}
	if (updated)   upper.clear();
	return upper;
}
三、弗洛伊德多源最短路径算法(Floyd):
     根据问题的需求,有时候需要对所有成对顶点求出最短距离。解决这种问题时,可以把各顶点都视为起点,并反复执行dijkstra。若存在负权值,就改用bellman-ford。

其实,有一种更快的算法Floyd,会计算出图结构的所有成对顶点之间的最短距离,并保存到二维数组dist[][]。此数组的元素dist[u][v]表示从顶点u到v的最短距离。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值