all_pairs_shortest_paths
floyd_warshall
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
#include "chapter-22/vertex_graph/vertex_graph.h"
#include "chapter-25/all_pairs_shortest_paths/all_pairs_shortest_paths_utilities.h"
namespace CLRS
{
std::vector<std::vector<APSPMatrixElement>>
floyd_warshall
(const std::vector<std::vector<APSPMatrixElement>> &w)
{
std::size_t n = w.size();
auto D = w;
auto d = D;
APSPMatrixElement temp;
for(std::size_t k = 0; k != n; ++k)
{
d = D;
for(std::size_t i = 0; i != n; ++i)
for(std::size_t j = 0; j != n; ++j)
{
temp = d[i][k] + d[k][j];
if(temp < d[i][j])
D[i][j] = temp;
else if(d[i][j] < temp)
D[i][j] = d[i][j];
}
}
return D;
}
std::vector<std::vector<bool>>
transitive_closure
(const APSPMatrixGraph &g)
{
std::size_t n = g.get_vertexes_size();
std::vector<std::vector<bool>>
T(n, std::vector<bool>(n));
for(std::size_t i = 0; i != n; ++i)
for(std::size_t j = 0; j != n; ++j)
{
if(i == j || g.edge_or_not(i, j))
T[i][j] = true;
else
T[i][j] = false;
}
auto t = T;
for(std::size_t k = 0; k != n; ++k)
{
t = T;
for(std::size_t i = 0; i != n; ++i)
for(std::size_t j = 0; j != n; ++j)
T[i][j] = t[i][j] || (t[i][k] && t[k][j]);
}
return T;
}
}
|
utilities
https://github.com/zero4drift/CLRS%5FCpp%5FImplementations/tree/master/include//chapter-25/all%5Fpairs%5Fshortest%5Fpaths/all%5Fpairs%5Fshortest%5Fpaths%5Futilities.h
matrix_all_pairs_shortest_paths
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#include "chapter-22/vertex_graph/vertex_graph.h"
#include "chapter-25/all_pairs_shortest_paths/all_pairs_shortest_paths_utilities.h"
namespace CLRS
{
std::vector<std::vector<APSPMatrixElement>>
extend_shortest_paths
(const std::vector<std::vector<APSPMatrixElement>> &l,
const std::vector<std::vector<APSPMatrixElement>> &w)
{
std::size_t n = l.size();
auto lr = l;
APSPMatrixElement temp;
for(std::size_t i = 0; i != n; ++i)
for(std::size_t j = 0; j != n; ++j)
for(std::size_t k = 0; k != n; ++k)
{
temp = l[i][k] + w[k][j];
if(temp < lr[i][j])
lr[i][j] = temp;
}
return lr;
}
std::vector<std::vector<APSPMatrixElement>>
faster_all_pairs_shortest_paths
(const std::vector<std::vector<APSPMatrixElement>> &w)
{
std::size_t n = w.size();
auto l = w;
std::size_t m = 1;
while(m < n - 1)
{
l = extend_shortest_paths(l, l);
m *= 2;
}
return l;
}
}
|
johnson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include "chapter-22/linked_list_graph/linked_list_graph.h"
#include "chapter-23/minimum_spanning_tree/mst_utilities.h"
#include "chapter-24/single_source_shortest_paths/bellman_ford/bellman_ford.h"
#include "chapter-24/single_source_shortest_paths/dijkstra/dijkstra.h"
namespace CLRS
{
/*
* TODO: too many initialization work greatly lower efficience.
* Needs improvement.
*/
std::vector<std::vector<int>>
johnson(const LinkedListGraph<SSSPVertexGraph,
SSSPWeightEdgeGraph<SSSPVertexGraph>> &g)
{
std::size_t n = g.get_vertexes_size();
auto vn = SSSPVertexGraph(n);
auto vs = g.get_vertexes();
vs.push_back(vn);
auto es = g.get_edges();
for(std::size_t i = 0; i != n; ++i)
{
es.push_back
(SSSPWeightEdgeGraph<
SSSPVertexGraph>(n, i, 0));
}
auto g1 = LinkedListGraph<
SSSPVertexGraph,
SSSPWeightEdgeGraph<SSSPVertexGraph>>(vs, es);
if(bellman_ford(g1, n) == false)
std::logic_error
("the input graph contains negative-weight cycle");
std::vector<int> vh;
for(std::size_t i = 0; i != n; ++i)
vh.push_back(g1.vertex(i).get_dw());
// create a graph suitable for dijkstra algorithm
std::vector<DijkstraVertexGraph> dvs;
std::vector<WeightEdgeGraph<DijkstraVertexGraph>> des;
for(std::size_t i = 0; i != n; ++i)
dvs.push_back(DijkstraVertexGraph(i));
for(const auto &e : g.get_edges())
des.push_back
(WeightEdgeGraph<DijkstraVertexGraph>
(e.get_first_vertex(),
e.get_second_vertex(),
e.get_weight() +
vh[e.get_first_vertex()] -
vh[e.get_second_vertex()]));
LinkedListGraph<DijkstraVertexGraph,
WeightEdgeGraph<DijkstraVertexGraph>> g2(dvs, des);
std::vector<std::vector<int>> D(n, std::vector<int>(n));
for(std::size_t i = 0; i != n; ++i)
{
dijkstra(g2, i);
for(std::size_t j = 0; j != n; ++j)
D[i][j] = g2.vertex(j).get_dw() + vh[j] - vh[i];
}
return D;
}
}
|