1. add method for class AdjMatrixGraph
/* * All-Pairs Shortest Paths */ void AdjMatrixGraph::floydWarshall() { unsigned int *d = new unsigned int[v * v]; unsigned int *p = new unsigned int[v * v]; // d0 = A for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { d[i * v + j] = A[i * v + j]; p[i * v + j] = v + 1; } } int n = v; for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { unsigned int distance = d[i * v + k] + d[k * v + j]; if (distance < d[i * v + j]) { d[i * v + j] = distance; p[i * v + j] = k; } } } } cout << "All-Pairs Shortest Paths distance matrix is "<< endl; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { cout << d[i * v + j]<< " "; } cout << endl; } cout << endl; cout << "All-Pairs Shortest Paths parent matrix is "<< endl; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { cout << p[i * v + j]<< " "; } cout << endl; } }
2. test suite
#include "../ch22/Edge.h" #include "../ch22/Graph.h" #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { Edge e[] = { { 1, 2, 10 }, { 1, 4, 5 }, { 2, 3, 1 }, { 2, 4, 2 }, { 3, 5, 4 }, { 4, 2, 3 }, { 4, 3, 9 }, { 4, 5, 2 }, { 5, 1, 7 }, { 5, 3, 6 } }; Edges* edges = Edges::getInstance(); for (unsigned int i = 0; i < sizeof(e)/sizeof(Edge); i++) { edges->insert(&(e[i])); } int numberOfVertexes = 5; AdjMatrixGraph *g1 = new AdjMatrixGraph(numberOfVertexes, edges, true, true); MatrixGraphBuilder* mgb = MatrixGraphBuilder::getInstance(); g1->build(mgb); g1->display(); g1->floydWarshall(); }
3. run result
0 10 2147483647 5 2147483647 2147483647 0 1 2 2147483647 2147483647 2147483647 0 2147483647 4 2147483647 3 9 0 2 7 2147483647 6 2147483647 0 All-Pairs Shortest Paths distance matrix is 0 8 9 5 7 11 0 1 2 4 11 19 0 16 4 9 3 4 0 2 7 15 6 12 0 All-Pairs Shortest Paths parent matrix is 6 3 3 6 3 4 6 6 6 3 4 4 6 4 6 4 6 1 6 6 6 3 6 0 6
4. 推广:如果将E中每条边的权值赋为1,然后运行Floyd-Warshall算法,可以得到有向图的传递闭包。
4.1 add method transitiveClosure
/* * Transitive Closure */ void AdjMatrixGraph::transitiveClosure() { int *d = new int[v * v]; // init d0 for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { if (i == j || ((A[i * v + j] > 0) && (A[i * v + j] < std::numeric_limits<int>::max()))) { d[i * v + j] = 1; } else { d[i * v + j] = 0; } } } int n = v; for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { d[i * v + j] |= d[i * v + k] & d[k * v + j]; } } } cout << "Transitive Closure Matrix is "<< endl; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { cout << d[i * v + j]<< " "; } cout << endl; } }
4.2 test suite
#include "../ch22/Edge.h" #include "../ch22/Graph.h" #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { Edge e[] = { { 1, 2, 10 }, { 1, 4, 5 }, { 2, 3, 1 }, { 2, 4, 2 }, { 3, 5, 4 }, { 4, 2, 3 }, { 4, 3, 9 }, { 4, 5, 2 }, { 5, 1, 7 }, { 5, 3, 6 } }; Edges* edges = Edges::getInstance(); for (unsigned int i = 0; i < sizeof(e)/sizeof(Edge); i++) { edges->insert(&(e[i])); } int numberOfVertexes = 5; AdjMatrixGraph *g1 = new AdjMatrixGraph(numberOfVertexes, edges, true, true); MatrixGraphBuilder* mgb = MatrixGraphBuilder::getInstance(); g1->build(mgb); g1->display(); g1->transitiveClosure(); }
4.3 test result
0 10 2147483647 5 2147483647 2147483647 0 1 2 2147483647 2147483647 2147483647 0 2147483647 4 2147483647 3 9 0 2 7 2147483647 6 2147483647 0 Transitive Closure Matrix is 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1