アルゴリズム学習−Bellman−Ford(ベルマンフォード)アルゴリズム(C++実装)
BellmanFordアルゴリズム
Bellman‐Fordアルゴリズムは単一ソース点最短経路アルゴリズムであり,このアルゴリズムの目的は図全体を見つけ,開始ノード(自分で定めた)最短経路と経路長に至ることである.
メリット/デメリット
このアルゴリズムの利点はDijkstraアルゴリズムに対して,負の重み経路があり,図中に負の重み回路があるかどうかを検出できることであるはずである.
欠点は,負の重み回路を検出できるが,負の重み回路がある最短経路の問題は解決できないことである.また、時間の複雑さが高い.O(|V| * |E|).
インプリメンテーション
実際に実現される原理は、現在の図全体に対して1回の緩和操作を行うことである.全部で|V|回行います.各弛緩操作は
|V|-1
回の弛緩判定であった.コード実装は次のとおりです.
//
// main.cpp
// BellmanFord
//
// Created by Alps on 15/3/26.
// Copyright (c) 2015 chen. All rights reserved.
//
#include <iostream>
using namespace std;
#ifndef NumVertex
#define NumVertex 4
#endif
#ifndef Infinity
#define Infinity 1000
#endif
typedef int Vertex;
struct LinkList{
int val;
int weight;
LinkList * next;
LinkList(int v, int w): val(v), weight(w), next(NULL){}
};
typedef LinkList* VList;
struct TableEntry{
VList Header;
Vertex Dist;
Vertex Path;
};
typedef TableEntry Table[NumVertex+1];
void InitTable(Vertex start, Table T){
int OutDegree = 0;
VList temp = NULL;
for (int i = 1; i <=NumVertex; i++) {
T[i].Header = NULL; // init the vertex
T[i].Dist = Infinity;
T[i].Path = -1;
scanf("%d",&OutDegree);
for (int j = 0; j < OutDegree; j++) { // init the link vertex
temp = (VList)malloc(sizeof(struct LinkList));
scanf("%d %d", &temp->val, &temp->weight);
temp->next = T[i].Header;
T[i].Header = temp;
}
}
T[start].Dist = 0;
}
void PrintPath(Vertex V, Table T){
if (T[V].Path != -1) {
PrintPath(T[V].Path, T);
printf(" to ");
}
printf("%d", V);
}
bool BellFord(Vertex start, Table T){
bool Update = false;
VList temp;
for (int i = 1; i <= NumVertex; i++) { //cycle the num of vertex
Update = false;
for (int j = 1; j <= NumVertex; j++) { // traversal all the vertex
if (T[j].Dist != Infinity) { // if the current vertex distance is not Inf
temp = T[j].Header;
while (temp != NULL) { // if it have traversaled the link vertex
if (T[j].Dist + temp->weight < T[temp->val].Dist) { //if need to relax
T[temp->val].Dist = T[j].Dist + temp->weight; //relax operation
T[temp->val].Path = j; // mark the path
Update = true; // mark the vertex update is true
}
temp = temp->next; // find the next node
}
}
}
}
if (Update == true) {
return false; // if the Graph have a negative cycle
}else{
return true; // no negative cycle
}
}
int main(int argc, const char * argv[]) {
Table T;
InitTable(1, T);
if (!BellFord(1, T)) {
printf("There is a cycle!
");
return 0;
}
PrintPath(3, T);
return 0;
}
:
case:
2 //
2 -1// id 2 length
3 1
2 //
3 -2 //
4 1
1
4 -1
0
上の図は、ノード1->2(-1)->3(1)ノード2->3(-2)->4(1)ノード3->4(-1)ノード4