Skip to content

Commit 17c374d

Browse files
[feat/docs/fix]: improve the Dijkstra algorithm (TheAlgorithms#2508)
Originally initiated in TheAlgorithms#2490. Co-authored-by: Mark Matthew Vergara <mmvergara@users.noreply.github.com>
1 parent b480ddb commit 17c374d

File tree

1 file changed

+140
-65
lines changed

1 file changed

+140
-65
lines changed

greedy_algorithms/dijkstra.cpp

Lines changed: 140 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,52 @@
1-
#include <limits.h>
2-
#include <iostream>
3-
4-
using namespace std;
5-
6-
// Wrapper class for storing a graph
1+
/**
2+
* @file
3+
* @brief [Dijkstra](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) algorithm
4+
* implementation
5+
* @details
6+
* _Quote from Wikipedia._
7+
*
8+
* **Dijkstra's algorithm** is an algorithm for finding the
9+
* shortest paths between nodes in a weighted graph, which may represent, for
10+
* example, road networks. It was conceived by computer scientist Edsger W.
11+
* Dijkstra in 1956 and published three years later.
12+
*
13+
* @author [David Leal](https://github.com/Panquesito7)
14+
* @author [Arpan Jain](https://github.com/arpanjain97)
15+
*/
16+
17+
#include <cassert> /// for assert
18+
#include <climits> /// for INT_MAX
19+
#include <iostream> /// for IO operations
20+
#include <vector> /// for std::vector
21+
22+
/**
23+
* @namespace
24+
* @brief Greedy Algorithms
25+
*/
26+
namespace greedy_algorithms {
27+
/**
28+
* @brief
29+
*/
30+
/**
31+
* @brief Wrapper class for storing a graph
32+
*/
733
class Graph {
834
public:
9-
int vertexNum;
10-
int **edges;
11-
12-
// Constructs a graph with V vertices and E edges
13-
Graph(const int V) {
14-
// initializes the array edges.
15-
this->edges = new int *[V];
35+
int vertexNum = 0;
36+
std::vector<std::vector<int>> edges{};
37+
38+
/**
39+
* @brief Constructs a graph
40+
* @param V number of vertices of the graph
41+
*/
42+
explicit Graph(const int V) {
43+
// Initialize the array edges
44+
this->edges = std::vector<std::vector<int>>(V, std::vector<int>(V, 0));
1645
for (int i = 0; i < V; i++) {
17-
edges[i] = new int[V];
46+
edges[i] = std::vector<int>(V, 0);
1847
}
1948

20-
// fills the array with zeros.
49+
// Fills the array with zeros
2150
for (int i = 0; i < V; i++) {
2251
for (int j = 0; j < V; j++) {
2352
edges[i][j] = 0;
@@ -27,13 +56,28 @@ class Graph {
2756
this->vertexNum = V;
2857
}
2958

30-
// Adds the given edge to the graph
31-
void addEdge(int src, int dst, int weight) {
59+
/**
60+
* @brief Adds an edge to the graph
61+
* @param src the graph the edge should be added to
62+
* @param dst the position where the edge should be added to
63+
* @param weight the weight of the edge that should be added
64+
* @returns void
65+
*/
66+
void add_edge(int src, int dst, int weight) {
3267
this->edges[src][dst] = weight;
3368
}
3469
};
35-
// Utility function to find minimum distance vertex in mdist
36-
int minDistance(int mdist[], bool vset[], int V) {
70+
71+
/**
72+
* @brief Utility function that finds
73+
* the vertex with the minimum distance in `mdist`.
74+
*
75+
* @param mdist array of distances to each vertex
76+
* @param vset array indicating inclusion in the shortest path tree
77+
* @param V the number of vertices in the graph
78+
* @returns index of the vertex with the minimum distance
79+
*/
80+
int minimum_distance(std::vector<int> mdist, std::vector<bool> vset, int V) {
3781
int minVal = INT_MAX, minInd = 0;
3882
for (int i = 0; i < V; i++) {
3983
if (!vset[i] && (mdist[i] < minVal)) {
@@ -45,37 +89,52 @@ int minDistance(int mdist[], bool vset[], int V) {
4589
return minInd;
4690
}
4791

48-
// Utility function to print distances
49-
void print(int dist[], int V) {
50-
cout << "\nVertex Distance" << endl;
92+
/**
93+
* @brief Utility function to print the distances to vertices.
94+
*
95+
* This function prints the distances to each vertex in a tabular format. If the
96+
* distance is equal to INT_MAX, it is displayed as "INF".
97+
*
98+
* @param dist An array representing the distances to each vertex.
99+
* @param V The number of vertices in the graph.
100+
* @return void
101+
*/
102+
void print(std::vector<int> dist, int V) {
103+
std::cout << "\nVertex Distance\n";
51104
for (int i = 0; i < V; i++) {
52-
if (dist[i] < INT_MAX)
53-
cout << i << "\t" << dist[i] << endl;
54-
else
55-
cout << i << "\tINF" << endl;
105+
if (dist[i] < INT_MAX) {
106+
std::cout << i << "\t" << dist[i] << "\n";
107+
}
108+
else {
109+
std::cout << i << "\tINF" << "\n";
110+
}
56111
}
57112
}
58113

59-
// The main function that finds the shortest path from given source
60-
// to all other vertices using Dijkstra's Algorithm.It doesn't work on negative
61-
// weights
62-
void Dijkstra(Graph graph, int src) {
114+
/**
115+
* @brief The main function that finds the shortest path from given source
116+
* to all other vertices using Dijkstra's Algorithm.
117+
* @note This doesn't work on negative weights.
118+
* @param graph the graph to be processed
119+
* @param src the source of the given vertex
120+
* @returns void
121+
*/
122+
void dijkstra(Graph graph, int src) {
63123
int V = graph.vertexNum;
64-
int mdist[V]; // Stores updated distances to vertex
65-
bool vset[V]; // vset[i] is true if the vertex i included
66-
// in the shortest path tree
124+
std::vector<int> mdist{}; // Stores updated distances to the vertex
125+
std::vector<bool> vset{}; // `vset[i]` is true if the vertex `i` is included in the shortest path tree
67126

68-
// Initialise mdist and vset. Set distance of source as zero
127+
// Initialize `mdist and `vset`. Set distance of source as zero
69128
for (int i = 0; i < V; i++) {
70129
mdist[i] = INT_MAX;
71130
vset[i] = false;
72131
}
73132

74133
mdist[src] = 0;
75134

76-
// iterate to find shortest path
135+
// iterate to find the shortest path
77136
for (int count = 0; count < V - 1; count++) {
78-
int u = minDistance(mdist, vset, V);
137+
int u = minimum_distance(mdist, vset, V);
79138

80139
vset[u] = true;
81140

@@ -89,36 +148,52 @@ void Dijkstra(Graph graph, int src) {
89148

90149
print(mdist, V);
91150
}
151+
} // namespace greedy_algorithms
92152

93-
// Driver Function
94-
int main() {
95-
int V, E, gsrc;
96-
int src, dst, weight;
97-
cout << "Enter number of vertices: ";
98-
cin >> V;
99-
cout << "Enter number of edges: ";
100-
cin >> E;
101-
Graph G(V);
102-
for (int i = 0; i < E; i++) {
103-
cout << "\nEdge " << i + 1 << "\nEnter source: ";
104-
cin >> src;
105-
cout << "Enter destination: ";
106-
cin >> dst;
107-
cout << "Enter weight: ";
108-
cin >> weight;
109-
110-
// makes sure source and destionation are in the proper bounds.
111-
if (src >= 0 && src < V && dst >= 0 && dst < V) {
112-
G.addEdge(src, dst, weight);
113-
} else {
114-
cout << "source and/or destination out of bounds" << endl;
115-
i--;
116-
continue;
117-
}
118-
}
119-
cout << "\nEnter source:";
120-
cin >> gsrc;
121-
Dijkstra(G, gsrc);
153+
/**
154+
* @brief Self-test implementations
155+
* @returns void
156+
*/
157+
static void tests() {
158+
greedy_algorithms::Graph graph(8);
159+
160+
// 1st test.
161+
graph.add_edge(6, 2, 4);
162+
graph.add_edge(2, 6, 4);
122163

164+
assert(graph.edges[6][2] == 4);
165+
166+
// 2nd test.
167+
graph.add_edge(0, 1, 1);
168+
graph.add_edge(1, 0, 1);
169+
170+
assert(graph.edges[0][1] == 1);
171+
172+
// 3rd test.
173+
graph.add_edge(0, 2, 7);
174+
graph.add_edge(2, 0, 7);
175+
graph.add_edge(1, 2, 1);
176+
graph.add_edge(2, 1, 1);
177+
178+
assert(graph.edges[0][2] == 7);
179+
180+
// 4th test.
181+
graph.add_edge(1, 3, 3);
182+
graph.add_edge(3, 1, 3);
183+
graph.add_edge(1, 4, 2);
184+
graph.add_edge(4, 1, 2);
185+
graph.add_edge(2, 3, 2);
186+
187+
assert(graph.edges[1][3] == 3);
188+
189+
std::cout << "All tests have successfully passed!\n";
190+
}
191+
192+
/**
193+
* @brief Main function
194+
* @returns 0 on exit
195+
*/
196+
int main() {
197+
tests(); // run self-test implementations
123198
return 0;
124199
}

0 commit comments

Comments
 (0)