Skip to content

Commit 73bb25b

Browse files
Merge branch 'master' into feature/add-gravity-constant
2 parents 2502f61 + c917fc4 commit 73bb25b

File tree

2 files changed

+152
-1
lines changed

2 files changed

+152
-1
lines changed

graph/number_of_paths.cpp

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
* @file
3+
* @brief Algorithm to count paths between two nodes in a directed graph using DFS
4+
* @details
5+
* This algorithm implements Depth First Search (DFS) to count the number of
6+
* possible paths between two nodes in a directed graph. It is represented using
7+
* an adjacency matrix. The algorithm recursively traverses the graph to find
8+
* all paths from the source node `u` to the destination node `v`.
9+
*
10+
* @author [Aditya Borate](https://github.com/adi776borate)
11+
* @see https://en.wikipedia.org/wiki/Path_(graph_theory)
12+
*/
13+
14+
#include <vector> /// for std::vector
15+
#include <iostream> /// for IO operations
16+
#include <cassert> /// for assert
17+
#include <cstdint> /// for fixed-size integer types (e.g., std::uint32_t)
18+
19+
/**
20+
* @namespace graph
21+
* @brief Graph algorithms
22+
*/
23+
namespace graph {
24+
25+
/**
26+
* @brief Helper function to perform DFS and count the number of paths from node `u` to node `v`
27+
* @param A adjacency matrix representing the graph (1: edge exists, 0: no edge)
28+
* @param u the starting node
29+
* @param v the destination node
30+
* @param n the number of nodes in the graph
31+
* @param visited a vector to keep track of visited nodes in the current DFS path
32+
* @returns the number of paths from node `u` to node `v`
33+
*/
34+
std::uint32_t count_paths_dfs(const std::vector<std::vector<std::uint32_t>>& A,
35+
std::uint32_t u,
36+
std::uint32_t v,
37+
std::uint32_t n,
38+
std::vector<bool>& visited) {
39+
if (u == v) {
40+
return 1; // Base case: Reached the destination node
41+
}
42+
43+
visited[u] = true; // Mark the current node as visited
44+
std::uint32_t path_count = 0; // Count of all paths from `u` to `v`
45+
46+
for (std::uint32_t i = 0; i < n; i++) {
47+
if (A[u][i] == 1 && !visited[i]) { // Check if there is an edge and the node is not visited
48+
path_count += count_paths_dfs(A, i, v, n, visited); // Recursively explore paths from `i` to `v`
49+
}
50+
}
51+
52+
visited[u] = false; // Unmark the current node as visited (backtracking)
53+
return path_count;
54+
}
55+
56+
57+
/**
58+
* @brief Counts the number of paths from node `u` to node `v` in a directed graph
59+
* using Depth First Search (DFS)
60+
*
61+
* @param A adjacency matrix representing the graph (1: edge exists, 0: no edge)
62+
* @param u the starting node
63+
* @param v the destination node
64+
* @param n the number of nodes in the graph
65+
* @returns the number of paths from node `u` to node `v`
66+
*/
67+
std::uint32_t count_paths(const std::vector<std::vector<std::uint32_t>>& A,
68+
std::uint32_t u,
69+
std::uint32_t v,
70+
std::uint32_t n) {
71+
// Check for invalid nodes or empty graph
72+
if (u >= n || v >= n || A.empty() || A[0].empty()) {
73+
return 0; // No valid paths if graph is empty or nodes are out of bounds
74+
}
75+
76+
std::vector<bool> visited(n, false); // Initialize a visited vector for tracking nodes
77+
return count_paths_dfs(A, u, v, n, visited); // Start DFS
78+
}
79+
80+
} // namespace graph
81+
82+
/**
83+
* @brief Self-test implementations
84+
* @returns void
85+
*/
86+
static void test() {
87+
// Test case 1: Simple directed graph with multiple paths
88+
std::vector<std::vector<std::uint32_t>> graph1 = {
89+
{0, 1, 0, 1, 0},
90+
{0, 0, 1, 0, 1},
91+
{0, 0, 0, 0, 1},
92+
{0, 0, 1, 0, 0},
93+
{0, 0, 0, 0, 0}
94+
};
95+
std::uint32_t n1 = 5, u1 = 0, v1 = 4;
96+
assert(graph::count_paths(graph1, u1, v1, n1) == 3); // There are 3 paths from node 0 to 4
97+
98+
// Test case 2: No possible path (disconnected graph)
99+
std::vector<std::vector<std::uint32_t>> graph2 = {
100+
{0, 1, 0, 0, 0},
101+
{0, 0, 0, 0, 0},
102+
{0, 0, 0, 0, 1},
103+
{0, 0, 1, 0, 0},
104+
{0, 0, 0, 0, 0}
105+
};
106+
std::uint32_t n2 = 5, u2 = 0, v2 = 4;
107+
assert(graph::count_paths(graph2, u2, v2, n2) == 0); // No path from node 0 to 4
108+
109+
// Test case 3: Cyclic graph with multiple paths
110+
std::vector<std::vector<std::uint32_t>> graph3 = {
111+
{0, 1, 0, 0, 0},
112+
{0, 0, 1, 1, 0},
113+
{1, 0, 0, 0, 1},
114+
{0, 0, 1, 0, 1},
115+
{0, 0, 0, 0, 0}
116+
};
117+
std::uint32_t n3 = 5, u3 = 0, v3 = 4;
118+
assert(graph::count_paths(graph3, u3, v3, n3) == 3); // There are 3 paths from node 0 to 4
119+
120+
// Test case 4: Single node graph (self-loop)
121+
std::vector<std::vector<std::uint32_t>> graph4 = {
122+
{0}
123+
};
124+
std::uint32_t n4 = 1, u4 = 0, v4 = 0;
125+
assert(graph::count_paths(graph4, u4, v4, n4) == 1); // There is self-loop, so 1 path from node 0 to 0
126+
127+
// Test case 5: Empty graph (no nodes, no paths)
128+
std::vector<std::vector<std::uint32_t>> graph5 = {{}};
129+
int n5 = 0, u5 = 0, v5 = 0;
130+
assert(graph::count_paths(graph5, u5, v5, n5) == 0); // There are no paths in an empty graph
131+
132+
// Test case 6: Invalid nodes (out of bounds)
133+
std::vector<std::vector<std::uint32_t>> graph6 = {
134+
{0, 1, 0},
135+
{0, 0, 1},
136+
{0, 0, 0}
137+
};
138+
int n6 = 3, u6 = 0, v6 = 5; // Node `v` is out of bounds (n = 3, so valid indices are 0, 1, 2)
139+
assert(graph::count_paths(graph6, u6, v6, n6) == 0); // Should return 0 because `v = 5` is invalid
140+
141+
std::cout << "All tests have successfully passed!\n";
142+
}
143+
144+
/**
145+
* @brief Main function
146+
* @returns 0 on exit
147+
*/
148+
int main() {
149+
test(); // Run self-test implementations
150+
return 0;
151+
}

search/hash_search.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ int hash_search(int key, int* counter) { // Hash lookup function
9898
/** main function */
9999
int main() {
100100
link p;
101-
int key, index, i, counter; // Key is the value to be found
101+
int key = 0, index, i, counter; // Key is the value to be found
102102
index = 0;
103103

104104
// You can write the input mode here

0 commit comments

Comments
 (0)