Bellman Ford 最短路径算法

版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者同意不得转载。 https://blog.csdn.net/kenden23/article/details/28231681

Dijsktra算法不能计算带负数路径的图 - 由于Dijsktra仅仅更新当前最小路径的权值,并不会更新之后找到的新的最短路径值 - 当有负数的时候这样的情况是会出现的。没有负数的情况下是不可能出现的。

而Bellman Ford是能够处理这样的情况的。

可是注意两种算法都不肯能处理出现负权值环的问题,负权值环出现好像也没有实际意义吧?没细致研究过,只是负权值的环会导致无限小的的值,由于能够无线走这个环换取更小的权值。


參考:http://www.geeksforgeeks.org/dynamic-programming-set-23-bellman-ford-algorithm/

參考文两点小瑕疵,1 没处理溢出问题。 2 给出的图不够完好,能够使用Dijsktra处理。

我这里创建一个无法使用Dijsktra处理的简单的图:

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

class BellmanFord
{
	struct Edge
	{
		int src, des, wei;
	};

	struct Graph
	{
		int V, E;
		Edge *edges;
		Graph(int v, int e) : V(v), E(e)
		{
			edges = new Edge[e];
		}
		~Graph()
		{
			if (edges) delete edges, edges = NULL;
		}
	};

	void printArr(int dist[], int n)
	{
		printf("Vertex   Distance from Source
");
		for (int i = 0; i < n; ++i)
			printf("%d 		 %d
", i, dist[i]);
	}

	void bellmanFord(Graph *gra, int src, int *dist)
	{
		int V = gra->V, E = gra->E;
		dist[src] = 0;

		for (int v = 1; v < V; v++)
		{
			for (int e = 0; e < E; e++)
			{
				int i = gra->edges[e].src;
				int j = gra->edges[e].des;
				int w = gra->edges[e].wei;
				//handle overflow
				if (dist[i] != INT_MAX && dist[i] + w < dist[j])
				{
					dist[j] = dist[i] + w;
				}
			}
		}

		for (int e = 0; e < E; e++)
		{
			int u = gra->edges[e].src;
			int v = gra->edges[e].des;
			int w = gra->edges[e].wei;
			if (dist[u] != INT_MAX && dist[u] + w < dist[v])
				printf("Graph contains negative weight cycle");
		}
	}
public:
	BellmanFord()
	{
		/* Let us create the graph given in above example */
		int V = 5;  // Number of vertices in graph
		int E = 4;  // Number of edges in graph
		struct Graph* graph = new Graph(V, E);

		/*
		// add edge 0-1 (or A-B in above figure)
		graph->edges[0].src = 0;
		graph->edges[0].des = 1;
		graph->edges[0].wei = -1;

		// add edges 0-2 (or A-C in above figure)
		graph->edges[1].src = 0;
		graph->edges[1].des = 2;
		graph->edges[1].wei = 4;

		// add edges 1-2 (or B-C in above figure)
		graph->edges[2].src = 1;
		graph->edges[2].des = 2;
		graph->edges[2].wei = 3;

		// add edges 1-3 (or B-D in above figure)
		graph->edges[3].src = 1;
		graph->edges[3].des = 3;
		graph->edges[3].wei = 2;

		// add edges 1-4 (or A-E in above figure)
		graph->edges[4].src = 1;
		graph->edges[4].des = 4;
		graph->edges[4].wei = 2;

		// add edges 3-2 (or D-C in above figure)
		graph->edges[5].src = 3;
		graph->edges[5].des = 2;
		graph->edges[5].wei = 5;

		// add edges 3-1 (or D-B in above figure)
		graph->edges[6].src = 3;
		graph->edges[6].des = 1;
		graph->edges[6].wei = 1;

		// add edges 4-3 (or E-D in above figure)
		graph->edges[7].src = 4;
		graph->edges[7].des = 3;
		graph->edges[7].wei = -3;
		*/

		graph->edges[0].src = 0;
		graph->edges[0].des = 1;
		graph->edges[0].wei = -8;

		graph->edges[1].src = 0;
		graph->edges[1].des = 3;
		graph->edges[1].wei = -3;

		graph->edges[2].src = 1;
		graph->edges[2].des = 2;
		graph->edges[2].wei = -2;

		graph->edges[3].src = 2;
		graph->edges[3].des = 3;
		graph->edges[3].wei = 5;

		int *dist = new int[V];
		for (int i = 0; i < V; i++)
		{
			dist[i] = INT_MAX;
		}

		bellmanFord(graph, 0, dist);

		printArr(dist, V);

		delete dist;
	}
};

输出:



大家能够试一试,这样的图使用Dijkstra处理,结果是错误的。


【推广】 免费学中医,健康全家人
原文地址:https://www.cnblogs.com/ldxsuanfa/p/10612770.html