1
+ #include " ../Headers/0003_Graph/0014_AllPairsShortestPathsJohnson.h"
2
+ #include < climits>
3
+ using namespace std ;
4
+
5
+ namespace AllPairsShortestPathsJohnson
6
+ {
7
+ Node::Node (int data)
8
+ {
9
+ this ->data = data;
10
+ this ->distance = INT_MAX;
11
+ this ->parent = nullptr ;
12
+ this ->potentialWeight = 0 ;
13
+ }
14
+
15
+ Edge::Edge (Node* nodeU, Node* nodeV, int weight)
16
+ {
17
+ this ->nodeU = nodeU;
18
+ this ->nodeV = nodeV;
19
+ this ->weight = weight;
20
+ }
21
+
22
+ // Graph Private Member Methods
23
+ Node* Graph::MakeOrFindNode (int data)
24
+ {
25
+ Node* node = nullptr ;
26
+ if (this ->_nodeMap .find (data) == this ->_nodeMap .end ())
27
+ {
28
+ node = new Node (data);
29
+ this ->_nodeMap [data] = node;
30
+ }
31
+ else
32
+ {
33
+ node = this ->_nodeMap [data];
34
+ }
35
+ return node;
36
+ }
37
+
38
+ void Graph::PushAugmentedDirectedEdges (Node* sourceNode, Node* nodeV, int weight)
39
+ {
40
+ this ->_augmentedAdjlist [sourceNode].push_back (nodeV);
41
+ this ->_augmentedEdgeList .push_back (new Edge (sourceNode, nodeV, weight));
42
+ }
43
+
44
+ void Graph::InitializeSingleSource (Node* sourceNode)
45
+ {
46
+ for (auto & iterator : this ->_nodeMap )
47
+ {
48
+ iterator.second ->distance = INT_MAX;
49
+ iterator.second ->parent = nullptr ;
50
+ }
51
+ sourceNode->distance = 0 ;
52
+ }
53
+
54
+ void Graph::RelaxBellmanFord (Edge* edge)
55
+ {
56
+ if (edge->nodeU ->distance != INT_MAX && (edge->nodeV ->distance > (edge->nodeU ->distance + edge->weight )))
57
+ {
58
+ edge->nodeV ->distance = edge->nodeU ->distance + edge->weight ;
59
+ edge->nodeV ->parent = edge->nodeU ;
60
+ }
61
+ }
62
+
63
+ bool Graph::BellmanFord (Node* source)
64
+ {
65
+ this ->InitializeSingleSource (source);
66
+
67
+ for (int i = 0 ; i < this ->_nodeMap .size () - 1 ; i++)
68
+ {
69
+ for (auto & edge : this ->_augmentedEdgeList )
70
+ {
71
+ this ->RelaxBellmanFord (edge);
72
+ }
73
+ }
74
+
75
+ for (auto & edge : this ->_augmentedEdgeList )
76
+ {
77
+ if (edge->nodeV ->distance > (edge->nodeU ->distance + edge->weight ))
78
+ {
79
+ return false ;
80
+ }
81
+ }
82
+ return true ;
83
+ }
84
+
85
+ void Graph::RelaxDijkstra (Edge* edge)
86
+ {
87
+ if (edge->nodeU ->distance != INT_MAX && (edge->nodeV ->distance > (edge->nodeU ->distance + edge->weight )))
88
+ {
89
+ this ->_operationalSet .erase (edge->nodeV );
90
+ edge->nodeV ->distance = edge->nodeU ->distance + edge->weight ;
91
+ edge->nodeV ->parent = edge->nodeU ;
92
+ this ->_operationalSet .insert (edge->nodeV );
93
+ }
94
+ }
95
+
96
+ void Graph::Dijkstra (Node* source)
97
+ {
98
+ this ->InitializeSingleSource (source);
99
+
100
+ for (auto & node : this ->_nodeMap )
101
+ {
102
+ this ->_operationalSet .insert (node.second );
103
+ }
104
+
105
+ while (!this ->_operationalSet .empty ())
106
+ {
107
+ Node* nodeU = *(this ->_operationalSet .begin ());
108
+ this ->_operationalSet .erase (nodeU);
109
+
110
+ for (auto & edge : this ->_edgeMap [nodeU])
111
+ {
112
+ this ->RelaxDijkstra (edge);
113
+ }
114
+ }
115
+ }
116
+
117
+ void Graph::GetShortestPath (int source, int destination, vector<int >& path)
118
+ {
119
+ if (this ->_predecessorMatrix [source - 1 ][destination - 1 ] != source)
120
+ {
121
+ int predecessor = this ->_predecessorMatrix [source - 1 ][destination - 1 ];
122
+ this ->GetShortestPath (source, predecessor, path);
123
+ path.push_back (predecessor);
124
+ }
125
+ }
126
+
127
+ // Graph Public Member Methods
128
+ void Graph::PushDirectedEdge (int dataU, int dataV, int weight)
129
+ {
130
+ Node* nodeU = this ->MakeOrFindNode (dataU);
131
+ Node* nodeV = this ->MakeOrFindNode (dataV);
132
+
133
+ this ->_adjlist [nodeU].push_back (nodeV);
134
+ Edge* edge = new Edge (nodeU, nodeV, weight);
135
+ this ->_edgeMap [nodeU].push_back (edge);
136
+ this ->_edgeList .push_back (edge);
137
+ }
138
+
139
+ bool Graph::FindAllPairsShortestPathsJohnsonAlgorithm ()
140
+ {
141
+ // Creating the graph G'
142
+ this ->_augmentedAdjlist = this ->_adjlist ;
143
+ this ->_augmentedEdgeList = this ->_edgeList ;
144
+ Node* source = new Node (0 );
145
+ this ->_nodeMap [0 ] = source;
146
+ for (auto & node : this ->_nodeMap )
147
+ {
148
+ if (node.second != source)
149
+ {
150
+ this ->PushAugmentedDirectedEdges (source, node.second , 0 );
151
+ }
152
+ }
153
+
154
+ if (this ->BellmanFord (source) == false )
155
+ {
156
+ return false ;
157
+ }
158
+ else
159
+ {
160
+ this ->_nodeMap .erase (0 );
161
+ for (auto & node : this ->_nodeMap )
162
+ {
163
+ node.second ->potentialWeight = node.second ->distance ;
164
+ }
165
+
166
+ for (auto & edge : this ->_edgeList )
167
+ {
168
+ edge->weight = edge->weight + edge->nodeU ->potentialWeight - edge->nodeV ->potentialWeight ;
169
+ }
170
+
171
+ this ->_noOfVertices = (int )this ->_nodeMap .size ();
172
+ this ->_shortestPathMatrix = vector<vector<int >>(this ->_noOfVertices , vector<int >(this ->_noOfVertices , -1 ));
173
+ this ->_predecessorMatrix = vector<vector<int >>(this ->_noOfVertices , vector<int >(this ->_noOfVertices , -1 ));
174
+ for (auto & iteratorU : this ->_nodeMap )
175
+ {
176
+ Node* nodeU = iteratorU.second ;
177
+ this ->Dijkstra (nodeU);
178
+ for (auto & iteratorV : this ->_nodeMap )
179
+ {
180
+ Node* nodeV = iteratorV.second ;
181
+ this ->_shortestPathMatrix [nodeU->data - 1 ][nodeV->data - 1 ] = nodeV->distance + nodeV->potentialWeight - nodeU->potentialWeight ;
182
+ this ->_predecessorMatrix [nodeU->data - 1 ][nodeV->data - 1 ] = nodeV->parent != nullptr ? nodeV->parent ->data : -1 ;
183
+ }
184
+ }
185
+ return true ;
186
+ }
187
+ }
188
+
189
+ vector<vector<int >> Graph::GetAllPairsShortestPathsDistanceMatrix ()
190
+ {
191
+ return this ->_shortestPathMatrix ;
192
+ }
193
+
194
+ vector<vector<int >> Graph::GetAllPairsShortestPathsPathMatrix ()
195
+ {
196
+ vector<vector<int >> result;
197
+ for (int i = 0 ; i < this ->_noOfVertices ; i++)
198
+ {
199
+ for (int j = 0 ; j < this ->_noOfVertices ; j++)
200
+ {
201
+ if (i != j)
202
+ {
203
+ vector<int > path = {};
204
+ path.push_back (i + 1 );
205
+ this ->GetShortestPath (i + 1 , j + 1 , path);
206
+ path.push_back (j + 1 );
207
+ result.push_back (path);
208
+ }
209
+ }
210
+ }
211
+ return result;
212
+ }
213
+ }
0 commit comments