TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
bidirectional_dijkstra.cpp
Go to the documentation of this file.
1
16#include <cassert>
17#include <cstdint>
18#include <iostream>
19#include <limits>
20#include <queue>
21#include <utility>
22#include <vector>
23
24constexpr int64_t INF = std::numeric_limits<int64_t>::max();
25
30namespace graph {
37namespace bidirectional_dijkstra {
46void addEdge(std::vector<std::vector<std::pair<uint64_t, uint64_t>>> *adj1,
47 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> *adj2,
48 uint64_t u, uint64_t v, uint64_t w) {
49 (*adj1)[u - 1].push_back(std::make_pair(v - 1, w));
50 (*adj2)[v - 1].push_back(std::make_pair(u - 1, w));
51 // (*adj)[v - 1].push_back(std::make_pair(u - 1, w));
52}
63 const std::vector<uint64_t> &workset_,
64 const std::vector<std::vector<uint64_t>> &distance_) {
65 int64_t distance = INF;
66 for (uint64_t i : workset_) {
67 if (distance_[0][i] + distance_[1][i] < distance) {
68 distance = distance_[0][i] + distance_[1][i];
69 }
70 }
71 return distance;
72}
73
87int Bidijkstra(std::vector<std::vector<std::pair<uint64_t, uint64_t>>> *adj1,
88 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> *adj2,
89 uint64_t s, uint64_t t) {
91 uint64_t n = adj1->size();
92
94 std::vector<std::vector<uint64_t>> dist(2, std::vector<uint64_t>(n, INF));
95
99
102 std::vector<
103 std::priority_queue<std::pair<uint64_t, uint64_t>,
104 std::vector<std::pair<uint64_t, uint64_t>>,
105 std::greater<std::pair<uint64_t, uint64_t>>>>
106 pq(2);
108 std::vector<uint64_t> workset(n);
110 std::vector<bool> visited(n);
111
113 pq[0].push(std::make_pair(0, s));
114
116 dist[0][s] = 0;
117
119 pq[1].push(std::make_pair(0, t));
120
122 dist[1][t] = 0;
123
124 while (true) {
126
127 // If pq[0].size() is equal to zero then the node/ vertex is not
128 // reachable from s
129 if (pq[0].size() == 0) {
130 break;
131 }
133 uint64_t currentNode = pq[0].top().second;
134
136 uint64_t currentDist = pq[0].top().first;
137
138 pq[0].pop();
139
142 for (std::pair<int, int> edge : (*adj1)[currentNode]) {
144 if (currentDist + edge.second < dist[0][edge.first]) {
145 dist[0][edge.first] = currentDist + edge.second;
146 pq[0].push(std::make_pair(dist[0][edge.first], edge.first));
147 }
148 }
149 // store the processed node/ vertex
150 workset.push_back(currentNode);
151
153 if (visited[currentNode] == 1) {
154 return Shortest_Path_Distance(workset, dist);
155 }
156 visited[currentNode] = true;
158
159 // If pq[1].size() is equal to zero then the node/ vertex is not
160 // reachable from t
161 if (pq[1].size() == 0) {
162 break;
163 }
165 currentNode = pq[1].top().second;
166
168 currentDist = pq[1].top().first;
169
170 pq[1].pop();
171
174 for (std::pair<int, int> edge : (*adj2)[currentNode]) {
176 if (currentDist + edge.second < dist[1][edge.first]) {
177 dist[1][edge.first] = currentDist + edge.second;
178 pq[1].push(std::make_pair(dist[1][edge.first], edge.first));
179 }
180 }
181 // store the processed node/ vertex
182 workset.push_back(currentNode);
183
185 if (visited[currentNode] == 1) {
186 return Shortest_Path_Distance(workset, dist);
187 }
188 visited[currentNode] = true;
189 }
190 return -1;
191}
192} // namespace bidirectional_dijkstra
193} // namespace graph
194
200static void tests() {
201 std::cout << "Initiatinig Predefined Tests..." << std::endl;
202 std::cout << "Initiating Test 1..." << std::endl;
203 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> adj1_1(
204 4, std::vector<std::pair<uint64_t, uint64_t>>());
205 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> adj1_2(
206 4, std::vector<std::pair<uint64_t, uint64_t>>());
207 graph::bidirectional_dijkstra::addEdge(&adj1_1, &adj1_2, 1, 2, 1);
208 graph::bidirectional_dijkstra::addEdge(&adj1_1, &adj1_2, 4, 1, 2);
209 graph::bidirectional_dijkstra::addEdge(&adj1_1, &adj1_2, 2, 3, 2);
210 graph::bidirectional_dijkstra::addEdge(&adj1_1, &adj1_2, 1, 3, 5);
211
212 uint64_t s = 1, t = 3;
213 assert(graph::bidirectional_dijkstra::Bidijkstra(&adj1_1, &adj1_2, s - 1,
214 t - 1) == 3);
215 std::cout << "Test 1 Passed..." << std::endl;
216
217 s = 4, t = 3;
218 std::cout << "Initiating Test 2..." << std::endl;
219 assert(graph::bidirectional_dijkstra::Bidijkstra(&adj1_1, &adj1_2, s - 1,
220 t - 1) == 5);
221 std::cout << "Test 2 Passed..." << std::endl;
222
223 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> adj2_1(
224 5, std::vector<std::pair<uint64_t, uint64_t>>());
225 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> adj2_2(
226 5, std::vector<std::pair<uint64_t, uint64_t>>());
227 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 1, 2, 4);
228 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 1, 3, 2);
229 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 2, 3, 2);
230 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 3, 2, 1);
231 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 2, 4, 2);
232 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 3, 5, 4);
233 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 5, 4, 1);
234 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 2, 5, 3);
235 graph::bidirectional_dijkstra::addEdge(&adj2_1, &adj2_2, 3, 4, 4);
236
237 s = 1, t = 5;
238 std::cout << "Initiating Test 3..." << std::endl;
239 assert(graph::bidirectional_dijkstra::Bidijkstra(&adj2_1, &adj2_2, s - 1,
240 t - 1) == 6);
241 std::cout << "Test 3 Passed..." << std::endl;
242 std::cout << "All Test Passed..." << std::endl << std::endl;
243}
244
249int main() {
250 tests(); // running predefined tests
251 uint64_t vertices = uint64_t();
252 uint64_t edges = uint64_t();
253 std::cout << "Enter the number of vertices : ";
254 std::cin >> vertices;
255 std::cout << "Enter the number of edges : ";
256 std::cin >> edges;
257
258 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> adj1(
259 vertices, std::vector<std::pair<uint64_t, uint64_t>>());
260 std::vector<std::vector<std::pair<uint64_t, uint64_t>>> adj2(
261 vertices, std::vector<std::pair<uint64_t, uint64_t>>());
262
263 uint64_t u = uint64_t(), v = uint64_t(), w = uint64_t();
264 std::cout << "Enter the edges by three integers in this form: u v w "
265 << std::endl;
266 std::cout << "Example: if there is and edge between node 1 and node 4 with "
267 "weight 7 enter: 1 4 7, and then press enter"
268 << std::endl;
269 while (edges--) {
270 std::cin >> u >> v >> w;
271 graph::bidirectional_dijkstra::addEdge(&adj1, &adj2, u, v, w);
272 if (edges != 0) {
273 std::cout << "Enter the next edge" << std::endl;
274 }
275 }
276
277 uint64_t s = uint64_t(), t = uint64_t();
278 std::cout
279 << "Enter the source node and the target node separated by a space"
280 << std::endl;
281 std::cout << "Example: If the source node is 5 and the target node is 6 "
282 "enter: 5 6 and press enter"
283 << std::endl;
284 std::cin >> s >> t;
285 int dist =
286 graph::bidirectional_dijkstra::Bidijkstra(&adj1, &adj2, s - 1, t - 1);
287 if (dist == -1) {
288 std::cout << "Target not reachable from source" << std::endl;
289 } else {
290 std::cout << "Shortest Path Distance : " << dist << std::endl;
291 }
292
293 return 0;
294}
int Bidijkstra(std::vector< std::vector< std::pair< uint64_t, uint64_t > > > *adj1, std::vector< std::vector< std::pair< uint64_t, uint64_t > > > *adj2, uint64_t s, uint64_t t)
Function runs the dijkstra algorithm for some source vertex and target vertex in the graph and return...
uint64_t Shortest_Path_Distance(const std::vector< uint64_t > &workset_, const std::vector< std::vector< uint64_t > > &distance_)
This function returns the shortest distance from the source to the target if there is path between ve...
constexpr int64_t INF
for assert
static void tests()
Function to test the provided algorithm above.
void addEdge(std::vector< std::vector< std::pair< uint64_t, uint64_t > > > *adj1, std::vector< std::vector< std::pair< uint64_t, uint64_t > > > *adj2, uint64_t u, uint64_t v, uint64_t w)
Function that add edge between two nodes or vertices of graph.
int main()
Main function.
Functions for [Bidirectional Dijkstra Shortest Path] (https://www.coursera.org/learn/algorithms-on-gr...
Graph Algorithms.