版权声明:本文作者靖心,靖空间地址: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处理,结果是错误的。