From 13fff24f42f9ce58119a9698a3b5364e2b095e2a Mon Sep 17 00:00:00 2001 From: Aditya Borate <23110065@iitgn.ac.in> Date: Tue, 15 Oct 2024 20:30:54 +0530 Subject: [PATCH] fix: updated number_of_paths algorithm, added more test cases, and set unsigned int as parameter --- graph/number_of_paths.cpp | 77 +++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/graph/number_of_paths.cpp b/graph/number_of_paths.cpp index a09add060..c9b17f116 100644 --- a/graph/number_of_paths.cpp +++ b/graph/number_of_paths.cpp @@ -21,6 +21,33 @@ */ namespace graph { + /** + * @brief Helper function to perform DFS and count the number of paths from node `u` to node `v` + * @param A adjacency matrix representing the graph (1: edge exists, 0: no edge) + * @param u the starting node + * @param v the destination node + * @param n the number of nodes in the graph + * @param visited a vector to keep track of visited nodes in the current DFS path + * @returns the number of paths from node `u` to node `v` + */ + int count_paths_dfs(const std::vector>& A, int u, int v, int n, std::vector& visited) { + if (u == v) { + return 1; // Base case: Reached the destination node + } + + visited[u] = true; // Mark the current node as visited + int path_count = 0; // Count of all paths from `u` to `v` + + for (int i = 0; i < n; i++) { + if (A[u][i] == 1 && !visited[i]) { // Check if there is an edge and the node is not visited + path_count += count_paths_dfs(A, i, v, n, visited); // Recursively explore paths from `i` to `v` + } + } + + visited[u] = false; // Unmark the current node as visited (backtracking) + return path_count; + } + /** * @brief Counts the number of paths from node `u` to node `v` in a directed graph * using Depth First Search (DFS) @@ -31,20 +58,9 @@ namespace graph { * @param n the number of nodes in the graph * @returns the number of paths from node `u` to node `v` */ - int count_paths(const std::vector> &A, int u, int v, int n) { - if (u == v) { - return 1; // Base case: Reached the destination node - } - - int path_count = 0; // Count of all paths from `u` to `v` - - for (int i = 0; i < n; i++) { - if (A[u][i] == 1) { // Check if there is an edge from `u` to `i` - path_count += count_paths(A, i, v, n); // Recursively explore paths from `i` to `v` - } - } - - return path_count; + int count_paths(const std::vector>& A, int u, int v, int n) { + std::vector visited(n, false); // Initialize a visited vector for tracking nodes + return count_paths_dfs(A, u, v, n, visited); } } // namespace graph @@ -55,7 +71,7 @@ namespace graph { */ static void test() { // Test case 1: Simple directed graph with multiple paths - std::vector> graph1 = { + std::vector> graph1 = { {0, 1, 0, 1, 0}, {0, 0, 1, 0, 1}, {0, 0, 0, 0, 1}, @@ -64,10 +80,39 @@ static void test() { }; int n1 = 5, u1 = 0, v1 = 4; assert(graph::count_paths(graph1, u1, v1, n1) == 3); // There are 3 paths from node 0 to 4 + + // Test case 2: No possible path (disconnected graph) + std::vector> graph2 = { + {0, 1, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1}, + {0, 0, 1, 0, 0}, + {0, 0, 0, 0, 0} + }; + int n2 = 5, u2 = 0, v2 = 4; + assert(graph::count_paths(graph2, u2, v2, n2) == 0); // No path from node 0 to 4 + + // Test case 3: Cyclic graph with multiple paths + std::vector> graph3 = { + {0, 1, 0, 0, 0}, + {0, 0, 1, 1, 0}, + {1, 0, 0, 0, 1}, + {0, 0, 1, 0, 1}, + {0, 0, 0, 0, 0} + }; + int n3 = 5, u3 = 0, v3 = 4; + assert(graph::count_paths(graph3, u3, v3, n3) == 3); // There are 3 paths from node 0 to 4 + + // Test case 4: Single node graph (self-loop) + std::vector> graph4 = { + {0} + }; + int n4 = 1, u4 = 0, v4 = 0; + assert(graph::count_paths(graph4, u4, v4, n4) == 1); // There is self-loop, so 1 path from node 0 to 0 + std::cout << "All tests have successfully passed!\n"; } - /** * @brief Main function * @returns 0 on exit