• 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处理,结果是错误的。


  • 相关阅读:
    Talend open studio数据导入、导出、同步Mysql、oracle、sqlserver简单案例
    Mysql彻底卸载
    .net图片快速去底(去除白色背景)
    .net图片自动裁剪白边函数案例
    .net图片裁剪抠图之性能优化
    .net图片压缩
    .net微软消息队列(msmq)简单案例
    SVM手撕公式
    算法效率分析
    模型稳定性
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10612770.html
  • Copyright © 2020-2023  润新知