From c53f37ab4334064114691cf571d62e3539ba421c Mon Sep 17 00:00:00 2001 From: Prakhar Bhatnagar <42675093+prakharb10@users.noreply.github.com> Date: Sun, 29 Oct 2023 17:26:31 -0700 Subject: [PATCH] fix `all_simple_paths` (#1015) * fix `min_depth=0` in `all_simple_paths` Fixes #955 * added reno --- ...fix-all-simple-paths-03f4534438d1068d.yaml | 7 +++ src/connectivity/mod.rs | 6 +- .../digraph/test_all_simple_paths.py | 19 +++++++ .../graph/test_all_simple_paths.py | 55 +++++++++++++++++++ 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/fix-all-simple-paths-03f4534438d1068d.yaml diff --git a/releasenotes/notes/fix-all-simple-paths-03f4534438d1068d.yaml b/releasenotes/notes/fix-all-simple-paths-03f4534438d1068d.yaml new file mode 100644 index 000000000..e56393348 --- /dev/null +++ b/releasenotes/notes/fix-all-simple-paths-03f4534438d1068d.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixed the behavior of :func:`~rustworkx.graph_all_simple_paths` and + :func:`~rustworkx.digraph_all_simple_paths` when ``min_depth`` is set to + ``0``. Refer to `#955 `__ for + more information. diff --git a/src/connectivity/mod.rs b/src/connectivity/mod.rs index 11c49c951..ad900535a 100644 --- a/src/connectivity/mod.rs +++ b/src/connectivity/mod.rs @@ -548,8 +548,8 @@ pub fn graph_all_simple_paths( )); } let min_intermediate_nodes: usize = match min_depth { + Some(0) | None => 0, Some(depth) => depth - 2, - None => 0, }; let cutoff_petgraph: Option = cutoff.map(|depth| depth - 2); let result: Vec> = algo::all_simple_paths( @@ -573,7 +573,7 @@ pub fn graph_all_simple_paths( /// :param int to: The node index to find the paths to /// :param int min_depth: The minimum depth of the path to include in the output /// list of paths. By default all paths are included regardless of depth, -/// sett to 0 will behave like the default. +/// setting to 0 will behave like the default. /// :param int cutoff: The maximum depth of path to include in the output list /// of paths. By default includes all paths regardless of depth, setting to /// 0 will behave like default. @@ -602,8 +602,8 @@ pub fn digraph_all_simple_paths( )); } let min_intermediate_nodes: usize = match min_depth { + Some(0) | None => 0, Some(depth) => depth - 2, - None => 0, }; let cutoff_petgraph: Option = cutoff.map(|depth| depth - 2); let result: Vec> = algo::all_simple_paths( diff --git a/tests/rustworkx_tests/digraph/test_all_simple_paths.py b/tests/rustworkx_tests/digraph/test_all_simple_paths.py index c63ea2c41..3ee4ed54b 100644 --- a/tests/rustworkx_tests/digraph/test_all_simple_paths.py +++ b/tests/rustworkx_tests/digraph/test_all_simple_paths.py @@ -53,6 +53,25 @@ def test_all_simple_paths(self): for i in expected: self.assertIn(i, paths) + def test_all_simple_paths_default_min_depth(self): + dag = rustworkx.PyDAG() + for i in range(6): + dag.add_node(i) + dag.add_edges_from_no_data(self.edges) + paths = rustworkx.digraph_all_simple_paths(dag, 0, 5, min_depth=0) + expected = [ + [0, 1, 2, 3, 4, 5], + [0, 1, 2, 4, 5], + [0, 1, 3, 2, 4, 5], + [0, 1, 3, 4, 5], + [0, 2, 3, 4, 5], + [0, 2, 4, 5], + [0, 3, 2, 4, 5], + [0, 3, 4, 5], + ] + for i in expected: + self.assertIn(i, paths) + def test_all_simple_paths_min_depth(self): dag = rustworkx.PyDAG() for i in range(6): diff --git a/tests/rustworkx_tests/graph/test_all_simple_paths.py b/tests/rustworkx_tests/graph/test_all_simple_paths.py index b179be29a..9e0ad998f 100644 --- a/tests/rustworkx_tests/graph/test_all_simple_paths.py +++ b/tests/rustworkx_tests/graph/test_all_simple_paths.py @@ -89,6 +89,61 @@ def test_all_simple_paths(self): for i in expected: self.assertIn(i, paths) + def test_all_simple_paths_default_min_depth(self): + graph = rustworkx.PyGraph() + for i in range(6): + graph.add_node(i) + graph.add_edges_from_no_data(self.edges) + paths = rustworkx.graph_all_simple_paths(graph, 0, 5, min_depth=0) + expected = [ + [0, 3, 4, 5], + [0, 3, 4, 2, 5], + [0, 3, 4, 2, 5], + [0, 3, 2, 4, 5], + [0, 3, 2, 5], + [0, 3, 2, 4, 5], + [0, 3, 5], + [0, 3, 2, 4, 5], + [0, 3, 2, 5], + [0, 3, 2, 4, 5], + [0, 3, 1, 2, 4, 5], + [0, 3, 1, 2, 5], + [0, 3, 1, 2, 4, 5], + [0, 2, 4, 5], + [0, 2, 4, 3, 5], + [0, 2, 3, 4, 5], + [0, 2, 3, 5], + [0, 2, 5], + [0, 2, 4, 5], + [0, 2, 4, 3, 5], + [0, 2, 3, 4, 5], + [0, 2, 3, 5], + [0, 2, 1, 3, 4, 5], + [0, 2, 1, 3, 5], + [0, 1, 3, 4, 5], + [0, 1, 3, 4, 2, 5], + [0, 1, 3, 4, 2, 5], + [0, 1, 3, 2, 4, 5], + [0, 1, 3, 2, 5], + [0, 1, 3, 2, 4, 5], + [0, 1, 3, 5], + [0, 1, 3, 2, 4, 5], + [0, 1, 3, 2, 5], + [0, 1, 3, 2, 4, 5], + [0, 1, 2, 4, 5], + [0, 1, 2, 4, 3, 5], + [0, 1, 2, 3, 4, 5], + [0, 1, 2, 3, 5], + [0, 1, 2, 5], + [0, 1, 2, 4, 5], + [0, 1, 2, 4, 3, 5], + [0, 1, 2, 3, 4, 5], + [0, 1, 2, 3, 5], + ] + self.assertEqual(len(expected), len(paths)) + for i in expected: + self.assertIn(i, paths) + def test_all_simple_paths_with_min_depth(self): graph = rustworkx.PyGraph() for i in range(6):