Last active
December 11, 2015 01:19
-
-
Save TheRayTracer/4522782 to your computer and use it in GitHub Desktop.
A working implementation of the Bellman - Ford algorithm in C++. It will also detect and bail out if a negative cycle is detected.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <vector> | |
#include <cassert> | |
#include <limits> | |
#include <iomanip> | |
namespace std { } | |
using namespace std; | |
struct edge | |
{ | |
size_t u, v; | |
long weight; | |
}; | |
istream& operator>>(istream& is, edge& i) | |
{ | |
return is >> i.u >> i.v >> i.weight; | |
} | |
long bellman_ford(const vector<edge>& store, const size_t s, const size_t nodes, const long max_weight, bool& negative_cycle_detected) | |
{ | |
assert(s < nodes); | |
negative_cycle_detected = false; | |
vector<long> distance; | |
distance.resize(nodes); | |
for (size_t i = 0; i < distance.size(); distance[i] = max_weight, ++i); | |
distance[s] = 0; | |
long result_min = 0; | |
for (size_t i = 0; i < (distance.size() - 1); ++i) | |
{ | |
for (size_t j = 0; j < store.size(); ++j) | |
{ | |
if ((distance[store[j].u] + store[j].weight) < distance[store[j].v]) | |
{ | |
distance[store[j].v] = distance[store[j].u] + store[j].weight; | |
result_min = min(distance[store[j].v], result_min); | |
} | |
} | |
} | |
for (size_t i = 0; i < store.size(); ++i) | |
{ | |
if ((distance[store[i].u] + store[i].weight) < distance[store[i].v]) | |
{ | |
negative_cycle_detected = true; | |
break; | |
} | |
} | |
return result_min; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
vector<edge> store; | |
size_t nodes = 0, edges = 0; | |
long max_weight = LONG_MIN; | |
if (argc > 1) | |
{ | |
ifstream ifs; | |
ifs.open(argv[1]); | |
ifs >> nodes >> edges; | |
edge e = {0}; | |
while (ifs >> e) | |
{ | |
--e.u; | |
--e.v; | |
store.push_back(e); | |
max_weight = max(max_weight, e.weight + 1); | |
} | |
ifs.close(); | |
} | |
cout << "Input size: " << store.size() << endl; | |
assert(store.size() == edges); | |
long min_weight = max_weight; | |
bool abort = false; | |
for (size_t i = 0; i < nodes; ++i) | |
{ | |
bool negative_cycle_detected = false; | |
long weight = bellman_ford(store, i, nodes, max_weight, negative_cycle_detected); | |
if (negative_cycle_detected == false) | |
{ | |
cout << "Source: " << setw(4) << i << ", Weight: " << setw(4) << weight << endl; | |
min_weight = min(min_weight, weight); | |
} | |
else | |
{ | |
cout << "Source: " << setw(4) << i << ", Negative Cycle Detected. No result. Aborting." << endl; | |
abort = true; | |
break; | |
} | |
} | |
if (abort == false) | |
{ | |
cout << "Shortest shortest weight: " << setw(4) << min_weight << endl; | |
} | |
cin.get(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 7 | |
1 2 -2 | |
2 3 -1 | |
3 1 4 | |
3 4 2 | |
3 5 -3 | |
6 4 1 | |
6 5 -4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment