您的位置:首页 > 其它

算法导论 ch25 每对顶点间的最短路径

2010-05-23 21:37 429 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: