From 3dc0d51327cc7a79171c57876be1f74dd8d6c3b9 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 15 Oct 2023 10:12:51 -0400 Subject: [PATCH] Ramp up deprecation of retworkx package and remove tests Since it's been > 1 year since we renamed retworkx to rustworkx, this commit starts actively emitting `DeprecationWarning`s for importing retworkx. Previously we had only documented the name as being deprecated, however we still ~54k downloads per month. The warning should hopefully encourage more people to move to the new name. While we prepare to drop support for the retworkx name in the lead up to rustworkx 1.0 eventually (see #1000) this commit also prepares us to stop publishing updates in the future. Besides removing the warning it decreases the prominence of the rename warning from the rustworkx package documentation. This commit also remove the retworkx legacy tests from the test suite as we've been running them for > 1 year now and have not enountered any issues with the import redirect. The benefits of keeping around a duplicated test suite for validating the redirects has outlived it's usefulness, and is just wasted CPU resources (both locally and more importantly in CI). As for the final step of the retworkx name, to eventually drop support for the legacy name, a comment is added to the setup.py about how we make that migration. For the final 0.X release of rustworkx we should change the `rustworkx==` pin in retworkx's setup.py to `rustworkx<1`. We do have the option to do this at anytime because the retworkx package source code is basically frozen and just redirecting imports from retworkx to rustworkx. However, if the retworkx package wasn't pinned to a fixed version then current users would potentially get a different experience when installing the same version of the retworkx package (i.e. if a user installed retworkx 0.14.0 tomorrow and then again 6 months later they could be using different rustworkx versions and encounter different API bugs or deprecation warnings). --- .github/workflows/main.yml | 41 - README.md | 8 +- docs/source/index.rst | 12 +- docs/source/install.rst | 2 +- retworkx/__init__.py | 7 + setup.py | 1 + tests/retworkx_backwards_compat/__init__.py | 0 .../digraph/__init__.py | 0 .../digraph/test_adj.py | 102 -- .../digraph/test_adjacency_matrix.py | 264 --- .../digraph/test_all_simple_paths.py | 307 ---- .../digraph/test_ancestors_descendants.py | 64 - .../digraph/test_astar.py | 114 -- .../digraph/test_avg_shortest_path.py | 169 -- .../digraph/test_bellman_ford.py | 438 ----- .../digraph/test_bfs_search.py | 162 -- .../digraph/test_cartesian_product.py | 60 - .../digraph/test_centrality.py | 162 -- .../digraph/test_collect_bicolor_runs.py | 350 ---- .../digraph/test_collect_runs.py | 138 -- .../digraph/test_complement.py | 68 - .../digraph/test_compose.py | 95 - .../digraph/test_contract_nodes.py | 265 --- .../digraph/test_copy.py | 55 - .../digraph/test_core_number.py | 96 - .../digraph/test_deepcopy.py | 48 - .../digraph/test_depth.py | 297 ---- .../digraph/test_dfs_edges.py | 31 - .../digraph/test_dfs_search.py | 106 -- .../digraph/test_dijkstra.py | 313 ---- .../digraph/test_dijkstra_search.py | 189 -- .../digraph/test_dist_matrix.py | 140 -- .../digraph/test_dot.py | 73 - .../digraph/test_edgelist.py | 213 --- .../digraph/test_edges.py | 938 ---------- .../digraph/test_find_cycle.py | 72 - .../digraph/test_floyd_warshall.py | 294 ---- .../digraph/test_graph_attrs.py | 31 - .../digraph/test_isomorphic.py | 350 ---- .../digraph/test_k_shortest_path.py | 96 - .../digraph/test_layers.py | 65 - .../digraph/test_layout.py | 477 ----- .../digraph/test_neighbors.py | 59 - .../digraph/test_nodes.py | 403 ----- .../digraph/test_num_shortest_path.py | 140 -- .../digraph/test_pred_succ.py | 385 ---- .../digraph/test_spring_layout.py | 73 - .../digraph/test_strongly_connected.py | 67 - .../digraph/test_subgraph.py | 150 -- .../digraph/test_subgraph_isomorphic.py | 266 --- .../test_substitute_node_with_subgraph.py | 163 -- .../digraph/test_symmetric.py | 39 - .../digraph/test_tensor_product.py | 110 -- .../digraph/test_to_undirected.py | 66 - .../digraph/test_toposort.py | 84 - .../digraph/test_transitivity.py | 43 - .../digraph/test_union.py | 105 -- .../digraph/test_weakly_connected.py | 81 - .../generators/__init__.py | 0 .../generators/test_barbell.py | 57 - .../generators/test_binomial_tree.py | 195 -- .../generators/test_cycle.py | 71 - .../generators/test_full_rary_tree.py | 89 - .../generators/test_grid.py | 131 -- .../generators/test_heavy_hex.py | 424 ----- .../generators/test_heavy_square.py | 503 ------ .../generators/test_hexagonal.py | 417 ----- .../generators/test_lollipop.py | 79 - .../generators/test_mesh.py | 67 - .../generators/test_path.py | 71 - .../generators/test_petersen.py | 56 - .../generators/test_star.py | 108 -- .../graph/__init__.py | 0 .../graph/test_adj.py | 32 - .../graph/test_adjencency_matrix.py | 262 --- .../graph/test_all_simple_paths.py | 245 --- .../graph/test_astar.py | 114 -- .../graph/test_avg_shortest_path.py | 89 - .../graph/test_bellman_ford.py | 308 ---- .../graph/test_bfs_search.py | 162 -- .../graph/test_biconnected.py | 138 -- .../graph/test_cartesian_product.py | 60 - .../graph/test_centrality.py | 133 -- .../graph/test_chain_decomposition.py | 89 - .../graph/test_coloring.py | 46 - .../graph/test_complement.py | 83 - .../graph/test_compose.py | 97 - .../graph/test_connected_components.py | 88 - .../graph/test_contract_nodes.py | 242 --- .../graph/test_copy.py | 55 - .../graph/test_core_number.py | 96 - .../graph/test_cycle_basis.py | 69 - .../graph/test_deepcopy.py | 50 - .../graph/test_dfs_edges.py | 31 - .../graph/test_dfs_search.py | 106 -- .../graph/test_dijkstra.py | 238 --- .../graph/test_dijkstra_search.py | 189 -- .../graph/test_dist_matrix.py | 102 -- .../graph/test_dot.py | 130 -- .../graph/test_edgelist.py | 209 --- .../graph/test_edges.py | 819 --------- .../graph/test_floyd_warshall.py | 201 --- .../graph/test_graph_attrs.py | 31 - .../graph/test_isomorphic.py | 313 ---- .../graph/test_k_shortest_path.py | 75 - .../graph/test_layout.py | 477 ----- .../graph/test_matching.py | 56 - .../graph/test_max_weight_matching.py | 569 ------ .../graph/test_mst.py | 122 -- .../graph/test_neighbors.py | 43 - .../graph/test_nodes.py | 181 -- .../graph/test_num_shortest_path.py | 138 -- .../graph/test_spring_layout.py | 73 - .../graph/test_steiner_tree.py | 188 -- .../graph/test_subgraph.py | 150 -- .../graph/test_subgraph_isomorphic.py | 296 ---- .../graph/test_tensor_product.py | 112 -- .../graph/test_to_directed.py | 79 - .../graph/test_transitivity.py | 49 - .../graph/test_union.py | 74 - .../test_converters.py | 117 -- .../test_custom_return_types.py | 1561 ----------------- .../test_dispatch.py | 111 -- .../retworkx_backwards_compat/test_graphml.py | 512 ------ .../retworkx_backwards_compat/test_random.py | 222 --- .../visualization/__init__.py | 0 .../visualization/test_graphviz.py | 152 -- .../visualization/test_mpl.py | 194 -- 128 files changed, 17 insertions(+), 21576 deletions(-) delete mode 100644 tests/retworkx_backwards_compat/__init__.py delete mode 100644 tests/retworkx_backwards_compat/digraph/__init__.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_adj.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_adjacency_matrix.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_all_simple_paths.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_ancestors_descendants.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_astar.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_avg_shortest_path.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_bellman_ford.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_bfs_search.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_cartesian_product.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_centrality.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_collect_bicolor_runs.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_collect_runs.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_complement.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_compose.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_contract_nodes.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_copy.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_core_number.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_deepcopy.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_depth.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_dfs_edges.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_dfs_search.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_dijkstra.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_dijkstra_search.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_dist_matrix.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_dot.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_edgelist.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_edges.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_find_cycle.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_floyd_warshall.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_graph_attrs.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_isomorphic.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_k_shortest_path.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_layers.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_layout.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_neighbors.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_nodes.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_num_shortest_path.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_pred_succ.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_spring_layout.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_strongly_connected.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_subgraph.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_subgraph_isomorphic.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_substitute_node_with_subgraph.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_symmetric.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_tensor_product.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_to_undirected.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_toposort.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_transitivity.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_union.py delete mode 100644 tests/retworkx_backwards_compat/digraph/test_weakly_connected.py delete mode 100644 tests/retworkx_backwards_compat/generators/__init__.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_barbell.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_binomial_tree.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_cycle.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_full_rary_tree.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_grid.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_heavy_hex.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_heavy_square.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_hexagonal.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_lollipop.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_mesh.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_path.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_petersen.py delete mode 100644 tests/retworkx_backwards_compat/generators/test_star.py delete mode 100644 tests/retworkx_backwards_compat/graph/__init__.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_adj.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_adjencency_matrix.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_all_simple_paths.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_astar.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_avg_shortest_path.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_bellman_ford.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_bfs_search.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_biconnected.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_cartesian_product.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_centrality.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_chain_decomposition.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_coloring.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_complement.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_compose.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_connected_components.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_contract_nodes.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_copy.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_core_number.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_cycle_basis.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_deepcopy.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_dfs_edges.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_dfs_search.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_dijkstra.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_dijkstra_search.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_dist_matrix.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_dot.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_edgelist.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_edges.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_floyd_warshall.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_graph_attrs.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_isomorphic.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_k_shortest_path.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_layout.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_matching.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_max_weight_matching.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_mst.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_neighbors.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_nodes.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_num_shortest_path.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_spring_layout.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_steiner_tree.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_subgraph.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_subgraph_isomorphic.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_tensor_product.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_to_directed.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_transitivity.py delete mode 100644 tests/retworkx_backwards_compat/graph/test_union.py delete mode 100644 tests/retworkx_backwards_compat/test_converters.py delete mode 100644 tests/retworkx_backwards_compat/test_custom_return_types.py delete mode 100644 tests/retworkx_backwards_compat/test_dispatch.py delete mode 100644 tests/retworkx_backwards_compat/test_graphml.py delete mode 100644 tests/retworkx_backwards_compat/test_random.py delete mode 100644 tests/retworkx_backwards_compat/visualization/__init__.py delete mode 100644 tests/retworkx_backwards_compat/visualization/test_graphviz.py delete mode 100644 tests/retworkx_backwards_compat/visualization/test_mpl.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b03b7a8e73..b55878ce45 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -110,47 +110,6 @@ jobs: run: python -m pip install --upgrade tox - name: 'Run rustworkx stub tests' run: tox -estubs - tests_retworkx_compat: - if: github.repository_owner == 'Qiskit' - needs: [build_lint] - name: python${{ matrix.python-version }}-${{ matrix.platform.python-architecture }} ${{ matrix.platform.os }} ${{ matrix.msrv }} - runs-on: ${{ matrix.platform.os }} - strategy: - matrix: - rust: [stable] - python-version: ["3.10"] - platform: [ - { os: "macOS-latest", python-architecture: "x64", rust-target: "x86_64-apple-darwin" }, - { os: "ubuntu-latest", python-architecture: "x64", rust-target: "x86_64-unknown-linux-gnu" }, - { os: "windows-latest", python-architecture: "x64", rust-target: "x86_64-pc-windows-msvc" }, - ] - steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - architecture: ${{ matrix.platform.python-architecture }} - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - targets: ${{ matrix.platform.rust-target }} - - name: 'Install binary dependencies' - run: sudo apt-get install -y graphviz - if: runner.os == 'Linux' - - name: 'Build rustworkx and test dependencies' - run: | - pip install -c constraints.txt -U '.[mpl,graphviz]' fixtures testtools>=2.5.0 networkx>=2.5 stestr>=4.1 - - name: 'Build retworkx' - env: - RUSTWORKX_PKG_NAME: "retworkx" - run: | - pip install -c constraints.txt -U . - - name: 'Run retworkx tests' - run: | - cd tests - stestr run -t ./retworkx_backwards_compat coverage: if: github.repository_owner == 'Qiskit' needs: [tests] diff --git a/README.md b/README.md index 417e4ff29c..5542b86af0 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,7 @@ [![Zenodo](https://img.shields.io/badge/Zenodo-10.5281%2Fzenodo.5879859-blue)](https://doi.org/10.5281/zenodo.5879859) - You can see the full rendered docs at: - - -|:warning:| The retworkx project has been renamed to **rustworkx**. The use of the -retworkx package will still work for the time being but starting in the 1.0.0 -release retworkx will no longer be supported + rustworkx is a general purpose graph library for Python written in Rust to take advantage of the performance and safety that Rust provides. It is @@ -27,7 +23,7 @@ any Python application. Rustworkx was originally called retworkx and was created initially to be a replacement for [qiskit](https://qiskit.org/)'s previous (and current) -networkx usage (hence the original name). The project was originally started +NetworkX usage (hence the original name). The project was originally started to build a faster directed graph to use as the underlying data structure for the DAG at the center of [qiskit-terra](https://github.com/Qiskit/qiskit-terra/)'s transpiler. However, diff --git a/docs/source/index.rst b/docs/source/index.rst index 26ec65d001..6e5ac96ac1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -2,12 +2,6 @@ rustworkx Documentation ####################### -.. note:: - - The project has been renamed to **rustworkx**. You can still use the legacy - retworkx name for now but starting in the 1.0.0 release the retworkx name - will no longer be supported. - rustworkx is a Python package for working with graphs and complex networks. It enables the creation, interaction with, and study of graphs and networks. @@ -57,6 +51,12 @@ https://docs.rs/rustworkx-core/0.13.0/rustworkx_core/ Project history --------------- +.. note:: + + The project has been renamed to **rustworkx**. You can still use the legacy + retworkx name for now but starting in the 1.0.0 release the retworkx name + will no longer be supported. + rustworkx was originally called retworkx and was created to be a high performance replacement for the Qiskit project's internal usage of the `NetworkX `__ library (which is where the name came diff --git a/docs/source/install.rst b/docs/source/install.rst index 61c854f94d..f55bcb711b 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -59,7 +59,7 @@ limitations in available testing resources and platform availability, not all platforms can be supported. Platform support for rustworkx is broken into 4 tiers with different levels of support for each tier. For platforms outside these, rustworkx is probably still installable, but it’s not tested and you will -need a Rust compiler and have to build retworkx (and likely Numpy too) from +need a Rust compiler and have to build rustworkx (and likely Numpy too) from source. .. list-table:: Platform Support diff --git a/retworkx/__init__.py b/retworkx/__init__.py index 8113d76169..fc2bedb395 100644 --- a/retworkx/__init__.py +++ b/retworkx/__init__.py @@ -10,11 +10,18 @@ import sys +import warnings from rustworkx import * # noqa from . import namespace +warnings.warn( + "The retworkx package is deprecated and has been renamed to rustworkx. Rustworkx is a " + "drop-in replacement and can be used by replacing `import retworkx` with import `rustworkx`. " + DeprecationWarning, + stacklevel=2, +) sys.modules["retworkx.generators"] = generators # noqa new_meta_path_finder = namespace.RetworkxImport("retworkx", "rustworkx") diff --git a/setup.py b/setup.py index e734d8be12..f9ba664544 100644 --- a/setup.py +++ b/setup.py @@ -46,6 +46,7 @@ def readme(): if PKG_NAME == "retworkx": README = retworkx_readme_compat + README PKG_PACKAGES = ["retworkx"] + # TODO: For final retworkx release change this to < 1. PKG_INSTALL_REQUIRES.append(f"rustworkx=={PKG_VERSION}") RUST_EXTENSIONS = [] diff --git a/tests/retworkx_backwards_compat/__init__.py b/tests/retworkx_backwards_compat/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/retworkx_backwards_compat/digraph/__init__.py b/tests/retworkx_backwards_compat/digraph/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/retworkx_backwards_compat/digraph/test_adj.py b/tests/retworkx_backwards_compat/digraph/test_adj.py deleted file mode 100644 index e09a008729..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_adj.py +++ /dev/null @@ -1,102 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAdj(unittest.TestCase): - def test_single_neighbor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - res = dag.adj(node_a) - self.assertEqual({node_b: {"a": 1}, node_c: {"a": 2}}, res) - - def test_in_and_out_adj_neighbor(self): - dag = retworkx.PyDAG() - dag.extend_from_weighted_edge_list([(0, 1, "a"), (1, 2, "b")]) - res = dag.adj(1) - self.assertEqual({0: "a", 2: "b"}, res) - - def test_single_neighbor_dir(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - res = dag.adj_direction(node_a, False) - self.assertEqual({node_b: {"a": 1}, node_c: {"a": 2}}, res) - res = dag.adj_direction(node_a, True) - self.assertEqual({}, res) - - def test_neighbor_dir_surrounded(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - res = dag.adj_direction(node_b, False) - self.assertEqual({node_c: {"a": 2}}, res) - res = dag.adj_direction(node_b, True) - self.assertEqual({node_a: {"a": 1}}, res) - - def test_single_neighbor_dir_out_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - res = dag.out_edges(node_a) - self.assertEqual([(node_a, node_c, {"a": 2}), (node_a, node_b, {"a": 1})], res) - - def test_neighbor_dir_surrounded_in_out_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - res = dag.out_edges(node_b) - self.assertEqual([(node_b, node_c, {"a": 2})], res) - res = dag.in_edges(node_b) - self.assertEqual([(node_a, node_b, {"a": 1})], res) - - def test_no_neighbor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - self.assertEqual({}, dag.adj(node_a)) - - def test_in_direction(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(5): - dag.add_parent(node_a, i, None) - self.assertEqual(5, dag.in_degree(node_a)) - - def test_in_direction_none(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(5): - dag.add_child(node_a, i, None) - self.assertEqual(0, dag.in_degree(node_a)) - - def test_out_direction(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(5): - dag.add_parent(node_a, i, None) - self.assertEqual(0, dag.out_degree(node_a)) - - def test_out_direction_none(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(5): - dag.add_child(node_a, i, None) - self.assertEqual(5, dag.out_degree(node_a)) diff --git a/tests/retworkx_backwards_compat/digraph/test_adjacency_matrix.py b/tests/retworkx_backwards_compat/digraph/test_adjacency_matrix.py deleted file mode 100644 index e62535f565..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_adjacency_matrix.py +++ /dev/null @@ -1,264 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx -import numpy as np - - -class TestDAGAdjacencyMatrix(unittest.TestCase): - def test_single_neighbor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - dag.add_child(node_a, "c", {"a": 2}) - res = retworkx.digraph_adjacency_matrix(dag, lambda x: 1) - self.assertIsInstance(res, np.ndarray) - self.assertTrue( - np.array_equal( - np.array( - [[0.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], - dtype=np.float64, - ), - res, - ) - ) - - def test_no_weight_fn(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - dag.add_child(node_a, "c", {"a": 2}) - res = retworkx.digraph_adjacency_matrix(dag) - self.assertIsInstance(res, np.ndarray) - self.assertTrue( - np.array_equal( - np.array( - [[0.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], - dtype=np.float64, - ), - res, - ) - ) - - def test_default_weight(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - dag.add_child(node_a, "c", {"a": 2}) - res = retworkx.digraph_adjacency_matrix(dag, default_weight=4) - self.assertIsInstance(res, np.ndarray) - self.assertTrue( - np.array_equal( - np.array( - [[0.0, 4.0, 4.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], - dtype=np.float64, - ), - res, - ) - ) - - def test_float_cast_weight_func(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", 7.0) - res = retworkx.digraph_adjacency_matrix(dag, lambda x: float(x)) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[0.0, 7.0], [0.0, 0.0]]), res)) - - def test_multigraph_sum_cast_weight_func(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 7.0) - dag.add_edge(node_a, node_b, 0.5) - res = retworkx.digraph_adjacency_matrix(dag, lambda x: float(x)) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[0.0, 7.5], [0.0, 0.0]]), res)) - - def test_multigraph_sum_cast_weight_func_non_zero_null(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, 7.0) - graph.add_edge(node_a, node_b, 0.5) - res = retworkx.adjacency_matrix(graph, lambda x: float(x), null_value=np.inf) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[np.inf, 7.5], [np.inf, np.inf]]), res)) - - def test_graph_to_digraph_adjacency_matrix(self): - graph = retworkx.PyGraph() - self.assertRaises(TypeError, retworkx.digraph_adjacency_matrix, graph) - - def test_no_edge_digraph_adjacency_matrix(self): - dag = retworkx.PyDAG() - for i in range(50): - dag.add_node(i) - res = retworkx.digraph_adjacency_matrix(dag, lambda x: 1) - self.assertTrue(np.array_equal(np.zeros([50, 50]), res)) - - def test_digraph_with_index_holes(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 1) - dag.add_child(node_a, "c", 1) - dag.remove_node(node_b) - res = retworkx.digraph_adjacency_matrix(dag, lambda x: 1) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[0, 1], [0, 0]]), res)) - - def test_from_adjacency_matrix(self): - input_array = np.array( - [[0.0, 4.0, 0.0], [4.0, 0.0, 4.0], [0.0, 4.0, 0.0]], - dtype=np.float64, - ) - graph = retworkx.PyDiGraph.from_adjacency_matrix(input_array) - out_array = retworkx.digraph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(input_array, out_array)) - - def test_random_graph_full_path(self): - graph = retworkx.directed_gnp_random_graph(100, 0.95, seed=42) - adjacency_matrix = retworkx.digraph_adjacency_matrix(graph) - new_graph = retworkx.PyDiGraph.from_adjacency_matrix(adjacency_matrix) - new_adjacency_matrix = retworkx.digraph_adjacency_matrix(new_graph) - self.assertTrue(np.array_equal(adjacency_matrix, new_adjacency_matrix)) - - def test_random_graph_different_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - with self.assertRaises(TypeError): - retworkx.PyDiGraph.from_adjacency_matrix(input_matrix) - - def test_random_graph_different_dtype_astype_no_copy(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - graph = retworkx.PyDiGraph.from_adjacency_matrix( - input_matrix.astype(np.float64, copy=False) - ) - adj_matrix = retworkx.digraph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(adj_matrix, input_matrix)) - - def test_random_graph_float_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=float) - graph = retworkx.PyDiGraph.from_adjacency_matrix(input_matrix) - adj_matrix = retworkx.digraph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(adj_matrix, input_matrix)) - - def test_non_zero_null(self): - input_matrix = np.array( - [[np.Inf, 1, np.Inf], [1, np.Inf, 1], [np.Inf, 1, np.Inf]], - dtype=np.float64, - ) - graph = retworkx.PyDiGraph.from_adjacency_matrix(input_matrix, null_value=np.Inf) - adj_matrix = retworkx.adjacency_matrix(graph, float) - expected_matrix = np.array( - [[0.0, 1.0, 0.0], [1.0, 0.0, 1.0], [0.0, 1.0, 0.0]], - dtype=np.float64, - ) - self.assertTrue(np.array_equal(adj_matrix, expected_matrix)) - - def test_negative_weight(self): - input_matrix = np.array([[0, 1, 0], [-1, 0, -1], [0, 1, 0]], dtype=float) - graph = retworkx.PyDiGraph.from_adjacency_matrix(input_matrix) - adj_matrix = retworkx.digraph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(adj_matrix, input_matrix)) - self.assertEqual( - [(0, 1, 1), (1, 0, -1), (1, 2, -1), (2, 1, 1)], - graph.weighted_edge_list(), - ) - - def test_nan_null(self): - input_matrix = np.array( - [[np.nan, 1, np.nan], [1, np.nan, 1], [np.nan, 1, np.nan]], - dtype=np.float64, - ) - graph = retworkx.PyDiGraph.from_adjacency_matrix(input_matrix, null_value=np.nan) - adj_matrix = retworkx.adjacency_matrix(graph, float) - expected_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.float64) - self.assertTrue(np.array_equal(adj_matrix, expected_matrix)) - - -class TestFromComplexAdjacencyMatrix(unittest.TestCase): - def test_from_adjacency_matrix(self): - input_array = np.array( - [[0.0, 4.0, 0.0], [4.0, 0.0, 4.0], [0.0, 4.0, 0.0]], - dtype=np.complex128, - ) - graph = retworkx.PyDiGraph.from_complex_adjacency_matrix(input_array) - expected = [ - (0, 1, 4 + 0j), - (1, 0, 4 + 0j), - (1, 2, 4 + 0j), - (2, 1, 4 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_random_graph_different_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - with self.assertRaises(TypeError): - retworkx.PyDiGraph.from_complex_adjacency_matrix(input_matrix) - - def test_random_graph_different_dtype_astype_no_copy(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - graph = retworkx.PyDiGraph.from_complex_adjacency_matrix( - input_matrix.astype(np.complex128, copy=False) - ) - expected = [ - (0, 1, 1 + 0j), - (1, 0, 1 + 0j), - (1, 2, 1 + 0j), - (2, 1, 1 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_random_graph_complex_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=complex) - graph = retworkx.PyDiGraph.from_complex_adjacency_matrix(input_matrix) - expected = [ - (0, 1, 1 + 0j), - (1, 0, 1 + 0j), - (1, 2, 1 + 0j), - (2, 1, 1 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_non_zero_null(self): - input_matrix = np.array( - [[np.Inf, 1, np.Inf], [1, np.Inf, 1], [np.Inf, 1, np.Inf]], - dtype=np.complex128, - ) - graph = retworkx.PyDiGraph.from_complex_adjacency_matrix(input_matrix, null_value=np.Inf) - expected = [ - (0, 1, 1 + 0j), - (1, 0, 1 + 0j), - (1, 2, 1 + 0j), - (2, 1, 1 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_negative_weight(self): - input_matrix = np.array([[0, 1, 0], [-1, 0, -1], [0, 1, 0]], dtype=complex) - graph = retworkx.PyDiGraph.from_complex_adjacency_matrix(input_matrix) - self.assertEqual( - [(0, 1, 1), (1, 0, -1), (1, 2, -1), (2, 1, 1)], - graph.weighted_edge_list(), - ) - - def test_nan_null(self): - input_matrix = np.array( - [[np.nan, 1, np.nan], [1, np.nan, 1], [np.nan, 1, np.nan]], - dtype=np.complex128, - ) - graph = retworkx.PyDiGraph.from_complex_adjacency_matrix(input_matrix, null_value=np.nan) - edge_list = graph.weighted_edge_list() - self.assertEqual( - edge_list, - [(0, 1, 1 + 0j), (1, 0, 1 + 0j), (1, 2, 1 + 0j), (2, 1, 1 + 0j)], - ) diff --git a/tests/retworkx_backwards_compat/digraph/test_all_simple_paths.py b/tests/retworkx_backwards_compat/digraph/test_all_simple_paths.py deleted file mode 100644 index 8d2b8e2aa5..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_all_simple_paths.py +++ /dev/null @@ -1,307 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDAGAllSimplePaths(unittest.TestCase): - def setUp(self): - super().setUp() - self.edges = [ - (0, 1), - (0, 2), - (0, 3), - (1, 2), - (1, 3), - (2, 3), - (2, 4), - (3, 2), - (3, 4), - (4, 2), - (4, 5), - (5, 2), - (5, 3), - ] - - def test_all_simple_paths(self): - dag = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.digraph_all_simple_paths(dag, 0, 5) - 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 = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.digraph_all_simple_paths(dag, 0, 5, min_depth=6) - expected = [ - [0, 1, 2, 3, 4, 5], - [0, 1, 3, 2, 4, 5], - ] - for i in expected: - self.assertIn(i, paths) - - def test_all_simple_paths_with_cutoff(self): - dag = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.digraph_all_simple_paths(dag, 0, 5, cutoff=4) - expected = [[0, 2, 4, 5], [0, 3, 4, 5]] - self.assertEqual(len(expected), len(paths)) - for i in expected: - self.assertIn(i, paths) - - def test_all_simple_paths_with_min_depth_and_cutoff(self): - dag = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.digraph_all_simple_paths(dag, 0, 5, min_depth=5, cutoff=5) - expected = [ - [0, 3, 2, 4, 5], - [0, 2, 3, 4, 5], - [0, 1, 3, 4, 5], - [0, 1, 2, 4, 5], - ] - self.assertEqual(len(expected), len(paths)) - for i in expected: - self.assertIn(i, paths) - - def test_all_simple_path_no_path(self): - dag = retworkx.PyDAG() - dag.add_node(0) - dag.add_node(1) - self.assertEqual([], retworkx.digraph_all_simple_paths(dag, 0, 1)) - - def test_all_simple_path_invalid_node_index(self): - dag = retworkx.PyDAG() - dag.add_node(0) - dag.add_node(1) - with self.assertRaises(retworkx.InvalidNode): - retworkx.digraph_all_simple_paths(dag, 0, 5) - - def test_graph_digraph_all_simple_paths(self): - dag = retworkx.PyGraph() - dag.add_node(0) - dag.add_node(1) - self.assertRaises(TypeError, retworkx.digraph_all_simple_paths, (dag, 0, 1)) - - -class TestDiGraphAllSimplePathsAllPairs(unittest.TestCase): - def setUp(self): - super().setUp() - self.edges = [ - (0, 1), - (0, 2), - (0, 3), - (1, 2), - (1, 3), - (2, 3), - (2, 4), - (3, 2), - (3, 4), - (4, 2), - (4, 5), - (5, 2), - (5, 3), - ] - - def test_all_simple_paths(self): - dag = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.all_pairs_all_simple_paths(dag) - expected = { - 0: { - 1: [[0, 1]], - 2: [ - [0, 3, 4, 5, 2], - [0, 3, 4, 2], - [0, 3, 2], - [0, 2], - [0, 1, 3, 4, 5, 2], - [0, 1, 3, 4, 2], - [0, 1, 3, 2], - [0, 1, 2], - ], - 3: [ - [0, 3], - [0, 2, 4, 5, 3], - [0, 2, 3], - [0, 1, 3], - [0, 1, 2, 4, 5, 3], - [0, 1, 2, 3], - ], - 4: [ - [0, 3, 4], - [0, 3, 2, 4], - [0, 2, 4], - [0, 2, 3, 4], - [0, 1, 3, 4], - [0, 1, 3, 2, 4], - [0, 1, 2, 4], - [0, 1, 2, 3, 4], - ], - 5: [ - [0, 3, 4, 5], - [0, 3, 2, 4, 5], - [0, 2, 4, 5], - [0, 2, 3, 4, 5], - [0, 1, 3, 4, 5], - [0, 1, 3, 2, 4, 5], - [0, 1, 2, 4, 5], - [0, 1, 2, 3, 4, 5], - ], - }, - 1: { - 2: [[1, 3, 4, 5, 2], [1, 3, 4, 2], [1, 3, 2], [1, 2]], - 3: [[1, 3], [1, 2, 4, 5, 3], [1, 2, 3]], - 4: [[1, 3, 4], [1, 3, 2, 4], [1, 2, 4], [1, 2, 3, 4]], - 5: [[1, 3, 4, 5], [1, 3, 2, 4, 5], [1, 2, 4, 5], [1, 2, 3, 4, 5]], - }, - 2: { - 3: [[2, 4, 5, 3], [2, 3]], - 4: [[2, 4], [2, 3, 4]], - 5: [[2, 4, 5], [2, 3, 4, 5]], - }, - 3: { - 2: [[3, 4, 5, 2], [3, 4, 2], [3, 2]], - 4: [[3, 4], [3, 2, 4]], - 5: [[3, 4, 5], [3, 2, 4, 5]], - }, - 4: { - 2: [[4, 5, 3, 2], [4, 5, 2], [4, 2]], - 3: [[4, 5, 3], [4, 5, 2, 3], [4, 2, 3]], - 5: [[4, 5]], - }, - 5: { - 2: [[5, 3, 4, 2], [5, 3, 2], [5, 2]], - 3: [[5, 3], [5, 2, 3]], - 4: [[5, 3, 4], [5, 3, 2, 4], [5, 2, 4], [5, 2, 3, 4]], - }, - } - self.assertEqual(expected, paths) - - def test_all_simple_paths_min_depth(self): - dag = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.all_pairs_all_simple_paths(dag, min_depth=6) - expected = { - 0: { - 2: [[0, 1, 3, 4, 5, 2]], - 3: [[0, 1, 2, 4, 5, 3]], - 5: [[0, 1, 3, 2, 4, 5], [0, 1, 2, 3, 4, 5]], - }, - 1: {}, - 2: {}, - 3: {}, - 4: {}, - 5: {}, - } - self.assertEqual(expected, paths) - - def test_all_simple_paths_with_cutoff(self): - dag = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.all_pairs_all_simple_paths(dag, cutoff=4) - expected = { - 0: { - 1: [[0, 1]], - 2: [[0, 3, 4, 2], [0, 3, 2], [0, 2], [0, 1, 3, 2], [0, 1, 2]], - 3: [[0, 3], [0, 2, 3], [0, 1, 3], [0, 1, 2, 3]], - 4: [[0, 3, 4], [0, 3, 2, 4], [0, 2, 4], [0, 2, 3, 4], [0, 1, 3, 4], [0, 1, 2, 4]], - 5: [[0, 3, 4, 5], [0, 2, 4, 5]], - }, - 1: { - 2: [[1, 3, 4, 2], [1, 3, 2], [1, 2]], - 3: [[1, 3], [1, 2, 3]], - 4: [[1, 3, 4], [1, 3, 2, 4], [1, 2, 4], [1, 2, 3, 4]], - 5: [[1, 3, 4, 5], [1, 2, 4, 5]], - }, - 2: { - 3: [[2, 4, 5, 3], [2, 3]], - 4: [[2, 4], [2, 3, 4]], - 5: [[2, 4, 5], [2, 3, 4, 5]], - }, - 3: { - 2: [[3, 4, 5, 2], [3, 4, 2], [3, 2]], - 4: [[3, 4], [3, 2, 4]], - 5: [[3, 4, 5], [3, 2, 4, 5]], - }, - 4: { - 2: [[4, 5, 3, 2], [4, 5, 2], [4, 2]], - 3: [[4, 5, 3], [4, 5, 2, 3], [4, 2, 3]], - 5: [[4, 5]], - }, - 5: { - 2: [[5, 3, 4, 2], [5, 3, 2], [5, 2]], - 3: [[5, 3], [5, 2, 3]], - 4: [[5, 3, 4], [5, 3, 2, 4], [5, 2, 4], [5, 2, 3, 4]], - }, - } - self.assertEqual(paths, expected) - - def test_all_simple_paths_with_min_depth_and_cutoff(self): - dag = retworkx.PyDAG() - for i in range(6): - dag.add_node(i) - dag.add_edges_from_no_data(self.edges) - paths = retworkx.all_pairs_all_simple_paths(dag, min_depth=5, cutoff=5) - expected = { - 0: { - 2: [[0, 3, 4, 5, 2], [0, 1, 3, 4, 2]], - 5: [[0, 3, 2, 4, 5], [0, 2, 3, 4, 5], [0, 1, 3, 4, 5], [0, 1, 2, 4, 5]], - 3: [[0, 2, 4, 5, 3]], - 4: [[0, 1, 3, 2, 4], [0, 1, 2, 3, 4]], - }, - 1: { - 2: [[1, 3, 4, 5, 2]], - 5: [[1, 3, 2, 4, 5], [1, 2, 3, 4, 5]], - 3: [[1, 2, 4, 5, 3]], - }, - 2: {}, - 3: {}, - 4: {}, - 5: {}, - } - self.assertEqual(expected, paths) - - def test_all_simple_path_no_path(self): - dag = retworkx.PyDAG() - dag.add_node(0) - dag.add_node(1) - self.assertEqual({0: {}, 1: {}}, retworkx.all_pairs_all_simple_paths(dag)) - - def test_all_simple_paths_empty(self): - self.assertEqual({}, retworkx.all_pairs_all_simple_paths(retworkx.PyDiGraph())) diff --git a/tests/retworkx_backwards_compat/digraph/test_ancestors_descendants.py b/tests/retworkx_backwards_compat/digraph/test_ancestors_descendants.py deleted file mode 100644 index 0db8d72acf..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_ancestors_descendants.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAncestors(unittest.TestCase): - def test_ancestors(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - res = retworkx.ancestors(dag, node_c) - self.assertEqual({node_a, node_b}, res) - - def test_no_ancestors(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - res = retworkx.ancestors(dag, node_a) - self.assertEqual(set(), res) - - def test_ancestors_no_descendants(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - dag.add_child(node_b, "c", {"b": 1}) - res = retworkx.ancestors(dag, node_b) - self.assertEqual({node_a}, res) - - -class TestDescendants(unittest.TestCase): - def test_descendants(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - res = retworkx.descendants(dag, node_a) - self.assertEqual({node_b, node_c}, res) - - def test_no_descendants(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - res = retworkx.descendants(dag, node_a) - self.assertEqual(set(), res) - - def test_descendants_no_ancestors(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"b": 1}) - res = retworkx.descendants(dag, node_b) - self.assertEqual({node_c}, res) diff --git a/tests/retworkx_backwards_compat/digraph/test_astar.py b/tests/retworkx_backwards_compat/digraph/test_astar.py deleted file mode 100644 index 7c03ea1191..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_astar.py +++ /dev/null @@ -1,114 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAstarDigraph(unittest.TestCase): - def test_astar_null_heuristic(self): - g = retworkx.PyDAG() - a = g.add_node("A") - b = g.add_node("B") - c = g.add_node("C") - d = g.add_node("D") - e = g.add_node("E") - f = g.add_node("F") - g.add_edge(a, b, 7) - g.add_edge(c, a, 9) - g.add_edge(a, d, 14) - g.add_edge(b, c, 10) - g.add_edge(d, c, 2) - g.add_edge(d, e, 9) - g.add_edge(b, f, 15) - g.add_edge(c, f, 11) - g.add_edge(e, f, 6) - path = retworkx.digraph_astar_shortest_path( - g, a, lambda goal: goal == "E", lambda x: float(x), lambda y: 0 - ) - expected = [a, d, e] - self.assertEqual(expected, path) - - def test_astar_manhattan_heuristic(self): - g = retworkx.PyDAG() - a = g.add_node((0.0, 0.0)) - b = g.add_node((2.0, 0.0)) - c = g.add_node((1.0, 1.0)) - d = g.add_node((0.0, 2.0)) - e = g.add_node((3.0, 3.0)) - f = g.add_node((4.0, 2.0)) - no_path = g.add_node((5.0, 5.0)) # no path to node - g.add_edge(a, b, 2.0) - g.add_edge(a, d, 4.0) - g.add_edge(b, c, 1.0) - g.add_edge(b, f, 7.0) - g.add_edge(c, e, 5.0) - g.add_edge(e, f, 1.0) - g.add_edge(d, e, 1.0) - - def heuristic_func(f): - x1, x2 = f - return abs(x2 - x1) - - def finish_func(node, x): - return x == g.get_node_data(node) - - expected = [ - [0], - [0, 1], - [0, 1, 2], - [0, 3], - [0, 3, 4], - [0, 3, 4, 5], - ] - - for index, end in enumerate([a, b, c, d, e, f]): - path = retworkx.digraph_astar_shortest_path( - g, - a, - lambda finish: finish_func(end, finish), - lambda x: float(x), - heuristic_func, - ) - self.assertEqual(expected[index], path) - - with self.assertRaises(retworkx.NoPathFound): - retworkx.digraph_astar_shortest_path( - g, - a, - lambda finish: finish_func(no_path, finish), - lambda x: float(x), - heuristic_func, - ) - - def test_astar_digraph_with_graph_input(self): - g = retworkx.PyGraph() - g.add_node(0) - with self.assertRaises(TypeError): - retworkx.digraph_astar_shortest_path(g, 0, lambda x: x, lambda y: 1, lambda z: 0) - - def test_astar_with_invalid_weights(self): - g = retworkx.PyDAG() - a = g.add_node("A") - b = g.add_node("B") - g.add_edge(a, b, 7) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.digraph_astar_shortest_path( - g, - a, - goal_fn=lambda goal: goal == "B", - edge_cost_fn=lambda _: invalid_weight, - estimate_cost_fn=lambda _: 0, - ) diff --git a/tests/retworkx_backwards_compat/digraph/test_avg_shortest_path.py b/tests/retworkx_backwards_compat/digraph/test_avg_shortest_path.py deleted file mode 100644 index a5f04c9990..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_avg_shortest_path.py +++ /dev/null @@ -1,169 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import math -import unittest - -import retworkx - - -class TestAvgShortestPath(unittest.TestCase): - def test_simple_example(self): - # Graph is not strongly connected. - edge_list = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (3, 6), (6, 7)] - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list(edge_list) - res = retworkx.digraph_unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isinf(res), "Output is not infinity") - - def test_cycle_graph(self): - graph = retworkx.generators.directed_cycle_graph(7) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertAlmostEqual(3.5, res, delta=1e-7) - - def test_path_graph(self): - # Graph is not strongly connected. - graph = retworkx.generators.directed_path_graph(5) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isinf(res), "Output is not infinity") - - def test_parallel_grid(self): - # Graph is not strongly connected. - graph = retworkx.generators.directed_grid_graph(30, 11) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isinf(res), "Output is not infinity") - - def test_empty(self): - graph = retworkx.PyDiGraph() - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_single_node(self): - graph = retworkx.PyDiGraph() - graph.add_node(0) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_single_node_self_edge(self): - graph = retworkx.PyDiGraph() - node = graph.add_node(0) - graph.add_edge(node, node, 0) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_disconnected_graph(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(32))) - with self.subTest(disconnected=False): - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isinf(res), "Output is not infinity") - - with self.subTest(disconnected=True): - res = retworkx.unweighted_average_shortest_path_length(graph, disconnected=True) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_partially_connected_graph(self): - graph = retworkx.generators.directed_cycle_graph(32) - graph.add_nodes_from(list(range(32))) - with self.subTest(disconnected=False): - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isinf(res), "Output is not infinity") - - with self.subTest(disconnected=True): - s = 15872 - den = 992 # n*(n-1), n=32 (only connected pairs considered) - res = retworkx.unweighted_average_shortest_path_length(graph, disconnected=True) - self.assertAlmostEqual(s / den, res, delta=1e-7) - - def test_connected_cycle_graph(self): - graph = retworkx.generators.directed_cycle_graph(32) - res = retworkx.unweighted_average_shortest_path_length(graph) - s = 15872 - den = 992 # n*(n-1) - self.assertAlmostEqual(s / den, res, delta=1e-7) - - -class TestAvgShortestPathAsUndirected(unittest.TestCase): - def test_simple_example(self): - edge_list = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (3, 6), (6, 7)] - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list(edge_list) - res = retworkx.digraph_unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertAlmostEqual(2.5714285714285716, res, delta=1e-7) - - def test_cycle_graph(self): - graph = retworkx.generators.directed_cycle_graph(7) - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertAlmostEqual(2, res, delta=1e-7) - - def test_path_graph(self): - graph = retworkx.generators.directed_path_graph(5) - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertAlmostEqual(2, res, delta=1e-7) - - def test_parallel_grid(self): - graph = retworkx.generators.directed_grid_graph(30, 11) - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertAlmostEqual(13.666666666666666, res, delta=1e-7) - - def test_empty(self): - graph = retworkx.PyDiGraph() - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_single_node(self): - graph = retworkx.PyDiGraph() - graph.add_node(0) - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_single_node_self_edge(self): - graph = retworkx.PyDiGraph() - node = graph.add_node(0) - graph.add_edge(node, node, 0) - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_disconnected_graph(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(32))) - with self.subTest(disconnected=False): - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertTrue(math.isinf(res), "Output is not infinity") - - with self.subTest(disconnected=True): - res = retworkx.unweighted_average_shortest_path_length( - graph, as_undirected=True, disconnected=True - ) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_partially_connected_graph(self): - graph = retworkx.generators.directed_cycle_graph(32) - graph.add_nodes_from(list(range(32))) - with self.subTest(disconnected=False): - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - self.assertTrue(math.isinf(res), "Output is not infinity") - - with self.subTest(disconnected=True): - s = 8192 - den = 992 # n*(n-1), n=32 (only connected pairs considered) - res = retworkx.unweighted_average_shortest_path_length( - graph, as_undirected=True, disconnected=True - ) - self.assertAlmostEqual(s / den, res, delta=1e-7) - - def test_connected_cycle_graph(self): - graph = retworkx.generators.directed_cycle_graph(32) - res = retworkx.unweighted_average_shortest_path_length(graph, as_undirected=True) - s = 8192 - den = 992 # n*(n-1) - self.assertAlmostEqual(s / den, res, delta=1e-7) diff --git a/tests/retworkx_backwards_compat/digraph/test_bellman_ford.py b/tests/retworkx_backwards_compat/digraph/test_bellman_ford.py deleted file mode 100644 index 3d5a9ef24a..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_bellman_ford.py +++ /dev/null @@ -1,438 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestBellmanFordDiGraph(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - self.d = self.graph.add_node("D") - self.e = self.graph.add_node("E") - self.f = self.graph.add_node("F") - edge_list = [ - (self.a, self.b, 7), - (self.c, self.a, 9), - (self.a, self.d, 14), - (self.b, self.c, 10), - (self.d, self.c, 2), - (self.d, self.e, 9), - (self.b, self.f, 15), - (self.c, self.f, 11), - (self.e, self.f, 6), - ] - self.graph.add_edges_from(edge_list) - - def test_bellman_ford(self): - path = retworkx.digraph_bellman_ford_shortest_path_lengths( - self.graph, self.a, lambda x: float(x) - ) - expected = {1: 7.0, 2: 16.0, 3: 14.0, 4: 23.0, 5: 22.0} - self.assertEqual(expected, path) - - def test_bellman_ford_length_with_no_path(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - g.add_node("B") - path_lenghts = retworkx.digraph_bellman_ford_shortest_path_lengths(g, a, edge_cost_fn=float) - expected = {} - self.assertEqual(expected, path_lenghts) - - def test_bellman_ford_path(self): - paths = retworkx.digraph_bellman_ford_shortest_paths(self.graph, self.a) - expected = { - # a -> b - 1: [0, 1], - # a -> c: a, d, c - 2: [0, 3, 2], - # a -> d - 3: [0, 3], - # a -> e: a, d, e - 4: [0, 3, 4], - # a -> f: a, b, f - 5: [0, 1, 5], - } - self.assertEqual(expected, paths) - - def test_bellman_ford_path_with_weight_fn(self): - paths = retworkx.digraph_bellman_ford_shortest_paths( - self.graph, self.a, weight_fn=lambda x: x - ) - expected = { - 1: [0, 1], - 2: [0, 3, 2], - 3: [0, 3], - 4: [0, 3, 4], - 5: [0, 1, 5], - } - self.assertEqual(expected, paths) - - def test_bellman_ford_path_undirected(self): - paths = retworkx.digraph_bellman_ford_shortest_paths(self.graph, self.a, as_undirected=True) - expected = { - 1: [0, 1], - 2: [0, 2], - 3: [0, 3], - 4: [0, 3, 4], - 5: [0, 1, 5], - } - self.assertEqual(expected, paths) - - def test_bellman_ford_path_undirected_with_weight_fn(self): - paths = retworkx.digraph_bellman_ford_shortest_paths( - self.graph, self.a, weight_fn=lambda x: x, as_undirected=True - ) - expected = { - 1: [0, 1], - 2: [0, 2], - 3: [0, 2, 3], - 4: [0, 2, 3, 4], - 5: [0, 2, 5], - } - self.assertEqual(expected, paths) - - def test_bellman_ford_with_no_goal_set(self): - path = retworkx.digraph_bellman_ford_shortest_path_lengths(self.graph, self.a, lambda x: 1) - expected = {1: 1.0, 2: 2.0, 3: 1.0, 4: 2.0, 5: 2.0} - self.assertEqual(expected, path) - - def test_bellman_path(self): - path = retworkx.digraph_bellman_ford_shortest_paths( - self.graph, self.a, weight_fn=lambda x: float(x), target=self.e - ) - expected = retworkx.digraph_dijkstra_shortest_paths( - self.graph, self.a, weight_fn=lambda x: float(x), target=self.e - ) - self.assertEqual(expected, path) - - def test_bellman_path_lengths(self): - path = retworkx.digraph_bellman_ford_shortest_path_lengths( - self.graph, self.a, lambda x: float(x), goal=self.e - ) - expected = retworkx.digraph_dijkstra_shortest_path_lengths( - self.graph, self.a, lambda x: float(x), goal=self.e - ) - self.assertEqual(expected, path) - - def test_bellman_ford_length_with_no_path_and_goal(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - b = g.add_node("B") - path_lenghts = retworkx.digraph_bellman_ford_shortest_path_lengths( - g, a, edge_cost_fn=float, goal=b - ) - expected = retworkx.digraph_dijkstra_shortest_path_lengths(g, a, edge_cost_fn=float, goal=b) - self.assertEqual(expected, path_lenghts) - - def test_bellman_ford_with_no_path(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.digraph_bellman_ford_shortest_path_lengths(g, a, lambda x: float(x)) - expected = {} - self.assertEqual(expected, path) - - def test_bellman_ford_path_with_no_path(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.digraph_bellman_ford_shortest_paths(g, a) - expected = {} - self.assertEqual(expected, path) - - def test_bellman_ford_with_disconnected_nodes(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - b = g.add_child(a, "B", 1.2) - g.add_node("C") - g.add_parent(b, "D", 2.4) - path = retworkx.digraph_bellman_ford_shortest_path_lengths(g, a, lambda x: x) - expected = {1: 1.2} - self.assertEqual(expected, path) - - def test_bellman_ford_with_graph_input(self): - g = retworkx.PyGraph() - g.add_node(0) - with self.assertRaises(TypeError): - retworkx.digraph_bellman_ford_shortest_path_lengths(g, 0, lambda x: x) - - def bellman_ford_with_invalid_weights(self): - graph = retworkx.generators.directed_path_graph(2) - - for as_undirected in [False, True]: - with self.subTest(as_undirected=as_undirected): - with self.assertRaises(ValueError): - retworkx.digraph_bellman_ford_shortest_paths( - graph, - source=0, - weight_fn=lambda _: float("nan"), - as_undirected=as_undirected, - ) - - def bellman_ford_lengths_with_invalid_weights(self): - graph = retworkx.generators.directed_path_graph(2) - - with self.assertRaises(ValueError): - retworkx.digraph_bellman_ford_shortest_path_lengths( - graph, node=0, edge_cost_fn=lambda _: float("nan") - ) - - def test_raises_negative_cycle_bellman_ford_paths(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.bellman_ford_shortest_paths(graph, 0, weight_fn=float) - - def test_raises_negative_cycle_bellman_ford_path_lenghts(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.bellman_ford_shortest_path_lengths(graph, 0, edge_cost_fn=float) - - def test_negative_edges_but_no_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, 1), - ] - ) - - result = retworkx.bellman_ford_shortest_path_lengths(graph, 0, edge_cost_fn=float) - - expected = {k: v for k, v in retworkx.floyd_warshall(graph, float)[0].items() if k != 0} - - self.assertEqual(result, expected) - - def test_negative_edge_cycle_true_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - self.assertTrue(retworkx.negative_edge_cycle(graph, float)) - - def test_negative_edge_cycle_no_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, 1), - ] - ) - - self.assertFalse(retworkx.negative_edge_cycle(graph, float)) - - def test_find_negative_cycle_true_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - cycle = retworkx.find_negative_cycle(graph, edge_cost_fn=float) - cycle_weight = 0 - - for i in range(len(cycle) - 1): - cycle_weight += graph.get_edge_data(cycle[i], cycle[i + 1]) - - self.assertTrue(cycle_weight < 0) - - def test_find_negative_cycle_self_loop_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from([(0, 1, 1), (1, 0, 1), (0, 0, -1)]) - - cycle = retworkx.find_negative_cycle(graph, edge_cost_fn=float) - cycle_weight = 0 - - for i in range(len(cycle) - 1): - cycle_weight += graph.get_edge_data(cycle[i], cycle[i + 1]) - - self.assertTrue(cycle_weight < 0) - - def test_find_negative_cycle_no_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, 1), - ] - ) - - with self.assertRaises(ValueError): - retworkx.find_negative_cycle(graph, edge_cost_fn=float) - - def test_bellman_ford_all_pair_path_lengths(self): - lengths = retworkx.digraph_all_pairs_bellman_ford_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 16.0, 3: 14.0, 4: 23.0, 5: 22.0}, - 1: {0: 19.0, 2: 10.0, 3: 33.0, 4: 42.0, 5: 15.0}, - 2: {0: 9.0, 1: 16.0, 3: 23.0, 4: 32.0, 5: 11.0}, - 3: {0: 11.0, 1: 18.0, 2: 2.0, 4: 9.0, 5: 13.0}, - 4: {5: 6.0}, - 5: {}, - } - self.assertEqual(expected, lengths) - - def test_bellman_ford_all_pair_paths(self): - paths = retworkx.digraph_all_pairs_bellman_ford_shortest_paths(self.graph, float) - expected = { - 0: {1: [0, 1], 2: [0, 3, 2], 3: [0, 3], 4: [0, 3, 4], 5: [0, 1, 5]}, - 1: { - 0: [1, 2, 0], - 2: [1, 2], - 3: [1, 2, 0, 3], - 4: [1, 2, 0, 3, 4], - 5: [1, 5], - }, - 2: { - 0: [2, 0], - 1: [2, 0, 1], - 3: [2, 0, 3], - 4: [2, 0, 3, 4], - 5: [2, 5], - }, - 3: { - 0: [3, 2, 0], - 1: [3, 2, 0, 1], - 2: [3, 2], - 4: [3, 4], - 5: [3, 2, 5], - }, - 4: {5: [4, 5]}, - 5: {}, - } - self.assertEqual(expected, paths) - - def test_bellman_ford_all_pair_path_lengths_with_node_removal(self): - self.graph.remove_node(3) - lengths = retworkx.digraph_all_pairs_bellman_ford_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 17.0, 5: 22.0}, - 1: {0: 19.0, 2: 10.0, 5: 15.0}, - 2: {0: 9.0, 1: 16.0, 5: 11.0}, - 4: {5: 6.0}, - 5: {}, - } - self.assertEqual(expected, lengths) - - def test_bellman_ford_all_pair_paths_with_node_removal(self): - self.graph.remove_node(3) - lengths = retworkx.digraph_all_pairs_bellman_ford_shortest_paths(self.graph, float) - expected = { - 0: {1: [0, 1], 2: [0, 1, 2], 5: [0, 1, 5]}, - 1: {0: [1, 2, 0], 2: [1, 2], 5: [1, 5]}, - 2: {0: [2, 0], 1: [2, 0, 1], 5: [2, 5]}, - 4: {5: [4, 5]}, - 5: {}, - } - self.assertEqual(expected, lengths) - - def test_bellman_ford_all_pair_path_lengths_empty_graph(self): - graph = retworkx.PyDiGraph() - self.assertEqual({}, retworkx.digraph_all_pairs_bellman_ford_path_lengths(graph, float)) - - def test_bellman_ford_all_pair_shortest_paths_empty_graph(self): - graph = retworkx.PyDiGraph() - self.assertEqual({}, retworkx.digraph_all_pairs_bellman_ford_shortest_paths(graph, float)) - - def test_bellman_ford_all_pair_path_lengths_graph_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.digraph_all_pairs_bellman_ford_path_lengths(graph, float), - ) - - def test_bellman_ford_all_pair_shortest_paths_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.digraph_all_pairs_bellman_ford_shortest_paths(graph, float), - ) - - def test_raises_negative_cycle_all_pairs_bellman_ford_paths(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.all_pairs_bellman_ford_shortest_paths(graph, float) - - def test_raises_negative_cycle_all_pairs_bellman_ford_path_lenghts(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.all_pairs_bellman_ford_path_lengths(graph, float) diff --git a/tests/retworkx_backwards_compat/digraph/test_bfs_search.py b/tests/retworkx_backwards_compat/digraph/test_bfs_search.py deleted file mode 100644 index 999f8422d9..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_bfs_search.py +++ /dev/null @@ -1,162 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestBfsSearch(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.graph.extend_from_edge_list( - [ - (0, 1), - (0, 2), - (1, 3), - (2, 1), - (2, 5), - (2, 6), - (5, 3), - (4, 7), - ] - ) - - def test_digraph_bfs_tree_edges(self): - class TreeEdgesRecorder(retworkx.visit.BFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.digraph_bfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 2), (0, 1), (2, 6), (2, 5), (1, 3)]) - - def test_digraph_bfs_tree_edges_no_starting_point(self): - class TreeEdgesRecorder(retworkx.visit.BFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.digraph_bfs_search(self.graph, None, vis) - self.assertEqual(vis.edges, [(0, 2), (0, 1), (2, 6), (2, 5), (1, 3), (4, 7)]) - - def test_digraph_bfs_tree_edges_restricted(self): - class TreeEdgesRecorderRestricted(retworkx.visit.BFSVisitor): - - prohibited = [(0, 2), (1, 2)] - - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - edge = (edge[0], edge[1]) - if edge in self.prohibited: - raise retworkx.visit.PruneSearch - self.edges.append(edge) - - vis = TreeEdgesRecorderRestricted() - retworkx.digraph_bfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 1), (1, 3)]) - - def test_digraph_bfs_goal_search_with_stop_search_exception(self): - class GoalSearch(retworkx.visit.BFSVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - - def tree_edge(self, edge): - u, v, _ = edge - self.parents[v] = u - - if v == self.goal: - raise retworkx.visit.StopSearch - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - retworkx.digraph_bfs_search(self.graph, [0], vis) - self.assertEqual(vis.reconstruct_path(), [0, 1, 3]) - - def test_digraph_bfs_goal_search_with_custom_exception(self): - class StopIfGoalFound(Exception): - pass - - class GoalSearch(retworkx.visit.BFSVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - - def tree_edge(self, edge): - u, v, _ = edge - self.parents[v] = u - - if v == self.goal: - raise StopIfGoalFound - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - try: - retworkx.digraph_bfs_search(self.graph, [0], vis) - except StopIfGoalFound: - pass - self.assertEqual(vis.reconstruct_path(), [0, 1, 3]) - - def test_graph_prune_non_tree_edge(self): - class PruneNonTreeEdge(retworkx.visit.BFSVisitor): - def non_tree_edge(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneNonTreeEdge() - retworkx.digraph_bfs_search(self.graph, [0], vis) - - def test_graph_prune_black_target_edge(self): - class PruneBlackTargetEdge(retworkx.visit.BFSVisitor): - def black_target_edge(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneBlackTargetEdge() - retworkx.digraph_bfs_search(self.graph, [0], vis) - - def test_graph_prune_gray_target_edge(self): - class PruneGrayTargetEdge(retworkx.visit.BFSVisitor): - def gray_target_edge(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneGrayTargetEdge() - retworkx.digraph_bfs_search(self.graph, [0], vis) diff --git a/tests/retworkx_backwards_compat/digraph/test_cartesian_product.py b/tests/retworkx_backwards_compat/digraph/test_cartesian_product.py deleted file mode 100644 index 9117abf6e9..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_cartesian_product.py +++ /dev/null @@ -1,60 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestCartesianProduct(unittest.TestCase): - def test_null_cartesian_null(self): - graph_1 = retworkx.PyDiGraph() - graph_2 = retworkx.PyDiGraph() - - graph_product, _ = retworkx.digraph_cartesian_product(graph_1, graph_2) - self.assertEqual(len(graph_product.nodes()), 0) - self.assertEqual(len(graph_product.edge_list()), 0) - - def test_directed_path_2_cartesian_path_2(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_2 = retworkx.generators.directed_path_graph(2) - - graph_product, _ = retworkx.digraph_cartesian_product(graph_1, graph_2) - self.assertEqual(len(graph_product.nodes()), 4) - self.assertEqual(len(graph_product.edge_list()), 4) - - def test_directed_path_2_cartesian_path_3(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_2 = retworkx.generators.directed_path_graph(3) - - graph_product, _ = retworkx.digraph_cartesian_product(graph_1, graph_2) - self.assertEqual(len(graph_product.nodes()), 6) - self.assertEqual(len(graph_product.edge_list()), 7) - - def test_directed_node_weights_cartesian(self): - graph_1 = retworkx.PyDiGraph() - graph_1.add_node("a_1") - graph_2 = retworkx.PyDiGraph() - graph_2.add_node(0) - - graph_product, _ = retworkx.digraph_cartesian_product(graph_1, graph_2) - self.assertEqual([("a_1", 0)], graph_product.nodes()) - - def test_directed_edge_weights_cartesian(self): - graph_1 = retworkx.PyDiGraph() - graph_1.add_nodes_from([0, 1]) - graph_1.add_edge(0, 1, "w_1") - graph_2 = retworkx.PyDiGraph() - graph_2.add_nodes_from([0, 1]) - graph_1.add_edge(0, 1, "w_2") - - graph_product, _ = retworkx.digraph_cartesian_product(graph_1, graph_2) - self.assertEqual(["w_1", "w_1", "w_2", "w_2"], graph_product.edges()) diff --git a/tests/retworkx_backwards_compat/digraph/test_centrality.py b/tests/retworkx_backwards_compat/digraph/test_centrality.py deleted file mode 100644 index eadb47614d..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_centrality.py +++ /dev/null @@ -1,162 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import math -import unittest - -import retworkx - - -class TestCentralityDiGraph(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - self.d = self.graph.add_node("D") - edge_list = [ - (self.a, self.b, 1), - (self.b, self.c, 1), - (self.c, self.d, 1), - ] - self.graph.add_edges_from(edge_list) - - def test_betweenness_centrality(self): - betweenness = retworkx.digraph_betweenness_centrality(self.graph) - expected = { - 0: 0.0, - 1: 0.3333333333333333, - 2: 0.3333333333333333, - 3: 0.0, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_endpoints(self): - betweenness = retworkx.digraph_betweenness_centrality(self.graph, endpoints=True) - expected = { - 0: 0.25, - 1: 0.41666666666666663, - 2: 0.41666666666666663, - 3: 0.25, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_unnormalized(self): - betweenness = retworkx.digraph_betweenness_centrality( - self.graph, endpoints=False, normalized=False - ) - expected = {0: 0.0, 1: 2.0, 2: 2.0, 3: 0.0} - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_parallel(self): - betweenness = retworkx.digraph_betweenness_centrality(self.graph, parallel_threshold=1) - expected = { - 0: 0.0, - 1: 0.3333333333333333, - 2: 0.3333333333333333, - 3: 0.0, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_endpoints_parallel(self): - betweenness = retworkx.digraph_betweenness_centrality( - self.graph, endpoints=True, parallel_threshold=1 - ) - expected = { - 0: 0.25, - 1: 0.41666666666666663, - 2: 0.41666666666666663, - 3: 0.25, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_unnormalized_parallel(self): - betweenness = retworkx.digraph_betweenness_centrality( - self.graph, endpoints=False, normalized=False, parallel_threshold=1 - ) - expected = {0: 0.0, 1: 2.0, 2: 2.0, 3: 0.0} - self.assertEqual(expected, betweenness) - - def test_closeness_centrality(self): - closeness = retworkx.digraph_closeness_centrality(self.graph) - expected = {0: 0.0, 1: 1.0 / 3.0, 2: 4.0 / 9.0, 3: 0.5} - self.assertEqual(expected, closeness) - - def test_closeness_centrality_wf_improved(self): - closeness = retworkx.digraph_closeness_centrality(self.graph, wf_improved=False) - expected = {0: 0.0, 1: 1.0, 2: 2.0 / 3.0, 3: 0.5} - self.assertEqual(expected, closeness) - - -class TestCentralityDiGraphDeletedNode(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - c0 = self.graph.add_node("C0") - self.d = self.graph.add_node("D") - edge_list = [ - (self.a, self.b, 1), - (self.b, self.c, 1), - (self.c, self.d, 1), - ] - self.graph.add_edges_from(edge_list) - self.graph.remove_node(c0) - - def test_betweenness_centrality(self): - betweenness = retworkx.digraph_betweenness_centrality(self.graph) - expected = { - 0: 0.0, - 1: 0.3333333333333333, - 2: 0.3333333333333333, - 4: 0.0, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_endpoints(self): - betweenness = retworkx.digraph_betweenness_centrality(self.graph, endpoints=True) - expected = { - 0: 0.25, - 1: 0.41666666666666663, - 2: 0.41666666666666663, - 4: 0.25, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_unnormalized(self): - betweenness = retworkx.digraph_betweenness_centrality( - self.graph, endpoints=False, normalized=False - ) - expected = {0: 0.0, 1: 2.0, 2: 2.0, 4: 0.0} - self.assertEqual(expected, betweenness) - - -class TestEigenvectorCentrality(unittest.TestCase): - def test_complete_graph(self): - graph = retworkx.generators.directed_mesh_graph(5) - centrality = retworkx.eigenvector_centrality(graph) - expected_value = math.sqrt(1.0 / 5.0) - for value in centrality.values(): - self.assertAlmostEqual(value, expected_value) - - def test_path_graph(self): - graph = retworkx.generators.directed_path_graph(3, bidirectional=True) - centrality = retworkx.eigenvector_centrality(graph) - expected = [0.5, 0.7071, 0.5] - for k, v in centrality.items(): - self.assertAlmostEqual(v, expected[k], 4) - - def test_no_convergence(self): - graph = retworkx.PyDiGraph() - with self.assertRaises(retworkx.FailedToConverge): - retworkx.eigenvector_centrality(graph, max_iter=0) diff --git a/tests/retworkx_backwards_compat/digraph/test_collect_bicolor_runs.py b/tests/retworkx_backwards_compat/digraph/test_collect_bicolor_runs.py deleted file mode 100644 index f0f6de1492..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_collect_bicolor_runs.py +++ /dev/null @@ -1,350 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCollectBicolorRuns(unittest.TestCase): - def test_cycle(self): - dag = retworkx.PyDiGraph() - dag.extend_from_edge_list([(0, 1), (1, 2), (2, 0)]) - with self.assertRaises(retworkx.DAGHasCycle): - retworkx.collect_bicolor_runs(dag, lambda _: True, lambda _: None) - - def test_filter_function_inner_exception(self): - dag = retworkx.PyDiGraph() - dag.add_node("a") - dag.add_child(0, "b", None) - dag.add_child(1, "c", None) - - def fail_function(node): - raise IndexError("Things fail from time to time") - - with self.assertRaises(IndexError): - retworkx.collect_bicolor_runs(dag, fail_function, lambda _: None) - - with self.assertRaises(IndexError): - retworkx.collect_bicolor_runs(dag, lambda _: True, fail_function) - - def test_empty(self): - dag = retworkx.PyDAG() - self.assertEqual( - [], - retworkx.collect_bicolor_runs(dag, lambda _: True, lambda _: None), - ) - - def test_two_colors(self): - """ - Input: - ┌─────────────┐ ┌─────────────┐ - │ │ │ │ - │ q0 │ │ q1 │ - │ │ │ │ - └───┬─────────┘ └──────┬──────┘ - │ ┌─────────────┐ │ - q0 │ │ │ │ q1 - │ │ │ │ - └─────────►│ cx │◄────────┘ - ┌──────────┤ ├─────────┐ - │ │ │ │ - q0 │ └─────────────┘ │ q1 - │ │ - │ ┌─────────────┐ │ - │ │ │ │ - └─────────►│ cz │◄────────┘ - ┌─────────┤ ├─────────┐ - │ └─────────────┘ │ - q0 │ │ q1 - │ │ - ┌───▼─────────┐ ┌──────▼──────┐ - │ │ │ │ - │ q0 │ │ q1 │ - │ │ │ │ - └─────────────┘ └─────────────┘ - - Expected: [[cx, cz]] - """ - dag = retworkx.PyDAG() - q0_list = [] - q1_list = [] - for _ in range(2): - q0_list.append(dag.add_node("q0")) - q1_list.append(dag.add_node("q1")) - - cx_gate = dag.add_node("cx") - cz_gate = dag.add_node("cz") - - dag.add_edge(q0_list[0], cx_gate, "q0") - dag.add_edge(q1_list[0], cx_gate, "q1") - dag.add_edge(cx_gate, cz_gate, "q0") - dag.add_edge(cx_gate, cz_gate, "q1") - dag.add_edge(cz_gate, q0_list[1], "q0") - dag.add_edge(cz_gate, q1_list[1], "q1") - - def filter_function(node): - if node in ["cx", "cz"]: - return True - else: - return None - - def color_function(node): - if "q" in node: - return int(node[1:]) - else: - return None - - self.assertEqual( - [["cx", "cz"]], - retworkx.collect_bicolor_runs(dag, filter_function, color_function), - ) - - def test_two_colors_with_pending(self): - """ - Input: - ┌─────────────┐ - │ │ - │ q0 │ - │ │ - └───┬─────────┘ - | q0 - │ - ┌───▼─────────┐ - │ │ - │ h │ - │ │ - └───┬─────────┘ - | q0 - │ ┌─────────────┐ - │ │ │ - │ │ q1 │ - │ │ │ - | └──────┬──────┘ - │ ┌─────────────┐ │ - q0 │ │ │ │ q1 - │ │ │ │ - └─────────►│ cx │◄────────┘ - ┌──────────┤ ├─────────┐ - │ │ │ │ - q0 │ └─────────────┘ │ q1 - │ │ - │ ┌─────────────┐ │ - │ │ │ │ - └─────────►│ cz │◄────────┘ - ┌─────────┤ ├─────────┐ - │ └─────────────┘ │ - q0 │ │ q1 - │ │ - ┌───▼─────────┐ ┌──────▼──────┐ - │ │ │ │ - │ q0 │ │ y │ - │ │ │ │ - └─────────────┘ └─────────────┘ - | q1 - │ - ┌───▼─────────┐ - │ │ - │ q1 │ - │ │ - └─────────────┘ - - Expected: [[h, cx, cz, y]] - """ - dag = retworkx.PyDAG() - q0_list = [] - q1_list = [] - for _ in range(2): - q0_list.append(dag.add_node("q0")) - q1_list.append(dag.add_node("q1")) - - h_gate = dag.add_node("h") - cx_gate = dag.add_node("cx") - cz_gate = dag.add_node("cz") - y_gate = dag.add_node("y") - - dag.add_edge(q0_list[0], h_gate, "q0") - dag.add_edge(h_gate, cx_gate, "q0") - dag.add_edge(q1_list[0], cx_gate, "q1") - dag.add_edge(cx_gate, cz_gate, "q0") - dag.add_edge(cx_gate, cz_gate, "q1") - dag.add_edge(cz_gate, q0_list[1], "q0") - dag.add_edge(cz_gate, y_gate, "q1") - dag.add_edge(y_gate, q1_list[1], "q1") - - def filter_function(node): - if node in ["cx", "cz", "h", "y"]: - return True - else: - return None - - def color_function(node): - if "q" in node: - return int(node[1:]) - else: - return None - - self.assertEqual( - [["h", "cx", "cz", "y"]], - retworkx.collect_bicolor_runs(dag, filter_function, color_function), - ) - - def test_two_colors_with_barrier(self): - """ - Input: - ┌─────────────┐ ┌─────────────┐ - │ │ │ │ - │ q0 │ │ q1 │ - │ │ │ │ - └───┬─────────┘ └──────┬──────┘ - │ ┌─────────────┐ │ - q0 │ │ │ │ q1 - └─────────►│ cx │◄────────┘ - ┌──────────┤ ├─────────┐ - q0 │ └─────────────┘ │ q1 - │ │ - │ ┌─────────────┐ │ - │ │ │ │ - └─────────►│ barrier │◄────────┘ - ┌─────────┤ ├─────────┐ - │ └─────────────┘ │ - q0 │ │ q1 - │ │ - │ ┌─────────────┐ │ - │ │ │ │ - └────────►│ cz │◄────────┘ - ┌──────────┤ ├─────────┐ - q0 │ └─────────────┘ │ q1 - │ │ - ┌───▼─────────┐ ┌──────▼──────┐ - │ │ │ │ - │ q0 │ │ q1 │ - │ │ │ │ - └─────────────┘ └─────────────┘ - - Expected: [[cx], [cz]] - """ - dag = retworkx.PyDAG() - q0_list = [] - q1_list = [] - for _ in range(2): - q0_list.append(dag.add_node("q0")) - q1_list.append(dag.add_node("q1")) - - cx_gate = dag.add_node("cx") - barrier = dag.add_node("barrier") - cz_gate = dag.add_node("cz") - - # CX - dag.add_edge(q0_list[0], cx_gate, "q0") - dag.add_edge(q1_list[0], cx_gate, "q1") - # Barrier - dag.add_edge(cx_gate, barrier, "q0") - dag.add_edge(cx_gate, barrier, "q1") - # CZ - dag.add_edge(barrier, cz_gate, "q0") - dag.add_edge(barrier, cz_gate, "q1") - dag.add_edge(cz_gate, q0_list[1], "q0") - dag.add_edge(cz_gate, q1_list[1], "q1") - - def filter_function(node): - if node in ["cx", "cz"]: - return True - elif node == "barrier": - return False - else: - return None - - def color_function(node): - if "q" in node: - return int(node[1:]) - else: - return None - - self.assertEqual( - [["cx"], ["cz"]], - retworkx.collect_bicolor_runs(dag, filter_function, color_function), - ) - - def test_color_with_ignored_edge(self): - """ - Input: - ┌─────────────┐ ┌─────────────┐ - │ │ │ │ - │ q0 │ │ c0 │ - │ │ │ │ - └───┬─────────┘ └──────┬──────┘ - │ ┌─────────────┐ │ - q0 │ │ │ │ c0 - └─────────►│ rx │◄────────┘ - ┌──────────┤ ├─────────┐ - q0 │ └─────────────┘ │ c0 - │ │ - │ ┌─────────────┐ │ - │ │ │ │ - └─────────►│ barrier │ │ - ┌─────────┤ │ │ - │ └─────────────┘ │ - q0 │ │ c0 - │ │ - │ ┌─────────────┐ │ - │ │ │ │ - └────────►│ rz │◄────────┘ - ┌──────────┤ ├─────────┐ - q0 │ └─────────────┘ │ c0 - │ │ - ┌───▼─────────┐ ┌──────▼──────┐ - │ │ │ │ - │ q0 │ │ c0 │ - │ │ │ │ - └─────────────┘ └─────────────┘ - - Expected: [] - """ - dag = retworkx.PyDAG() - q0_list = [] - c0_list = [] - for _ in range(2): - q0_list.append(dag.add_node("q0")) - c0_list.append(dag.add_node("c0")) - - rx_gate = dag.add_node("rx") - barrier = dag.add_node("barrier") - rz_gate = dag.add_node("rz") - - # RX - dag.add_edge(q0_list[0], rx_gate, "q0") - dag.add_edge(c0_list[0], rx_gate, "c0") - # Barrier - dag.add_edge(rx_gate, barrier, "q0") - # RZ - dag.add_edge(barrier, rz_gate, "q0") - dag.add_edge(rx_gate, rz_gate, "c0") - dag.add_edge(rz_gate, q0_list[1], "q0") - dag.add_edge(rz_gate, c0_list[1], "c0") - - def filter_function(node): - if node == "barrier": - return False - else: - return None - - def color_function(node): - if "q" in node: - return int(node[1:]) - else: - return None - - self.assertEqual( - [], - retworkx.collect_bicolor_runs(dag, filter_function, color_function), - ) diff --git a/tests/retworkx_backwards_compat/digraph/test_collect_runs.py b/tests/retworkx_backwards_compat/digraph/test_collect_runs.py deleted file mode 100644 index 2e8ea20065..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_collect_runs.py +++ /dev/null @@ -1,138 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCollectRuns(unittest.TestCase): - def test_dagcircuit_basic(self): - dag = retworkx.PyDAG() - qr_0_in = dag.add_node("qr[0]") - qr_0_out = dag.add_node("qr[0]") - qr_1_in = dag.add_node("qr[1]") - qr_1_out = dag.add_node("qr[1]") - cr_0_in = dag.add_node("cr[0]") - cr_0_out = dag.add_node("cr[0]") - cr_1_in = dag.add_node("cr[1]") - cr_1_out = dag.add_node("cr[1]") - - h_gate = dag.add_child(qr_0_in, "h", "qr[0]") - x_gate = dag.add_child(h_gate, "x", "qr[0]") - cx_gate = dag.add_child(x_gate, "cx", "qr[0]") - dag.add_edge(qr_1_in, cx_gate, "qr[1]") - - measure_qr_1 = dag.add_child(cx_gate, "measure", "qr[1]") - dag.add_edge(cr_1_in, measure_qr_1, "cr[1]") - x_gate = dag.add_child(measure_qr_1, "x", "qr[1]") - dag.add_edge(measure_qr_1, x_gate, "cr[1]") - dag.add_edge(cr_0_in, x_gate, "cr[0]") - - measure_qr_0 = dag.add_child(cx_gate, "measure", "qr[0]") - dag.add_edge(measure_qr_0, qr_0_out, "qr[0]") - dag.add_edge(measure_qr_0, cr_0_out, "cr[0]") - dag.add_edge(x_gate, measure_qr_0, "cr[0]") - - measure_qr_1_out = dag.add_child(x_gate, "measure", "cr[1]") - dag.add_edge(x_gate, measure_qr_1_out, "qr[1]") - dag.add_edge(measure_qr_1_out, qr_1_out, "qr[1]") - dag.add_edge(measure_qr_1_out, cr_1_out, "cr[1]") - - def filter_function(node): - return node in ["h", "x"] - - res = retworkx.collect_runs(dag, filter_function) - expected = [["h", "x"], ["x"]] - self.assertEqual(expected, res) - - def test_multiple_successor_edges(self): - dag = retworkx.PyDiGraph() - q0, q1 = dag.add_nodes_from(["q0", "q1"]) - cx_1 = dag.add_child(q0, "cx", "q0") - dag.add_edge(q1, cx_1, "q1") - cx_2 = dag.add_child(cx_1, "cx", "q0") - dag.add_edge(q1, cx_2, "q1") - cx_3 = dag.add_child(cx_2, "cx", "q0") - dag.add_edge(q1, cx_3, "q1") - - def filter_function(node): - return node == "cx" - - res = retworkx.collect_runs(dag, filter_function) - self.assertEqual([["cx", "cx", "cx"]], res) - - def test_cycle(self): - dag = retworkx.PyDiGraph() - dag.extend_from_edge_list([(0, 1), (1, 2), (2, 0)]) - with self.assertRaises(retworkx.DAGHasCycle): - retworkx.collect_runs(dag, lambda _: True) - - def test_filter_function_inner_exception(self): - dag = retworkx.PyDiGraph() - dag.add_node("a") - dag.add_child(0, "b", None) - - def filter_function(node): - raise IndexError("Things fail from time to time") - - with self.assertRaises(IndexError): - retworkx.collect_runs(dag, filter_function) - - def test_empty(self): - dag = retworkx.PyDAG() - self.assertEqual([], retworkx.collect_runs(dag, lambda _: True)) - - def test_h_h_cx(self): - dag = retworkx.PyDiGraph() - q0, q1 = dag.add_nodes_from(["q0", "q1"]) - h_1 = dag.add_child(q0, "h", "q0") - h_2 = dag.add_child(q1, "h", "q1") - cx_2 = dag.add_child(h_1, "cx", "q0") - dag.add_edge(h_2, cx_2, "q1") - - def filter_function(node): - return node in ["cx", "h"] - - res = retworkx.collect_runs(dag, filter_function) - self.assertEqual([["h", "cx"], ["h"]], res) - - def test_cx_h_h_cx(self): - dag = retworkx.PyDiGraph() - q0, q1 = dag.add_nodes_from(["q0", "q1"]) - cx_1 = dag.add_child(q0, "cx", "q0") - dag.add_edge(q1, cx_1, "q1") - h_1 = dag.add_child(cx_1, "h", "q0") - h_2 = dag.add_child(cx_1, "h", "q1") - cx_2 = dag.add_child(h_1, "cx", "q0") - dag.add_edge(h_2, cx_2, "q1") - - def filter_function(node): - return node in ["cx", "h"] - - res = retworkx.collect_runs(dag, filter_function) - self.assertEqual([["cx"], ["h", "cx"], ["h"]], res) - - def test_cx_h_cx(self): - dag = retworkx.PyDiGraph() - q0, q1 = dag.add_nodes_from(["q0", "q1"]) - cx_1 = dag.add_child(q0, "cx", "q0") - dag.add_edge(q1, cx_1, "q1") - h_1 = dag.add_child(cx_1, "h", "q0") - cx_2 = dag.add_child(h_1, "cx", "q0") - dag.add_edge(cx_1, cx_2, "q1") - - def filter_function(node): - return node in ["cx", "h"] - - res = retworkx.collect_runs(dag, filter_function) - self.assertEqual([["cx"], ["h", "cx"]], res) diff --git a/tests/retworkx_backwards_compat/digraph/test_complement.py b/tests/retworkx_backwards_compat/digraph/test_complement.py deleted file mode 100644 index ef5eccc828..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_complement.py +++ /dev/null @@ -1,68 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestComplement(unittest.TestCase): - def test_null_graph(self): - graph = retworkx.PyDiGraph() - complement_graph = retworkx.complement(graph) - self.assertEqual(0, len(complement_graph.nodes())) - self.assertEqual(0, len(complement_graph.edges())) - - def test_clique_directed(self): - N = 5 - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list([(i, j) for i in range(N) for j in range(N) if i != j]) - - complement_graph = retworkx.complement(graph) - self.assertEqual(graph.nodes(), complement_graph.nodes()) - self.assertEqual(0, len(complement_graph.edges())) - - def test_empty_directed(self): - N = 5 - graph = retworkx.PyDiGraph() - graph.add_nodes_from([i for i in range(N)]) - - expected_graph = retworkx.PyDiGraph() - expected_graph.extend_from_edge_list([(i, j) for i in range(N) for j in range(N) if i != j]) - - complement_graph = retworkx.complement(graph) - self.assertTrue( - retworkx.is_isomorphic( - expected_graph, - complement_graph, - ) - ) - - def test_complement_directed(self): - N = 8 - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list( - [(i, j) for i in range(N) for j in range(N) if i != j and (i + j) % 3 == 0] - ) - - expected_graph = retworkx.PyDiGraph() - expected_graph.extend_from_edge_list( - [(i, j) for i in range(N) for j in range(N) if i != j and (i + j) % 3 != 0] - ) - - complement_graph = retworkx.complement(graph) - self.assertTrue( - retworkx.is_isomorphic( - expected_graph, - complement_graph, - ) - ) diff --git a/tests/retworkx_backwards_compat/digraph/test_compose.py b/tests/retworkx_backwards_compat/digraph/test_compose.py deleted file mode 100644 index 86268dda79..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_compose.py +++ /dev/null @@ -1,95 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCompose(unittest.TestCase): - def test_simple_dag_composition(self): - dag = retworkx.PyDAG() - dag.check_cycle = True - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - dag_other = retworkx.PyDAG() - node_d = dag_other.add_node("d") - dag_other.add_child(node_d, "e", {"a": 3}) - res = dag.compose(dag_other, {node_c: (node_d, {"b": 1})}) - self.assertEqual({0: 3, 1: 4}, res) - self.assertEqual([0, 1, 2, 3, 4], retworkx.topological_sort(dag)) - - def test_compose_graph_onto_digraph_error(self): - digraph = retworkx.PyDiGraph() - graph = retworkx.PyGraph() - with self.assertRaises(TypeError): - digraph.compose(graph, {}) - - def test_edge_map_and_node_map_funcs_digraph_compose(self): - digraph = retworkx.PyDiGraph() - original_input_nodes = digraph.add_nodes_from(["qr[0]", "qr[1]"]) - original_op_nodes = digraph.add_nodes_from(["h"]) - output_nodes = digraph.add_nodes_from(["qr[0]", "qr[1]"]) - digraph.add_edge(original_input_nodes[0], original_op_nodes[0], "qr[0]") - digraph.add_edge(original_op_nodes[0], output_nodes[0], "qr[0]") - # Setup other graph - other_digraph = retworkx.PyDiGraph() - input_nodes = other_digraph.add_nodes_from(["qr[2]", "qr[3]"]) - op_nodes = other_digraph.add_nodes_from(["cx"]) - other_output_nodes = other_digraph.add_nodes_from(["qr[2]", "qr[3]"]) - other_digraph.add_edges_from( - [ - (input_nodes[0], op_nodes[0], "qr[2]"), - (input_nodes[1], op_nodes[0], "qr[3]"), - ] - ) - other_digraph.add_edges_from( - [ - (op_nodes[0], other_output_nodes[0], "qr[2]"), - (op_nodes[0], other_output_nodes[1], "qr[3]"), - ] - ) - - def map_fn(weight): - if weight == "qr[2]": - return "qr[0]" - elif weight == "qr[3]": - return "qr[1]" - else: - return weight - - digraph.remove_nodes_from(output_nodes) - other_digraph.remove_nodes_from(input_nodes) - node_map = { - original_op_nodes[0]: (op_nodes[0], "qr[0]"), - original_input_nodes[1]: (op_nodes[0], "qr[1]"), - } - res = digraph.compose(other_digraph, node_map, node_map_func=map_fn, edge_map_func=map_fn) - self.assertEqual({2: 4, 3: 3, 4: 5}, res) - self.assertEqual(digraph[res[other_output_nodes[0]]], "qr[0]") - self.assertEqual(digraph[res[other_output_nodes[1]]], "qr[1]") - # qr[0] -> h - self.assertTrue(digraph.has_edge(0, 2)) - self.assertTrue(digraph.get_all_edge_data(0, 2), ["qr[0]"]) - # qr[1] -> cx - self.assertTrue(digraph.has_edge(1, 4)) - self.assertTrue(digraph.get_all_edge_data(1, 4), ["qr[1]"]) - # h -> cx - self.assertTrue(digraph.has_edge(2, 4)) - self.assertTrue(digraph.get_all_edge_data(0, 2), ["qr[0]"]) - # cx -> qr[2] - self.assertTrue(digraph.has_edge(4, 3)) - self.assertTrue(digraph.get_all_edge_data(0, 2), ["qr[0]"]) - # cx -> qr[3] - self.assertTrue(digraph.has_edge(4, 5)) - self.assertTrue(digraph.get_all_edge_data(0, 2), ["qr[1]"]) diff --git a/tests/retworkx_backwards_compat/digraph/test_contract_nodes.py b/tests/retworkx_backwards_compat/digraph/test_contract_nodes.py deleted file mode 100644 index 8caf5580b9..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_contract_nodes.py +++ /dev/null @@ -1,265 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestContractNodesCheckCycleSwitch(unittest.TestCase): - def setUp(self): - super().setUp() - self.dag = retworkx.PyDAG() - self.node_a = self.dag.add_node("a") - self.node_b = self.dag.add_child(self.node_a, "b", "b") - self.node_c = self.dag.add_child(self.node_b, "c", "c") - - self.new_weight = "m" - - def contract(self, **kwargs): - """ - ┌─┐ ┌─┐ - ┌─┤a│ ┌─────────┤m│ - │ └─┘ │ └▲┘ - ┌▼┐ ┌▼┐ │ - │b│ ───► │b├─────────┘ - └┬┘ └─┘ - │ ┌─┐ - └─►┤c│ - └─┘ - """ - self.dag.contract_nodes([self.node_a, self.node_c], self.new_weight, **kwargs) - - def test_cycle_check_enable_local(self): - # Disable at class level. - self.dag.check_cycle = False - - # Check removal is not allowed with explicit check_cycle=True. - self.assertRaises(retworkx.DAGWouldCycle, self.contract, check_cycle=True) - - def test_cycle_check_disable_local(self): - # Enable at class level. - self.dag.check_cycle = True - - # Check removal is allowed for check_cycle=False - self.contract(check_cycle=False) - self.assertEqual(set(self.dag.nodes()), {"b", "m"}) - - def test_cycle_check_inherit_class_enable(self): - # Enable at class level. - self.dag.check_cycle = True - - # Check removal is not allowed. - self.assertRaises(retworkx.DAGWouldCycle, self.contract) - - def test_cycle_check_inherit_class_disable(self): - # Disable at class level. - self.dag.check_cycle = False - - # Check removal is allowed. - self.contract() - self.assertEqual(set(self.dag.nodes()), {"b", "m"}) - - -class TestContractNodes(unittest.TestCase): - def test_empty_nodes(self): - """Replacing empty nodes is functionally equivalent to add_node.""" - dag = retworkx.PyDAG() - dag.contract_nodes([], "m") - - self.assertEqual(set(dag.nodes()), {"m"}) - - def test_unknown_nodes(self): - """ - Replacing all unknown nodes is functionally equivalent to add_node, - since unknown nodes should be ignored. - """ - dag = retworkx.PyDAG() - dag.contract_nodes([0, 1, 2], "m") - - self.assertEqual(set(dag.nodes()), {"m"}) - - def test_cycle_path_len_gt_1(self): - """ - ┌─┐ ┌─┐ - ┌4─┤a├─1┐ │m├──1───┐ - │ └─┘ │ └▲┘ │ - ┌▼┐ ┌▼┐ │ ┌▼┐ - │d│ │b│ ───► │ │b│ - └▲┘ └┬┘ │ └┬┘ - │ ┌─┐ 2 │ ┌─┐ 2 - └3─┤c│◄─┘ └3─┤c│◄─┘ - └─┘ └─┘ - """ - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 1) - node_c = dag.add_child(node_b, "c", 2) - node_d = dag.add_child(node_c, "c", 3) - dag.add_edge(node_a, node_d, 4) - - with self.assertRaises(retworkx.DAGWouldCycle): - dag.contract_nodes([node_a, node_d], "m", check_cycle=True) - - # Proceed, ignoring cycles. - node_m = dag.contract_nodes([node_a, node_d], "m") - - self.assertEqual([node_b, node_c, node_m], dag.node_indexes()) - self.assertEqual( - {(node_b, node_c), (node_c, node_m), (node_m, node_b)}, - set(dag.edge_list()), - ) - - def test_multiple_paths_would_cycle(self): - """ - ┌─┐ ┌─┐ ┌─┐ ┌─┐ - ┌3─┤c│ │e├─5┐ ┌──┤c│ │e├──┐ - │ └▲┘ └▲┘ │ │ └▲┘ └▲┘ │ - ┌▼┐ 2 ┌─┐ 4 ┌▼┐ │ 2 ┌─┐ 4 │ - │d│ └──┤b├──┘ │f│ ───► │ └──┤b├──┘ │ - └─┘ └▲┘ └─┘ 3 └▲┘ 5 - 1 │ 1 │ - ┌┴┐ │ ┌┴┐ │ - │a│ └─────►│m│◄─────┘ - └─┘ └─┘ - """ - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 1) - node_c = dag.add_child(node_b, "c", 2) - node_d = dag.add_child(node_c, "d", 3) - node_e = dag.add_child(node_b, "e", 4) - node_f = dag.add_child(node_e, "f", 5) - - with self.assertRaises(retworkx.DAGWouldCycle): - dag.contract_nodes([node_a, node_d, node_f], "m", check_cycle=True) - - # Proceed, ignoring cycles. - node_m = dag.contract_nodes([node_a, node_d, node_f], "m") - - self.assertEqual([node_b, node_c, node_e, node_m], dag.node_indexes()) - self.assertEqual( - { - (node_b, node_c), - (node_c, node_m), - (node_e, node_m), - (node_b, node_e), - (node_m, node_b), - }, - set(dag.edge_list()), - ) - - def test_replace_node_no_neighbors(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_m = dag.contract_nodes([node_a], "m", check_cycle=True) - self.assertEqual([node_m], dag.node_indexes()) - self.assertEqual(set(), set(dag.edge_list())) - - def test_keep_edges_multigraph(self): - """ - ┌─┐ ┌─┐ - ┌─┤a│◄┐ ┌─┤a│◄┐ - │ └─┘ │ │ └─┘ │ - 1 2 ──► 1 2 - ┌▼┐ ┌┴┐ │ ┌─┐ │ - │b│ │c│ └►│m├─┘ - └─┘ └─┘ └─┘ - """ - dag = retworkx.PyDiGraph() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - node_c = dag.add_node("c") - - dag.add_edge(node_a, node_b, 1) - dag.add_edge(node_c, node_a, 2) - - with self.assertRaises(retworkx.DAGWouldCycle): - dag.contract_nodes([node_b, node_c], "m", check_cycle=True) - - # Proceed, ignoring cycles. - node_m = dag.contract_nodes([node_b, node_c], "m") - self.assertEqual([node_a, node_m], dag.node_indexes()) - self.assertEqual( - {(node_a, node_m, 1), (node_m, node_a, 2)}, - set(dag.weighted_edge_list()), - ) - - -class TestContractNodesSimpleGraph(unittest.TestCase): - def setUp(self): - super().setUp() - self.dag = retworkx.PyDAG(multigraph=False) - self.node_a = self.dag.add_node("a") - self.node_b = self.dag.add_child(self.node_a, "b", 1) - self.node_c = self.dag.add_child(self.node_a, "c", 2) - self.node_d = self.dag.add_child(self.node_a, "d", 3) - self.node_e = self.dag.add_node("e") - self.dag.add_edge(self.node_b, self.node_e, 4) - self.dag.add_edge(self.node_c, self.node_e, 5) - self.dag.add_edge(self.node_d, self.node_e, 6) - - def test_collapse_parallel_edges_no_combo_fn(self): - """ - Parallel edges are collapsed arbitrarily when weight_combo_fn is None. - ┌─┐ ┌─┐ - │a│ │a│ - ┌──┴┬┴──┐ └┬┘ - 1 2 3 1 or 2 or 3 - ┌▼┐ ┌▼┐ ┌▼┐ ┌▼┐ - │b│ │c│ │d│ ──► │m│ - └┬┘ └┬┘ └┬┘ └┬┘ - 4 5 6 4 or 5 or 6 - └──►▼◄──┘ ┌▼┐ - │e│ │e│ - └─┘ └─┘ - """ - self.dag.contract_nodes([self.node_b, self.node_c, self.node_d], "m") - - self.assertEqual(set(self.dag.nodes()), {"a", "e", "m"}) - self.assertEqual(len(self.dag.edges()), 2) - - # Should have one incoming edge, one outgoing - self.assertTrue(any(e in self.dag.edges() for e in {1, 2, 3})) - self.assertTrue(any(e in self.dag.edges() for e in {4, 5, 6})) - - def test_collapse_parallel_edges(self): - """ - Parallel edges are collapsed using weight_combo_fn. - ┌─┐ ┌─┐ - │a│ │a│ - ┌──┴┬┴──┐ └┬┘ - 1 2 3 6 - ┌▼┐ ┌▼┐ ┌▼┐ ┌▼┐ - │b│ │c│ │d│ ──► │m│ - └┬┘ └┬┘ └┬┘ └┬┘ - 4 5 6 15 - └──►▼◄──┘ ┌▼┐ - │e│ │e│ - └─┘ └─┘ - """ - self.dag.contract_nodes( - [self.node_b, self.node_c, self.node_d], - "m", - weight_combo_fn=lambda w1, w2: w1 + w2, - ) - - self.assertEqual(set(self.dag.nodes()), {"a", "e", "m"}) - self.assertEqual(len(self.dag.edges()), 2) - - # Should have one incoming edge, one outgoing - self.assertEqual(set(self.dag.edges()), {6, 15}) - - def test_replace_all_nodes(self): - self.dag.contract_nodes(self.dag.node_indexes(), "m") - self.assertEqual(set(self.dag.nodes()), {"m"}) - self.assertFalse(self.dag.edges()) diff --git a/tests/retworkx_backwards_compat/digraph/test_copy.py b/tests/retworkx_backwards_compat/digraph/test_copy.py deleted file mode 100644 index 18e12b203f..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_copy.py +++ /dev/null @@ -1,55 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCopy(unittest.TestCase): - def test_copy_returns_graph(self): - graph_a = retworkx.PyDiGraph() - node_a = graph_a.add_node("a_1") - node_b = graph_a.add_node("a_2") - graph_a.add_edge(node_a, node_b, "edge_1") - node_c = graph_a.add_node("a_3") - graph_a.add_edge(node_b, node_c, "edge_2") - graph_b = graph_a.copy() - self.assertIsInstance(graph_b, retworkx.PyDiGraph) - - def test_copy_with_holes_returns_graph(self): - graph_a = retworkx.PyDiGraph() - node_a = graph_a.add_node("a_1") - node_b = graph_a.add_node("a_2") - graph_a.add_edge(node_a, node_b, "edge_1") - node_c = graph_a.add_node("a_3") - graph_a.add_edge(node_b, node_c, "edge_2") - graph_a.remove_node(node_b) - graph_b = graph_a.copy() - self.assertIsInstance(graph_b, retworkx.PyDiGraph) - self.assertEqual([node_a, node_c], graph_b.node_indexes()) - - def test_copy_empty(self): - graph = retworkx.PyDiGraph() - empty_copy = graph.copy() - self.assertEqual(len(empty_copy), 0) - - def test_copy_shared_ref(self): - graph_a = retworkx.PyDiGraph() - node_a = graph_a.add_node({"a": 1}) - node_b = graph_a.add_node({"b": 2}) - graph_a.add_edge(node_a, node_b, {"edge": 1}) - graph_b = graph_a.copy() - graph_a[0]["a"] = 42 - graph_b.get_edge_data(0, 1)["edge"] = 162 - self.assertEqual(graph_b[0]["a"], 42) - self.assertEqual(graph_a.get_edge_data(0, 1), {"edge": 162}) diff --git a/tests/retworkx_backwards_compat/digraph/test_core_number.py b/tests/retworkx_backwards_compat/digraph/test_core_number.py deleted file mode 100644 index b13a9a35be..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_core_number.py +++ /dev/null @@ -1,96 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCoreNumber(unittest.TestCase): - def setUp(self): - # This is the example graph in Figure 1 from Batagelj and - # Zaversnik's paper titled An O(m) Algorithm for Cores - # Decomposition of Networks, 2003, - # http://arXiv.org/abs/cs/0310049. With nodes labeled as - # shown, the 3-core is given by nodes 0-7, the 2-core by nodes - # 8-15, the 1-core by nodes 16-19 and node 20 is in the - # 0-core. - self.example_edges = [ - (0, 2), - (0, 3), - (0, 5), - (1, 4), - (1, 6), - (1, 7), - (2, 3), - (3, 5), - (2, 5), - (5, 6), - (4, 6), - (4, 7), - (6, 7), - (5, 8), - (6, 8), - (6, 9), - (8, 9), - (0, 10), - (1, 10), - (1, 11), - (10, 11), - (12, 13), - (13, 15), - (14, 15), - (12, 14), - (8, 19), - (11, 16), - (11, 17), - (12, 18), - ] - - example_core = {} - for i in range(8): - example_core[i] = 3 - for i in range(8, 16): - example_core[i] = 2 - for i in range(16, 20): - example_core[i] = 1 - example_core[20] = 0 - self.example_core = example_core - - def test_directed_empty(self): - digraph = retworkx.PyDiGraph() - res = retworkx.core_number(digraph) - self.assertIsInstance(res, dict) - self.assertEqual(res, {}) - - def test_directed_all_0(self): - digraph = retworkx.PyDiGraph() - digraph.add_nodes_from(list(range(4))) - res = retworkx.core_number(digraph) - self.assertIsInstance(res, dict) - self.assertEqual(res, {0: 0, 1: 0, 2: 0, 3: 0}) - - def test_directed_all_3(self): - digraph = retworkx.PyDiGraph() - digraph.add_nodes_from(list(range(4))) - digraph.add_edges_from_no_data([(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]) - res = retworkx.core_number(digraph) - self.assertIsInstance(res, dict) - self.assertEqual(res, {0: 3, 1: 3, 2: 3, 3: 3}) - - def test_directed_paper_example(self): - digraph = retworkx.PyDiGraph() - digraph.add_nodes_from(list(range(21))) - digraph.add_edges_from_no_data(self.example_edges) - res = retworkx.core_number(digraph) - self.assertIsInstance(res, dict) - self.assertEqual(res, self.example_core) diff --git a/tests/retworkx_backwards_compat/digraph/test_deepcopy.py b/tests/retworkx_backwards_compat/digraph/test_deepcopy.py deleted file mode 100644 index cdd41b14a1..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_deepcopy.py +++ /dev/null @@ -1,48 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import unittest - -import retworkx - - -class TestDeepcopy(unittest.TestCase): - def test_isomorphic_compare_nodes_identical(self): - dag_a = retworkx.PyDAG() - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "a_1") - dag_a.add_child(node_a, "a_3", "a_2") - dag_b = copy.deepcopy(dag_a) - self.assertTrue(retworkx.is_isomorphic_node_match(dag_a, dag_b, lambda x, y: x == y)) - - def test_deepcopy_with_holes(self): - dag_a = retworkx.PyDAG() - node_a = dag_a.add_node("a_1") - node_b = dag_a.add_node("a_2") - dag_a.add_edge(node_a, node_b, "edge_1") - node_c = dag_a.add_node("a_3") - dag_a.add_edge(node_b, node_c, "edge_2") - dag_a.remove_node(node_b) - dag_b = copy.deepcopy(dag_a) - self.assertIsInstance(dag_b, retworkx.PyDAG) - self.assertEqual([node_a, node_c], dag_b.node_indexes()) - - def test_deepcopy_empty(self): - dag = retworkx.PyDAG() - empty_copy = copy.deepcopy(dag) - self.assertEqual(len(empty_copy), 0) - - def test_deepcopy_attrs(self): - graph = retworkx.PyDiGraph(attrs="abc") - graph_copy = copy.deepcopy(graph) - self.assertEqual(graph.attrs, graph_copy.attrs) diff --git a/tests/retworkx_backwards_compat/digraph/test_depth.py b/tests/retworkx_backwards_compat/digraph/test_depth.py deleted file mode 100644 index 601bd51026..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_depth.py +++ /dev/null @@ -1,297 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestLongestPath(unittest.TestCase): - def test_linear(self): - """Longest depth for a simple dag. - - a - | - b - |\ - c d - |\ - e | - | | - f g - """ - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - node_c = dag.add_child(node_b, "c", {}) - dag.add_child(node_b, "d", {}) - node_e = dag.add_child(node_c, "e", {}) - node_f = dag.add_child(node_e, "f", {}) - dag.add_child(node_c, "g", {}) - self.assertEqual(4, retworkx.dag_longest_path_length(dag)) - self.assertEqual( - [node_a, node_b, node_c, node_e, node_f], - retworkx.dag_longest_path(dag), - ) - - def test_less_linear(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - node_c = dag.add_child(node_b, "c", {}) - node_d = dag.add_child(node_c, "d", {}) - node_e = dag.add_child(node_d, "e", {}) - dag.add_edge(node_a, node_c, {}) - dag.add_edge(node_a, node_e, {}) - dag.add_edge(node_c, node_e, {}) - self.assertEqual(4, retworkx.dag_longest_path_length(dag)) - self.assertEqual( - [node_a, node_b, node_c, node_d, node_e], - retworkx.dag_longest_path(dag), - ) - - def test_degenerate_graph(self): - dag = retworkx.PyDAG() - dag.add_node(0) - self.assertEqual(0, retworkx.dag_longest_path_length(dag)) - self.assertEqual([0], retworkx.dag_longest_path(dag)) - - def test_empty_graph(self): - dag = retworkx.PyDAG() - self.assertEqual(0, retworkx.dag_longest_path_length(dag)) - self.assertEqual([], retworkx.dag_longest_path(dag)) - - def test_parallel_edges(self): - dag = retworkx.PyDiGraph() - dag.extend_from_weighted_edge_list( - [ - (0, 1, 1), - (0, 3, 1), - (3, 4, 1), - (4, 5, 1), - (1, 2, 1), - (0, 1, 3), - ] - ) - self.assertEqual( - [0, 3, 4, 5], - retworkx.dag_longest_path(dag), - ) - - def test_linear_with_weight(self): - """Longest depth for a simple dag. - - a - | - b - |\ - c d - |\ - e | - | | - f g - """ - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 4) - node_c = dag.add_child(node_b, "c", 4) - dag.add_child(node_b, "d", 5) - node_e = dag.add_child(node_c, "e", 2) - dag.add_child(node_e, "f", 2) - node_g = dag.add_child(node_c, "g", 15) - self.assertEqual( - [node_a, node_b, node_c, node_g], - retworkx.dag_longest_path(dag, lambda _, __, weight: weight), - ) - self.assertEqual( - 23, - retworkx.dag_longest_path_length(dag, lambda _, __, weight: weight), - ) - - def test_parallel_edges_with_weights(self): - dag = retworkx.PyDiGraph() - dag.extend_from_weighted_edge_list( - [ - (0, 1, 1), - (0, 3, 1), - (3, 4, 1), - (4, 5, 1), - (1, 2, 1), - (0, 1, 3), - ] - ) - self.assertEqual( - [0, 1, 2], - retworkx.dag_longest_path(dag, lambda _, __, weight: weight), - ) - self.assertEqual( - 4, - retworkx.dag_longest_path_length(dag, weight_fn=lambda _, __, weight: weight), - ) - - def test_less_linear_with_weight(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 1) - node_c = dag.add_child(node_b, "c", 1) - node_d = dag.add_child(node_c, "d", 1) - node_e = dag.add_child(node_d, "e", 1) - dag.add_edge(node_a, node_c, 3) - dag.add_edge(node_a, node_e, 3) - dag.add_edge(node_c, node_e, 3) - self.assertEqual( - 6, - retworkx.dag_longest_path_length(dag, weight_fn=lambda _, __, weight: weight), - ) - self.assertEqual( - [node_a, node_c, node_e], - retworkx.dag_longest_path(dag, weight_fn=lambda _, __, weight: weight), - ) - - def test_degenerate_graph_with_weight(self): - dag = retworkx.PyDAG() - dag.add_node(0) - self.assertEqual([0], retworkx.dag_longest_path(dag, weight_fn=weight_fn)) - self.assertEqual(0, retworkx.dag_longest_path_length(dag, weight_fn=weight_fn)) - - def test_empty_graph_with_weights(self): - dag = retworkx.PyDAG() - self.assertEqual([], retworkx.dag_longest_path(dag, weight_fn=weight_fn)) - self.assertEqual(0, retworkx.dag_longest_path_length(dag, weight_fn=weight_fn)) - - def test_cycle(self): - not_a_dag = retworkx.generators.directed_cycle_graph(250) - with self.assertRaises(retworkx.DAGHasCycle): - retworkx.dag_longest_path_length(not_a_dag, lambda *_: 1.0) - with self.assertRaises(retworkx.DAGHasCycle): - retworkx.dag_longest_path(not_a_dag, lambda *_: 1.0) - - -def weight_fn(_, __, weight): - return int(weight) - - -class TestWeightedLongestPath(unittest.TestCase): - def test_linear_with_weight(self): - """Longest depth for a simple dag. - - a - | - b - |\ - c d - |\ - e | - | | - f g - """ - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 4) - node_c = dag.add_child(node_b, "c", 4) - dag.add_child(node_b, "d", 5) - node_e = dag.add_child(node_c, "e", 2) - dag.add_child(node_e, "f", 2) - node_g = dag.add_child(node_c, "g", 15) - self.assertEqual( - 23.0, - retworkx.dag_weighted_longest_path_length(dag, lambda _, __, weight: float(weight)), - ) - self.assertEqual( - [node_a, node_b, node_c, node_g], - retworkx.dag_weighted_longest_path(dag, lambda _, __, weight: float(weight)), - ) - - def test_parallel_edges_with_weights(self): - dag = retworkx.PyDiGraph() - dag.extend_from_weighted_edge_list( - [ - (0, 1, 1), - (0, 3, 1), - (3, 4, 1), - (4, 5, 1), - (1, 2, 1), - (0, 1, 3), - ] - ) - self.assertEqual( - 4.0, - retworkx.dag_weighted_longest_path_length( - dag, weight_fn=lambda _, __, weight: float(weight) - ), - ) - self.assertEqual( - [0, 1, 2], - retworkx.dag_weighted_longest_path(dag, lambda _, __, weight: float(weight)), - ) - - def test_less_linear_with_weight(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", 1) - node_c = dag.add_child(node_b, "c", 1) - node_d = dag.add_child(node_c, "d", 1) - node_e = dag.add_child(node_d, "e", 1) - dag.add_edge(node_a, node_c, 3) - dag.add_edge(node_a, node_e, 3) - dag.add_edge(node_c, node_e, 3) - self.assertEqual( - 6.0, - retworkx.dag_weighted_longest_path_length( - dag, weight_fn=lambda _, __, weight: float(weight) - ), - ) - self.assertEqual( - [node_a, node_c, node_e], - retworkx.dag_weighted_longest_path(dag, weight_fn=lambda _, __, weight: float(weight)), - ) - - def test_degenerate_graph_with_weight(self): - dag = retworkx.PyDAG() - dag.add_node(0) - self.assertEqual( - 0.0, - retworkx.dag_weighted_longest_path_length(dag, lambda x: float(weight_fn(x))), - ) - self.assertEqual( - [0], - retworkx.dag_weighted_longest_path(dag, lambda x: float(weight_fn(x))), - ) - - def test_empty_graph_with_weights(self): - dag = retworkx.PyDAG() - self.assertEqual( - 0.0, - retworkx.dag_weighted_longest_path_length(dag, lambda x: float(weight_fn(x))), - ) - self.assertEqual( - [], - retworkx.dag_weighted_longest_path(dag, lambda x: float(weight_fn(x))), - ) - - def test_nan_not_valid_weight(self): - dag = retworkx.generators.directed_path_graph(526) - - def weight_fn(*_): - return float("nan") - - with self.assertRaises(ValueError): - retworkx.dag_weighted_longest_path_length(dag, weight_fn) - with self.assertRaises(ValueError): - retworkx.dag_weighted_longest_path(dag, weight_fn) - - def test_cycle(self): - not_a_dag = retworkx.generators.directed_cycle_graph(250) - with self.assertRaises(retworkx.DAGHasCycle): - retworkx.dag_weighted_longest_path_length(not_a_dag, lambda *_: 1.0) - with self.assertRaises(retworkx.DAGHasCycle): - retworkx.dag_weighted_longest_path(not_a_dag, lambda *_: 1.0) diff --git a/tests/retworkx_backwards_compat/digraph/test_dfs_edges.py b/tests/retworkx_backwards_compat/digraph/test_dfs_edges.py deleted file mode 100644 index 054e170ece..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_dfs_edges.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDfsEdges(unittest.TestCase): - def test_digraph_disconnected_dfs_edges(self): - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list([(0, 1), (2, 3)]) - edges = retworkx.digraph_dfs_edges(graph) - expected = [(0, 1), (2, 3)] - self.assertEqual(expected, edges) - - def test_digraph_dfs_edges(self): - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)]) - edges = retworkx.digraph_dfs_edges(graph, 0) - expected = [(0, 1), (1, 2), (2, 4), (1, 3)] - self.assertEqual(expected, edges) diff --git a/tests/retworkx_backwards_compat/digraph/test_dfs_search.py b/tests/retworkx_backwards_compat/digraph/test_dfs_search.py deleted file mode 100644 index 8c099ae2e1..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_dfs_search.py +++ /dev/null @@ -1,106 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDfsSearch(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.graph.extend_from_edge_list( - [ - (0, 1), - (0, 2), - (1, 3), - (2, 1), - (2, 5), - (2, 6), - (5, 3), - (4, 7), - ] - ) - - def test_digraph_dfs_tree_edges(self): - class TreeEdgesRecorder(retworkx.visit.DFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.digraph_dfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 2), (2, 6), (2, 5), (5, 3), (2, 1)]) - - def test_digraph_dfs_tree_edges_no_starting_point(self): - class TreeEdgesRecorder(retworkx.visit.DFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.digraph_dfs_search(self.graph, None, vis) - self.assertEqual(vis.edges, [(0, 2), (2, 6), (2, 5), (5, 3), (2, 1), (4, 7)]) - - def test_digraph_dfs_tree_edges_restricted(self): - class TreeEdgesRecorderRestricted(retworkx.visit.DFSVisitor): - - prohibited = [(0, 1), (5, 3)] - - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - edge = (edge[0], edge[1]) - if edge in self.prohibited: - raise retworkx.visit.PruneSearch - self.edges.append(edge) - - vis = TreeEdgesRecorderRestricted() - retworkx.digraph_dfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 2), (2, 6), (2, 5), (2, 1), (1, 3)]) - - def test_digraph_dfs_goal_search(self): - class GoalSearch(retworkx.visit.DFSVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - - def tree_edge(self, edge): - u, v, _ = edge - self.parents[v] = u - - if v == self.goal: - raise retworkx.visit.StopSearch - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - try: - retworkx.digraph_dfs_search(self.graph, [0], vis) - except retworkx.visit.StopSearch: - pass - self.assertEqual(vis.reconstruct_path(), [0, 2, 5, 3]) diff --git a/tests/retworkx_backwards_compat/digraph/test_dijkstra.py b/tests/retworkx_backwards_compat/digraph/test_dijkstra.py deleted file mode 100644 index 0d7c6d47ad..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_dijkstra.py +++ /dev/null @@ -1,313 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDijkstraDiGraph(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - self.d = self.graph.add_node("D") - self.e = self.graph.add_node("E") - self.f = self.graph.add_node("F") - edge_list = [ - (self.a, self.b, 7), - (self.c, self.a, 9), - (self.a, self.d, 14), - (self.b, self.c, 10), - (self.d, self.c, 2), - (self.d, self.e, 9), - (self.b, self.f, 15), - (self.c, self.f, 11), - (self.e, self.f, 6), - ] - self.graph.add_edges_from(edge_list) - - def test_dijkstra(self): - path = retworkx.digraph_dijkstra_shortest_path_lengths( - self.graph, self.a, lambda x: float(x), self.e - ) - expected = {4: 23.0} - self.assertEqual(expected, path) - - def test_dijkstra_length_with_no_path(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - b = g.add_node("B") - path_lenghts = retworkx.digraph_dijkstra_shortest_path_lengths( - g, a, edge_cost_fn=float, goal=b - ) - expected = {} - self.assertEqual(expected, path_lenghts) - - def test_dijkstra_path(self): - paths = retworkx.digraph_dijkstra_shortest_paths(self.graph, self.a) - expected = { - # a -> b - 1: [0, 1], - # a -> c: a, d, c - 2: [0, 3, 2], - # a -> d - 3: [0, 3], - # a -> e: a, d, e - 4: [0, 3, 4], - # a -> f: a, b, f - 5: [0, 1, 5], - } - self.assertEqual(expected, paths) - - def test_dijkstra_path_with_weight_fn(self): - paths = retworkx.digraph_dijkstra_shortest_paths(self.graph, self.a, weight_fn=lambda x: x) - expected = { - 1: [0, 1], - 2: [0, 3, 2], - 3: [0, 3], - 4: [0, 3, 4], - 5: [0, 1, 5], - } - self.assertEqual(expected, paths) - - def test_dijkstra_path_with_target(self): - paths = retworkx.digraph_dijkstra_shortest_paths(self.graph, self.a, target=self.e) - expected = { - 4: [0, 3, 4], - } - self.assertEqual(expected, paths) - - def test_dijkstra_path_with_weight_fn_and_target(self): - paths = retworkx.digraph_dijkstra_shortest_paths( - self.graph, self.a, target=self.e, weight_fn=lambda x: x - ) - expected = { - 4: [0, 3, 4], - } - self.assertEqual(expected, paths) - - def test_dijkstra_path_undirected(self): - paths = retworkx.digraph_dijkstra_shortest_paths(self.graph, self.a, as_undirected=True) - expected = { - 1: [0, 1], - 2: [0, 2], - 3: [0, 3], - 4: [0, 3, 4], - 5: [0, 1, 5], - } - self.assertEqual(expected, paths) - - def test_dijkstra_path_undirected_with_weight_fn(self): - paths = retworkx.digraph_dijkstra_shortest_paths( - self.graph, self.a, weight_fn=lambda x: x, as_undirected=True - ) - expected = { - 1: [0, 1], - 2: [0, 2], - 3: [0, 2, 3], - 4: [0, 2, 3, 4], - 5: [0, 2, 5], - } - self.assertEqual(expected, paths) - - def test_dijkstra_path_undirected_with_target(self): - paths = retworkx.digraph_dijkstra_shortest_paths( - self.graph, self.a, target=self.e, as_undirected=True - ) - expected = { - 4: [0, 3, 4], - } - self.assertEqual(expected, paths) - - def test_dijkstra_path_undirected_with_weight_fn_and_target(self): - paths = retworkx.digraph_dijkstra_shortest_paths( - self.graph, - self.a, - target=self.e, - weight_fn=lambda x: x, - as_undirected=True, - ) - expected = { - 4: [0, 2, 3, 4], - } - self.assertEqual(expected, paths) - - def test_dijkstra_with_no_goal_set(self): - path = retworkx.digraph_dijkstra_shortest_path_lengths(self.graph, self.a, lambda x: 1) - expected = {1: 1.0, 2: 2.0, 3: 1.0, 4: 2.0, 5: 2.0} - self.assertEqual(expected, path) - - def test_dijkstra_with_no_path(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.digraph_dijkstra_shortest_path_lengths(g, a, lambda x: float(x)) - expected = {} - self.assertEqual(expected, path) - - def test_dijkstra_path_with_no_path(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.digraph_dijkstra_shortest_paths(g, a) - expected = {} - self.assertEqual(expected, path) - - def test_dijkstra_with_disconnected_nodes(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - b = g.add_child(a, "B", 1.2) - g.add_node("C") - g.add_parent(b, "D", 2.4) - path = retworkx.digraph_dijkstra_shortest_path_lengths(g, a, lambda x: x) - expected = {1: 1.2} - self.assertEqual(expected, path) - - def test_dijkstra_with_graph_input(self): - g = retworkx.PyGraph() - g.add_node(0) - with self.assertRaises(TypeError): - retworkx.digraph_dijkstra_shortest_path_lengths(g, 0, lambda x: x) - - def test_dijkstra_all_pair_path_lengths(self): - lengths = retworkx.digraph_all_pairs_dijkstra_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 16.0, 3: 14.0, 4: 23.0, 5: 22.0}, - 1: {0: 19.0, 2: 10.0, 3: 33.0, 4: 42.0, 5: 15.0}, - 2: {0: 9.0, 1: 16.0, 3: 23.0, 4: 32.0, 5: 11.0}, - 3: {0: 11.0, 1: 18.0, 2: 2.0, 4: 9.0, 5: 13.0}, - 4: {5: 6.0}, - 5: {}, - } - self.assertEqual(expected, lengths) - - def test_dijkstra_all_pair_paths(self): - paths = retworkx.digraph_all_pairs_dijkstra_shortest_paths(self.graph, float) - expected = { - 0: {1: [0, 1], 2: [0, 3, 2], 3: [0, 3], 4: [0, 3, 4], 5: [0, 1, 5]}, - 1: { - 0: [1, 2, 0], - 2: [1, 2], - 3: [1, 2, 0, 3], - 4: [1, 2, 0, 3, 4], - 5: [1, 5], - }, - 2: { - 0: [2, 0], - 1: [2, 0, 1], - 3: [2, 0, 3], - 4: [2, 0, 3, 4], - 5: [2, 5], - }, - 3: { - 0: [3, 2, 0], - 1: [3, 2, 0, 1], - 2: [3, 2], - 4: [3, 4], - 5: [3, 2, 5], - }, - 4: {5: [4, 5]}, - 5: {}, - } - self.assertEqual(expected, paths) - - def test_dijkstra_all_pair_path_lengths_with_node_removal(self): - self.graph.remove_node(3) - lengths = retworkx.digraph_all_pairs_dijkstra_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 17.0, 5: 22.0}, - 1: {0: 19.0, 2: 10.0, 5: 15.0}, - 2: {0: 9.0, 1: 16.0, 5: 11.0}, - 4: {5: 6.0}, - 5: {}, - } - self.assertEqual(expected, lengths) - - def test_dijkstra_all_pair_paths_with_node_removal(self): - self.graph.remove_node(3) - lengths = retworkx.digraph_all_pairs_dijkstra_shortest_paths(self.graph, float) - expected = { - 0: {1: [0, 1], 2: [0, 1, 2], 5: [0, 1, 5]}, - 1: {0: [1, 2, 0], 2: [1, 2], 5: [1, 5]}, - 2: {0: [2, 0], 1: [2, 0, 1], 5: [2, 5]}, - 4: {5: [4, 5]}, - 5: {}, - } - self.assertEqual(expected, lengths) - - def test_dijkstra_all_pair_path_lengths_empty_graph(self): - graph = retworkx.PyDiGraph() - self.assertEqual({}, retworkx.digraph_all_pairs_dijkstra_path_lengths(graph, float)) - - def test_dijkstra_all_pair_shortest_paths_empty_graph(self): - graph = retworkx.PyDiGraph() - self.assertEqual({}, retworkx.digraph_all_pairs_dijkstra_shortest_paths(graph, float)) - - def test_dijkstra_all_pair_path_lengths_graph_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.digraph_all_pairs_dijkstra_path_lengths(graph, float), - ) - - def test_dijkstra_all_pair_shortest_paths_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.digraph_all_pairs_dijkstra_shortest_paths(graph, float), - ) - - def dijkstra_with_invalid_weights(self): - graph = retworkx.generators.directed_path_graph(2) - for invalid_weight in [float("nan"), -1]: - for as_undirected in [False, True]: - with self.subTest(invalid_weight=invalid_weight, as_undirected=as_undirected): - with self.assertRaises(ValueError): - retworkx.digraph_dijkstra_shortest_paths( - graph, - source=0, - weight_fn=lambda _: invalid_weight, - as_undirected=as_undirected, - ) - - def dijkstra_lengths_with_invalid_weights(self): - graph = retworkx.generators.directed_path_graph(2) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.digraph_dijkstra_shortest_path_lengths( - graph, node=0, edge_cost_fn=lambda _: invalid_weight - ) - - def all_pairs_dijkstra_with_invalid_weights(self): - graph = retworkx.generators.directed_path_graph(2) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.digraph_all_pairs_dijkstra_shortest_paths( - graph, edge_cost_fn=lambda _: invalid_weight - ) - - def all_pairs_dijkstra_lenghts_with_invalid_weights(self): - graph = retworkx.generators.directed_path_graph(2) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.digraph_all_pairs_dijkstra_path_lengths( - graph, edge_cost_fn=lambda _: invalid_weight - ) diff --git a/tests/retworkx_backwards_compat/digraph/test_dijkstra_search.py b/tests/retworkx_backwards_compat/digraph/test_dijkstra_search.py deleted file mode 100644 index 9cd8e6d0e3..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_dijkstra_search.py +++ /dev/null @@ -1,189 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDijkstraSearch(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.graph.extend_from_weighted_edge_list( - [ - (0, 1, 1), - (0, 2, 2), - (1, 3, 10), - (2, 1, 1), - (2, 5, 1), - (2, 6, 1), - (5, 3, 1), - (4, 7, 1), - ] - ) - - def test_digraph_dijkstra_tree_edges(self): - class DijkstraTreeEdgesRecorder(retworkx.visit.DijkstraVisitor): - def __init__(self): - self.edges = [] - self.parents = dict() - - def discover_vertex(self, v, _): - u = self.parents.get(v, None) - if u is not None: - self.edges.append((u, v)) - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - vis = DijkstraTreeEdgesRecorder() - retworkx.digraph_dijkstra_search(self.graph, [0], float, vis) - self.assertEqual(vis.edges, [(0, 1), (0, 2), (2, 6), (2, 5), (5, 3)]) - - def test_digraph_dijkstra_tree_edges_no_starting_point(self): - class DijkstraTreeEdgesRecorder(retworkx.visit.DijkstraVisitor): - def __init__(self): - self.edges = [] - self.parents = dict() - - def discover_vertex(self, v, _): - u = self.parents.get(v, None) - if u is not None: - self.edges.append((u, v)) - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - vis = DijkstraTreeEdgesRecorder() - retworkx.digraph_dijkstra_search(self.graph, None, float, vis) - self.assertEqual(vis.edges, [(0, 1), (0, 2), (2, 6), (2, 5), (5, 3), (4, 7)]) - - def test_digraph_dijkstra_goal_search_with_stop_search_exception(self): - class GoalSearch(retworkx.visit.DijkstraVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - self.opt_goal_cost = None - - def discover_vertex(self, v, score): - if v == self.goal: - self.opt_goal_cost = score - raise retworkx.visit.StopSearch - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - retworkx.digraph_dijkstra_search(self.graph, [0], float, vis) - self.assertEqual(vis.reconstruct_path(), [0, 2, 5, 3]) - self.assertEqual(vis.opt_goal_cost, 4.0) - - def test_digraph_dijkstra_goal_search_with_custom_exception(self): - class StopIfGoalFound(Exception): - pass - - class GoalSearch(retworkx.visit.DijkstraVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - self.opt_goal_cost = None - - def discover_vertex(self, v, score): - if v == self.goal: - self.opt_goal_cost = score - raise StopIfGoalFound - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - try: - retworkx.digraph_dijkstra_search(self.graph, [0], float, vis) - except StopIfGoalFound: - pass - self.assertEqual(vis.reconstruct_path(), [0, 2, 5, 3]) - self.assertEqual(vis.opt_goal_cost, 4.0) - - def test_digraph_dijkstra_goal_search_with_prohibited_edges(self): - class GoalSearch(retworkx.visit.DijkstraVisitor): - - goal = 3 - prohibited = [(5, 3)] - - def __init__(self): - self.parents = {} - self.opt_goal_cost = None - - def discover_vertex(self, v, score): - if v == self.goal: - self.opt_goal_cost = score - raise retworkx.visit.StopSearch - - def examine_edge(self, edge): - u, v, _ = edge - if (u, v) in self.prohibited: - raise retworkx.visit.PruneSearch - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - retworkx.digraph_dijkstra_search(self.graph, [0], float, vis) - self.assertEqual(vis.reconstruct_path(), [0, 1, 3]) - self.assertEqual(vis.opt_goal_cost, 11.0) - - def test_digraph_prune_edge_not_relaxed(self): - class PruneEdgeNotRelaxed(retworkx.visit.DijkstraVisitor): - def edge_not_relaxed(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneEdgeNotRelaxed() - retworkx.digraph_dijkstra_search(self.graph, [0], float, vis) diff --git a/tests/retworkx_backwards_compat/digraph/test_dist_matrix.py b/tests/retworkx_backwards_compat/digraph/test_dist_matrix.py deleted file mode 100644 index 05459c4f27..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_dist_matrix.py +++ /dev/null @@ -1,140 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import numpy as np - -import retworkx - - -class TestDistanceMatrix(unittest.TestCase): - def test_digraph_distance_matrix(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.digraph_distance_matrix(graph) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 1.0], - [0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0], - [0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0], - [0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected)) - - def test_digraph_distance_matrix_parallel(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.digraph_distance_matrix(graph, parallel_threshold=5) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 1.0], - [0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0], - [0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0], - [0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected)) - - def test_digraph_distance_matrix_as_undirected(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.digraph_distance_matrix(graph, as_undirected=True) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected)) - - def test_digraph_distance_matrix_parallel_as_undirected(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.digraph_distance_matrix(graph, parallel_threshold=5, as_undirected=True) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected)) - - def test_digraph_distance_matrix_non_zero_null(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - graph.add_node(7) - dist = retworkx.distance_matrix(graph, as_undirected=True, null_value=np.nan) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, np.nan], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0, np.nan], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0, np.nan], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0, np.nan], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0, np.nan], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0, np.nan], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0, np.nan], - [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected, equal_nan=True)) - - def test_digraph_distance_matrix_parallel_non_zero_null(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - graph.add_node(7) - dist = retworkx.distance_matrix( - graph, as_undirected=True, parallel_threshold=5, null_value=np.nan - ) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, np.nan], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0, np.nan], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0, np.nan], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0, np.nan], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0, np.nan], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0, np.nan], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0, np.nan], - [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected, equal_nan=True)) - - def test_digraph_distance_matrix_node_hole(self): - graph = retworkx.generators.directed_path_graph(4) - graph.remove_node(0) - dist = retworkx.digraph_distance_matrix(graph) - expected = np.array([[0.0, 1.0, 2.0], [0.0, 0.0, 1.0], [0.0, 0.0, 0.0]]) - self.assertTrue(np.array_equal(dist, expected)) diff --git a/tests/retworkx_backwards_compat/digraph/test_dot.py b/tests/retworkx_backwards_compat/digraph/test_dot.py deleted file mode 100644 index fb2211c43d..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_dot.py +++ /dev/null @@ -1,73 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import tempfile -import unittest - -import retworkx - - -class TestDot(unittest.TestCase): - def setUp(self): - fd, self.path = tempfile.mkstemp() - os.close(fd) - os.remove(self.path) - - def test_digraph_to_dot_to_file(self): - graph = retworkx.PyDiGraph() - graph.add_node( - { - "color": "black", - "fillcolor": "green", - "label": "a", - "style": "filled", - } - ) - graph.add_node( - { - "color": "black", - "fillcolor": "red", - "label": "a", - "style": "filled", - } - ) - graph.add_edge(0, 1, dict(label="1", name="1")) - expected = ( - 'digraph {\n0 [color=black, fillcolor=green, label="a", ' - 'style=filled];\n1 [color=black, fillcolor=red, label="a", ' - 'style=filled];\n0 -> 1 [label="1", name=1];\n}\n' - ) - res = graph.to_dot(lambda node: node, lambda edge: edge, filename=self.path) - self.addCleanup(os.remove, self.path) - self.assertIsNone(res) - with open(self.path, "r") as fd: - res = fd.read() - self.assertEqual(expected, res) - - def test_digraph_empty_dicts(self): - graph = retworkx.directed_gnp_random_graph(3, 0.9, seed=42) - dot_str = graph.to_dot(lambda _: {}, lambda _: {}) - self.assertEqual("digraph {\n0 ;\n1 ;\n2 ;\n0 -> 1 ;\n0 -> 2 ;\n}\n", dot_str) - - def test_digraph_graph_attrs(self): - graph = retworkx.directed_gnp_random_graph(3, 0.9, seed=42) - dot_str = graph.to_dot(lambda _: {}, lambda _: {}, {"bgcolor": "red"}) - self.assertEqual( - "digraph {\nbgcolor=red ;\n0 ;\n1 ;\n2 ;\n0 -> 1 ;\n" "0 -> 2 ;\n}\n", - dot_str, - ) - - def test_digraph_no_args(self): - graph = retworkx.directed_gnp_random_graph(3, 0.95, seed=24) - dot_str = graph.to_dot() - self.assertEqual("digraph {\n0 ;\n1 ;\n2 ;\n0 -> 1 ;\n0 -> 2 ;\n}\n", dot_str) diff --git a/tests/retworkx_backwards_compat/digraph/test_edgelist.py b/tests/retworkx_backwards_compat/digraph/test_edgelist.py deleted file mode 100644 index 45ae47091b..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_edgelist.py +++ /dev/null @@ -1,213 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import tempfile -import unittest - -import retworkx - - -class TestEdgeList(unittest.TestCase): - def test_empty_edge_list_digraph(self): - with tempfile.NamedTemporaryFile() as fd: - graph = retworkx.PyDiGraph.read_edge_list(fd.name) - self.assertEqual(graph.nodes(), []) - - def test_invalid_path_digraph(self): - path = os.path.join(tempfile.gettempdir(), "fake_file_name.txt") - with self.assertRaises(FileNotFoundError): - retworkx.PyDiGraph.read_edge_list(path) - - def test_simple_example_digraph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1\n") - fd.write("1 2\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list(fd.name) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_blank_line_digraph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1\n") - fd.write("\n") - fd.write("1 2\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list(fd.name) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_comment_digraph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1 // test a comment\n") - fd.write("1 2\n") - fd.write("//2 3\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list(fd.name, comment="//") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_comment_leading_space_digraph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1 // test a comment\n") - fd.write("1 2\n") - fd.write(" //2 3\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list(fd.name, comment="//") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_weight_digraph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1 0// test a comment\n") - fd.write("1 2 1\n") - fd.write("//2 3\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list(fd.name, comment="//") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1"]) - - def test_delim_digraph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0|1|0// test a comment\n") - fd.write("1|2|1\n") - fd.write("//2|3\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list(fd.name, comment="//", deliminator="|") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1"]) - - def test_labels_digraph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("a|b|0// test a comment\n") - fd.write("b|c|1\n") - fd.write("//c|d\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list( - fd.name, comment="//", deliminator="|", labels=True - ) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1"]) - - def test_labels_digraph_target_existing(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("a|b|0// test a comment\n") - fd.write("b|c|1\n") - fd.write("a|c\n") - fd.flush() - graph = retworkx.PyDiGraph.read_edge_list( - fd.name, comment="//", deliminator="|", labels=True - ) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(1, 0)) - self.assertFalse(graph.has_edge(2, 1)) - self.assertTrue(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1", None]) - - def test_write_edge_list_empty_digraph(self): - path = os.path.join(tempfile.gettempdir(), "empty.txt") - graph = retworkx.PyDiGraph() - graph.write_edge_list(path) - self.addCleanup(os.remove, path) - with open(path, "rt") as edge_file: - self.assertEqual("", edge_file.read()) - - def test_write_edge_list_round_trip(self): - path = os.path.join(tempfile.gettempdir(), "round_trip.txt") - graph = retworkx.generators.directed_star_graph(5) - count = iter(range(5)) - - def weight_fn(edge): - return str(next(count)) - - graph.write_edge_list(path, weight_fn=weight_fn) - self.addCleanup(os.remove, path) - new_graph = retworkx.PyDiGraph.read_edge_list(path) - expected = [ - (0, 1, "0"), - (0, 2, "1"), - (0, 3, "2"), - (0, 4, "3"), - ] - self.assertEqual(expected, new_graph.weighted_edge_list()) - - def test_custom_delim(self): - path = os.path.join(tempfile.gettempdir(), "custom_delim.txt") - graph = retworkx.generators.directed_path_graph(5) - graph.write_edge_list(path, deliminator=",") - self.addCleanup(os.remove, path) - expected = """0,1 -1,2 -2,3 -3,4 -""" - with open(path, "rt") as edge_file: - self.assertEqual(edge_file.read(), expected) - - def test_invalid_return_type_weight_fn(self): - path = os.path.join(tempfile.gettempdir(), "fail.txt") - graph = retworkx.directed_gnm_random_graph(5, 4) - self.addCleanup(cleanup_file, path) - with self.assertRaises(TypeError): - graph.write_edge_list(path, weight_fn=lambda _: 4.5) - - def test_weight_fn_raises(self): - path = os.path.join(tempfile.gettempdir(), "fail.txt") - graph = retworkx.directed_gnm_random_graph(5, 4) - - def weight_fn(edge): - raise KeyError - - self.addCleanup(cleanup_file, path) - with self.assertRaises(KeyError): - graph.write_edge_list(path, weight_fn=weight_fn) - - -def cleanup_file(path): - try: - os.remove(path) - except Exception: - pass diff --git a/tests/retworkx_backwards_compat/digraph/test_edges.py b/tests/retworkx_backwards_compat/digraph/test_edges.py deleted file mode 100644 index 1552b3d50c..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_edges.py +++ /dev/null @@ -1,938 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestEdges(unittest.TestCase): - def test_get_edge_data(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - res = dag.get_edge_data(node_a, node_b) - self.assertEqual("Edgy", res) - - def test_get_all_edge_data(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_edge(node_a, node_b, "b") - res = dag.get_all_edge_data(node_a, node_b) - self.assertIn("b", res) - self.assertIn("Edgy", res) - - def test_no_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, dag.get_edge_data, node_a, node_b) - - def test_num_edges(self): - graph = retworkx.PyDiGraph() - graph.add_node(1) - graph.add_node(42) - graph.add_node(146) - graph.add_edges_from_no_data([(0, 1), (1, 2)]) - self.assertEqual(2, graph.num_edges()) - - def test_num_edges_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_node(1) - graph.add_node(42) - self.assertEqual(0, graph.num_edges()) - - def test_update_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "not edgy") - dag.update_edge(node_a, node_b, "Edgy") - self.assertEqual([(0, 1, "Edgy")], dag.weighted_edge_list()) - - def test_update_edge_no_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, dag.update_edge, node_a, node_b, None) - - def test_update_edge_by_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", "not edgy") - dag.update_edge_by_index(0, "Edgy") - self.assertEqual([(0, 1, "Edgy")], dag.weighted_edge_list()) - - def test_update_edge_invalid_index(self): - dag = retworkx.PyDAG() - dag.add_node("a") - dag.add_node("b") - self.assertRaises(IndexError, dag.update_edge_by_index, 0, None) - - def test_update_edge_parallel_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "not edgy") - edge_index = graph.add_edge(node_a, node_b, "not edgy") - graph.update_edge_by_index(edge_index, "Edgy") - self.assertEqual( - [(0, 1, "not edgy"), (0, 1, "Edgy")], - list(graph.weighted_edge_list()), - ) - - def test_has_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - self.assertTrue(dag.has_edge(node_a, node_b)) - - def test_has_edge_no_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - self.assertFalse(dag.has_edge(node_a, node_b)) - - def test_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_child(node_b, "c", "Super edgy") - self.assertEqual(["Edgy", "Super edgy"], dag.edges()) - - def test_edges_empty(self): - dag = retworkx.PyDAG() - dag.add_node("a") - self.assertEqual([], dag.edges()) - - def test_edge_indices(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_child(node_b, "c", "Super edgy") - self.assertEqual([0, 1], dag.edge_indices()) - - def test_edge_indices_empty(self): - dag = retworkx.PyDAG() - dag.add_node("a") - self.assertEqual([], dag.edge_indices()) - - def test_add_duplicates(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "a", "a") - dag.add_edge(node_a, node_b, "b") - self.assertEqual(["a", "b"], dag.edges()) - - def test_remove_no_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, dag.remove_edge, node_a, node_b) - - def test_remove_edge_single(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "edgy") - dag.remove_edge(node_a, node_b) - self.assertEqual([], dag.edges()) - - def test_remove_multiple(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "edgy") - dag.add_edge(node_a, node_b, "super_edgy") - dag.remove_edge_from_index(0) - self.assertEqual(["super_edgy"], dag.edges()) - - def test_remove_edges_from(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - node_c = graph.add_node("c") - graph.add_edge(node_a, node_b, "edgy") - graph.add_edge(node_a, node_c, "super_edgy") - graph.remove_edges_from([(node_a, node_b), (node_a, node_c)]) - self.assertEqual([], graph.edges()) - - def test_remove_edges_from_invalid(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - node_c = graph.add_node("c") - graph.add_edge(node_a, node_b, "edgy") - graph.add_edge(node_a, node_c, "super_edgy") - with self.assertRaises(retworkx.NoEdgeBetweenNodes): - graph.remove_edges_from([(node_b, node_c), (node_a, node_c)]) - - def test_remove_edge_from_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", "edgy") - dag.remove_edge_from_index(0) - self.assertEqual([], dag.edges()) - - def test_remove_edge_no_edge(self): - dag = retworkx.PyDAG() - dag.add_node("a") - dag.remove_edge_from_index(0) - self.assertEqual([], dag.edges()) - - def test_add_cycle(self): - dag = retworkx.PyDAG() - dag.check_cycle = True - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - self.assertRaises(retworkx.DAGWouldCycle, dag.add_edge, node_b, node_a, {}) - - def test_add_edge_with_cycle_check_enabled(self): - dag = retworkx.PyDAG(True) - node_a = dag.add_node("a") - node_c = dag.add_node("c") - node_b = dag.add_child(node_a, "b", {}) - dag.add_edge(node_c, node_b, {}) - self.assertTrue(dag.has_edge(node_c, node_b)) - - def test_enable_cycle_checking_after_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - dag.add_edge(node_b, node_a, {}) - with self.assertRaises(retworkx.DAGHasCycle): - dag.check_cycle = True - - def test_cycle_checking_at_init(self): - dag = retworkx.PyDAG(True) - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - with self.assertRaises(retworkx.DAGWouldCycle): - dag.add_edge(node_b, node_a, {}) - - def test_find_adjacent_node_by_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"weights": [1, 2]}) - dag.add_child(node_a, "c", {"weights": [3, 4]}) - - def compare_edges(edge): - return 4 in edge["weights"] - - res = dag.find_adjacent_node_by_edge(node_a, compare_edges) - self.assertEqual("c", res) - - def test_find_adjacent_node_by_edge_no_match(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"weights": [1, 2]}) - dag.add_child(node_a, "c", {"weights": [3, 4]}) - - def compare_edges(edge): - return 5 in edge["weights"] - - with self.assertRaises(retworkx.NoSuitableNeighbors): - dag.find_adjacent_node_by_edge(node_a, compare_edges) - - def test_add_edge_from(self): - dag = retworkx.PyDAG() - nodes = list(range(4)) - dag.add_nodes_from(nodes) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - res = dag.add_edges_from(edge_list) - self.assertEqual(len(res), 5) - self.assertEqual(["a", "b", "c", "d", "e"], dag.edges()) - self.assertEqual(3, dag.out_degree(0)) - self.assertEqual(0, dag.in_degree(0)) - self.assertEqual(1, dag.out_degree(1)) - self.assertEqual(1, dag.out_degree(2)) - self.assertEqual(2, dag.in_degree(3)) - - def test_add_edge_from_empty(self): - dag = retworkx.PyDAG() - res = dag.add_edges_from([]) - self.assertEqual([], res) - - def test_cycle_checking_at_init_nodes_from(self): - dag = retworkx.PyDAG(True) - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - node_c = dag.add_child(node_b, "c", {}) - with self.assertRaises(retworkx.DAGWouldCycle): - dag.add_edges_from([(node_a, node_c, {}), (node_c, node_b, {})]) - - def test_is_directed_acyclic_graph(self): - dag = retworkx.generators.directed_path_graph(1000) - res = retworkx.is_directed_acyclic_graph(dag) - self.assertTrue(res) - - def test_is_directed_acyclic_graph_false(self): - digraph = retworkx.generators.directed_cycle_graph(1000) - self.assertFalse(retworkx.is_directed_acyclic_graph(digraph)) - - def test_add_edge_from_no_data(self): - dag = retworkx.PyDAG() - nodes = list(range(4)) - dag.add_nodes_from(nodes) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - res = dag.add_edges_from_no_data(edge_list) - self.assertEqual(len(res), 5) - self.assertEqual([None, None, None, None, None], dag.edges()) - self.assertEqual(3, dag.out_degree(0)) - self.assertEqual(0, dag.in_degree(0)) - self.assertEqual(1, dag.out_degree(1)) - self.assertEqual(1, dag.out_degree(2)) - self.assertEqual(2, dag.in_degree(3)) - - def test_add_edge_from_empty_no_data(self): - dag = retworkx.PyDAG() - res = dag.add_edges_from_no_data([]) - self.assertEqual([], res) - - def test_cycle_checking_at_init_nodes_from_no_data(self): - dag = retworkx.PyDAG(True) - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - node_c = dag.add_child(node_b, "c", {}) - with self.assertRaises(retworkx.DAGWouldCycle): - dag.add_edges_from_no_data([(node_a, node_c), (node_c, node_b)]) - - def test_edge_list(self): - dag = retworkx.PyDiGraph() - dag.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - dag.add_edges_from(edge_list) - self.assertEqual([(x[0], x[1]) for x in edge_list], dag.edge_list()) - - def test_edge_list_empty(self): - dag = retworkx.PyDiGraph() - self.assertEqual([], dag.edge_list()) - - def test_weighted_edge_list(self): - dag = retworkx.PyDiGraph() - dag.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - dag.add_edges_from(edge_list) - self.assertEqual(edge_list, dag.weighted_edge_list()) - - def test_weighted_edge_list_empty(self): - dag = retworkx.PyDiGraph() - self.assertEqual([], dag.weighted_edge_list()) - - def test_extend_from_edge_list(self): - dag = retworkx.PyDAG() - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - dag.extend_from_edge_list(edge_list) - self.assertEqual(len(dag), 4) - self.assertEqual([None] * 5, dag.edges()) - self.assertEqual(3, dag.out_degree(0)) - self.assertEqual(0, dag.in_degree(0)) - self.assertEqual(1, dag.out_degree(1)) - self.assertEqual(1, dag.out_degree(2)) - self.assertEqual(2, dag.in_degree(3)) - - def test_extend_from_edge_list_empty(self): - dag = retworkx.PyDAG() - dag.extend_from_edge_list([]) - self.assertEqual(0, len(dag)) - - def test_cycle_checking_at_init_extend_from_weighted_edge_list(self): - dag = retworkx.PyDAG(True) - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - node_c = dag.add_child(node_b, "c", {}) - with self.assertRaises(retworkx.DAGWouldCycle): - dag.extend_from_weighted_edge_list([(node_a, node_c, {}), (node_c, node_b, {})]) - - def test_extend_from_edge_list_nodes_exist(self): - dag = retworkx.PyDiGraph() - dag.add_nodes_from(list(range(4))) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - dag.extend_from_edge_list(edge_list) - self.assertEqual(len(dag), 4) - self.assertEqual([None] * 5, dag.edges()) - self.assertEqual(3, dag.out_degree(0)) - self.assertEqual(0, dag.in_degree(0)) - self.assertEqual(1, dag.out_degree(1)) - self.assertEqual(1, dag.out_degree(2)) - self.assertEqual(2, dag.in_degree(3)) - - def test_extend_from_weighted_edge_list(self): - dag = retworkx.PyDAG() - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - dag.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(dag), 4) - self.assertEqual(["a", "b", "c", "d", "e"], dag.edges()) - self.assertEqual(3, dag.out_degree(0)) - self.assertEqual(0, dag.in_degree(0)) - self.assertEqual(1, dag.out_degree(1)) - self.assertEqual(1, dag.out_degree(2)) - self.assertEqual(2, dag.in_degree(3)) - - def test_extend_from_weighted_edge_list_empty(self): - dag = retworkx.PyDAG() - dag.extend_from_weighted_edge_list([]) - self.assertEqual(0, len(dag)) - - def test_cycle_checking_at_init_nodes_extend_from_edge_list(self): - dag = retworkx.PyDAG(True) - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - node_c = dag.add_child(node_b, "c", {}) - with self.assertRaises(retworkx.DAGWouldCycle): - dag.extend_from_edge_list([(node_a, node_c), (node_c, node_b)]) - - def test_extend_from_weighted_edge_list_nodes_exist(self): - dag = retworkx.PyDiGraph() - dag.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - dag.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(dag), 4) - self.assertEqual(["a", "b", "c", "d", "e"], dag.edges()) - self.assertEqual(3, dag.out_degree(0)) - self.assertEqual(0, dag.in_degree(0)) - self.assertEqual(1, dag.out_degree(1)) - self.assertEqual(1, dag.out_degree(2)) - self.assertEqual(2, dag.in_degree(3)) - - def test_insert_node_on_in_edges(self): - graph = retworkx.PyDiGraph() - in_node = graph.add_node("qr[0]") - out_node = graph.add_child(in_node, "qr[0]", "qr[0]") - h_gate = graph.add_node("h") - graph.insert_node_on_in_edges(h_gate, out_node) - self.assertEqual( - [(in_node, h_gate, "qr[0]"), (h_gate, out_node, "qr[0]")], - graph.weighted_edge_list(), - ) - - def test_insert_node_on_in_edges_multiple(self): - graph = retworkx.PyDiGraph() - in_node_0 = graph.add_node("qr[0]") - out_node_0 = graph.add_child(in_node_0, "qr[0]", "qr[0]") - in_node_1 = graph.add_node("qr[1]") - out_node_1 = graph.add_child(in_node_1, "qr[1]", "qr[1]") - cx_gate = graph.add_node("cx") - graph.insert_node_on_in_edges_multiple(cx_gate, [out_node_0, out_node_1]) - self.assertEqual( - { - (in_node_0, cx_gate, "qr[0]"), - (cx_gate, out_node_0, "qr[0]"), - (in_node_1, cx_gate, "qr[1]"), - (cx_gate, out_node_1, "qr[1]"), - }, - set(graph.weighted_edge_list()), - ) - - def test_insert_node_on_in_edges_double(self): - graph = retworkx.PyDiGraph() - in_node = graph.add_node("qr[0]") - out_node = graph.add_child(in_node, "qr[0]", "qr[0]") - h_gate = graph.add_node("h") - z_gate = graph.add_node("z") - graph.insert_node_on_in_edges(h_gate, out_node) - graph.insert_node_on_in_edges(z_gate, out_node) - self.assertEqual( - { - (in_node, h_gate, "qr[0]"), - (h_gate, z_gate, "qr[0]"), - (z_gate, out_node, "qr[0]"), - }, - set(graph.weighted_edge_list()), - ) - - def test_insert_node_on_in_edges_multiple_double(self): - graph = retworkx.PyDiGraph() - in_node_0 = graph.add_node("qr[0]") - out_node_0 = graph.add_child(in_node_0, "qr[0]", "qr[0]") - in_node_1 = graph.add_node("qr[1]") - out_node_1 = graph.add_child(in_node_1, "qr[1]", "qr[1]") - cx_gate = graph.add_node("cx") - cz_gate = graph.add_node("cz") - graph.insert_node_on_in_edges_multiple(cx_gate, [out_node_0, out_node_1]) - graph.insert_node_on_in_edges_multiple(cz_gate, [out_node_0, out_node_1]) - self.assertEqual( - { - (in_node_0, cx_gate, "qr[0]"), - (cx_gate, cz_gate, "qr[0]"), - (in_node_1, cx_gate, "qr[1]"), - (cx_gate, cz_gate, "qr[1]"), - (cz_gate, out_node_0, "qr[0]"), - (cz_gate, out_node_1, "qr[1]"), - }, - set(graph.weighted_edge_list()), - ) - - def test_insert_node_on_out_edges(self): - graph = retworkx.PyDiGraph() - in_node = graph.add_node("qr[0]") - out_node = graph.add_child(in_node, "qr[0]", "qr[0]") - h_gate = graph.add_node("h") - graph.insert_node_on_out_edges(h_gate, in_node) - self.assertEqual( - {(in_node, h_gate, "qr[0]"), (h_gate, out_node, "qr[0]")}, - set(graph.weighted_edge_list()), - ) - - def test_insert_node_on_out_edges_multiple(self): - graph = retworkx.PyDiGraph() - in_node_0 = graph.add_node("qr[0]") - out_node_0 = graph.add_child(in_node_0, "qr[0]", "qr[0]") - in_node_1 = graph.add_node("qr[1]") - out_node_1 = graph.add_child(in_node_1, "qr[1]", "qr[1]") - cx_gate = graph.add_node("cx") - graph.insert_node_on_out_edges_multiple(cx_gate, [in_node_0, in_node_1]) - self.assertEqual( - { - (in_node_0, cx_gate, "qr[0]"), - (cx_gate, out_node_0, "qr[0]"), - (in_node_1, cx_gate, "qr[1]"), - (cx_gate, out_node_1, "qr[1]"), - }, - set(graph.weighted_edge_list()), - ) - - def test_insert_node_on_out_edges_double(self): - graph = retworkx.PyDiGraph() - in_node = graph.add_node("qr[0]") - out_node = graph.add_child(in_node, "qr[0]", "qr[0]") - h_gate = graph.add_node("h") - z_gate = graph.add_node("z") - graph.insert_node_on_out_edges(h_gate, in_node) - graph.insert_node_on_out_edges(z_gate, in_node) - self.assertEqual( - { - (in_node, z_gate, "qr[0]"), - (z_gate, h_gate, "qr[0]"), - (h_gate, out_node, "qr[0]"), - }, - set(graph.weighted_edge_list()), - ) - - def test_insert_node_on_out_edges_multiple_double(self): - graph = retworkx.PyDiGraph() - in_node_0 = graph.add_node("qr[0]") - out_node_0 = graph.add_child(in_node_0, "qr[0]", "qr[0]") - in_node_1 = graph.add_node("qr[1]") - out_node_1 = graph.add_child(in_node_1, "qr[1]", "qr[1]") - cx_gate = graph.add_node("cx") - cz_gate = graph.add_node("cz") - graph.insert_node_on_out_edges_multiple(cx_gate, [in_node_0, in_node_1]) - graph.insert_node_on_out_edges_multiple(cz_gate, [in_node_0, in_node_1]) - self.assertEqual( - { - (in_node_0, cz_gate, "qr[0]"), - (cz_gate, cx_gate, "qr[0]"), - (in_node_1, cz_gate, "qr[1]"), - (cz_gate, cx_gate, "qr[1]"), - (cx_gate, out_node_0, "qr[0]"), - (cx_gate, out_node_1, "qr[1]"), - }, - set(graph.weighted_edge_list()), - ) - - def test_insert_node_on_in_edges_no_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(None) - node_b = graph.add_node(None) - graph.insert_node_on_in_edges(node_b, node_a) - self.assertEqual([], graph.edge_list()) - - def test_insert_node_on_in_edges_multiple_no_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(None) - node_b = graph.add_node(None) - graph.insert_node_on_in_edges_multiple(node_b, [node_a]) - self.assertEqual([], graph.edge_list()) - - def test_insert_node_on_out_edges_no_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(None) - node_b = graph.add_node(None) - graph.insert_node_on_out_edges(node_b, node_a) - self.assertEqual([], graph.edge_list()) - - def test_insert_node_on_out_edges_multiple_no_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(None) - node_b = graph.add_node(None) - graph.insert_node_on_out_edges_multiple(node_b, [node_a]) - self.assertEqual([], graph.edge_list()) - - def test_edge_index_map(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_child(node_a, "c", "edge a") - node_d = graph.add_parent(node_b, "d", "edge_b") - graph.add_edge(node_c, node_d, "edge c") - self.assertEqual( - { - 0: (node_a, node_c, "edge a"), - 1: (node_d, node_b, "edge_b"), - 2: (node_c, node_d, "edge c"), - }, - graph.edge_index_map(), - ) - - def test_edge_index_map_empty(self): - graph = retworkx.PyDiGraph() - self.assertEqual({}, graph.edge_index_map()) - - def test_has_parallel_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0, 1]) - graph.add_edge(0, 1, None) - graph.add_edge(0, 1, 0) - self.assertTrue(graph.has_parallel_edges()) - - def test_has_parallel_edges_no_parallel_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0, 1]) - graph.add_edge(0, 1, None) - self.assertFalse(graph.has_parallel_edges()) - - def test_has_parallel_edges_empty(self): - graph = retworkx.PyDiGraph() - self.assertFalse(graph.has_parallel_edges()) - - def test_get_edge_data_by_index(self): - graph = retworkx.PyDiGraph() - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - res = graph.get_edge_data_by_index(2) - self.assertEqual("c", res) - - def test_get_edge_data_by_index_invalid_index(self): - graph = retworkx.PyDiGraph() - with self.assertRaisesRegex( - IndexError, "Provided edge index 2 is not present in the graph" - ): - graph.get_edge_data_by_index(2) - - def test_get_edge_endpoints_by_index(self): - graph = retworkx.PyDiGraph() - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - res = graph.get_edge_endpoints_by_index(2) - self.assertEqual((0, 2), res) - - def test_get_edge_endpoints_by_index_invalid_index(self): - graph = retworkx.PyDiGraph() - with self.assertRaisesRegex( - IndexError, "Provided edge index 2 is not present in the graph" - ): - graph.get_edge_endpoints_by_index(2) - - def test_incident_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_node("c") - node_d = graph.add_node("d") - graph.add_edge(node_a, node_c, "edge a") - graph.add_edge(node_b, node_d, "edge_b") - graph.add_edge(node_d, node_c, "edge c") - res = graph.incident_edges(node_d) - self.assertEqual([2], res) - - def test_incident_edges_invalid_node(self): - graph = retworkx.PyDiGraph() - res = graph.incident_edges(42) - self.assertEqual([], res) - - def test_incident_edges_all_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_node("c") - node_d = graph.add_node("d") - graph.add_edge(node_a, node_c, "edge a") - graph.add_edge(node_b, node_d, "edge_b") - graph.add_edge(node_d, node_c, "edge c") - res = graph.incident_edges(node_d, all_edges=True) - self.assertEqual([2, 1], res) - - def test_incident_edge_index_map(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_node("c") - node_d = graph.add_node("d") - graph.add_edge(node_a, node_c, "edge a") - graph.add_edge(node_b, node_d, "edge_b") - graph.add_edge(node_d, node_c, "edge c") - res = graph.incident_edge_index_map(node_d) - self.assertEqual({2: (3, 2, "edge c")}, res) - - def test_incident_edge_index_map_invalid_node(self): - graph = retworkx.PyDiGraph() - res = graph.incident_edge_index_map(42) - self.assertEqual([], res) - - def test_incident_edge_index_map_all_edges(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_node("c") - node_d = graph.add_node("d") - graph.add_edge(node_a, node_c, "edge a") - graph.add_edge(node_b, node_d, "edge_b") - graph.add_edge(node_d, node_c, "edge c") - res = graph.incident_edge_index_map(node_d, all_edges=True) - self.assertEqual({2: (3, 2, "edge c"), 1: (1, 3, "edge_b")}, res) - - -class TestEdgesMultigraphFalse(unittest.TestCase): - def test_multigraph_attr(self): - graph = retworkx.PyDiGraph(multigraph=False) - self.assertFalse(graph.multigraph) - - def test_has_parallel_edges(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.add_nodes_from([0, 1]) - graph.add_edge(0, 1, None) - graph.add_edge(0, 1, 0) - self.assertFalse(graph.has_parallel_edges()) - - def test_get_edge_data(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - res = graph.get_edge_data(node_a, node_b) - self.assertEqual("Edgy", res) - - def test_get_all_edge_data(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - graph.add_edge(node_a, node_b, "b") - res = graph.get_all_edge_data(node_a, node_b) - self.assertIn("b", res) - self.assertNotIn("Edgy", res) - - def test_no_edge(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.get_edge_data, node_a, node_b) - - def test_no_edge_get_all_edge_data(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.get_all_edge_data, node_a, node_b) - - def test_has_edge(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, {}) - self.assertTrue(graph.has_edge(node_a, node_b)) - - def test_has_edge_no_edge(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertFalse(graph.has_edge(node_a, node_b)) - - def test_edges(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Super edgy") - self.assertEqual(["Edgy", "Super edgy"], graph.edges()) - - def test_edges_empty(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.add_node("a") - self.assertEqual([], graph.edges()) - - def test_add_duplicates(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "a") - graph.add_edge(node_a, node_b, "b") - self.assertEqual(["b"], graph.edges()) - - def test_remove_no_edge(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.remove_edge, node_a, node_b) - - def test_remove_edge_single(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.remove_edge(node_a, node_b) - self.assertEqual([], graph.edges()) - - def test_remove_multiple(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.add_edge(node_a, node_b, "super_edgy") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_remove_edge_from_index(self): - graph = retworkx.PyDiGraph(multigraph=False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_remove_edge_no_edge(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.add_node("a") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_add_edge_from_empty(self): - graph = retworkx.PyDiGraph(multigraph=False) - res = graph.add_edges_from([]) - self.assertEqual([], res) - - def test_add_edge_from_empty_no_data(self): - graph = retworkx.PyDiGraph(multigraph=False) - res = graph.add_edges_from_no_data([]) - self.assertEqual([], res) - - def test_add_edges_from_parallel_edges(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.add_nodes_from([0, 1]) - res = graph.add_edges_from([(0, 1, False), (0, 1, True)]) - self.assertEqual([0, 0], res) - self.assertEqual([True], graph.edges()) - - def test_add_edges_from_no_data_parallel_edges(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.add_nodes_from([0, 1]) - res = graph.add_edges_from_no_data([(0, 1), (0, 1)]) - self.assertEqual([0, 0], res) - self.assertEqual([None], graph.edges()) - - def test_extend_from_weighted_edge_list_empty(self): - graph = retworkx.PyDiGraph() - graph.extend_from_weighted_edge_list([]) - self.assertEqual(0, len(graph)) - - def test_extend_from_weighted_edge_list_nodes_exist(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["a", "b", "c", "d", "e"], graph.edges()) - - def test_extend_from_weighted_edge_list_edges_exist(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - (0, 1, "not_a"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["not_a", "b", "c", "d", "e"], graph.edges()) - - def test_extend_from_edge_list(self): - graph = retworkx.PyDiGraph(multigraph=False) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 5, graph.edges()) - - def test_extend_from_edge_list_empty(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.extend_from_edge_list([]) - self.assertEqual(0, len(graph)) - - def test_extend_from_edge_list_existing_edge(self): - graph = retworkx.PyDiGraph(multigraph=False) - graph.add_nodes_from(list(range(4))) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3), (0, 1)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 5, graph.edges()) - - def test_extend_from_weighted_edge_list(self): - graph = retworkx.PyDiGraph(multigraph=False) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["a", "b", "c", "d", "e"], graph.edges()) diff --git a/tests/retworkx_backwards_compat/digraph/test_find_cycle.py b/tests/retworkx_backwards_compat/digraph/test_find_cycle.py deleted file mode 100644 index 6ecdf77e33..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_find_cycle.py +++ /dev/null @@ -1,72 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestFindCycle(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.graph.add_nodes_from(list(range(10))) - self.graph.add_edges_from_no_data( - [ - (0, 1), - (3, 0), - (0, 5), - (8, 0), - (1, 2), - (1, 6), - (2, 3), - (3, 4), - (4, 5), - (6, 7), - (7, 8), - (8, 9), - ] - ) - - def test_find_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(6))) - graph.add_edges_from_no_data( - [(0, 1), (0, 3), (0, 5), (1, 2), (2, 3), (3, 4), (4, 5), (4, 0)] - ) - res = retworkx.digraph_find_cycle(graph, 0) - self.assertEqual([(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)], res) - - def test_find_cycle_multiple_roots_same_cycles(self): - res = retworkx.digraph_find_cycle(self.graph, 0) - self.assertEqual(res, [(0, 1), (1, 2), (2, 3), (3, 0)]) - res = retworkx.digraph_find_cycle(self.graph, 1) - self.assertEqual(res, [(1, 2), (2, 3), (3, 0), (0, 1)]) - res = retworkx.digraph_find_cycle(self.graph, 5) - self.assertEqual(res, []) - - def test_find_cycle_disconnected_graphs(self): - self.graph.add_nodes_from(["A", "B", "C"]) - self.graph.add_edges_from_no_data([(10, 11), (12, 10), (11, 12)]) - res = retworkx.digraph_find_cycle(self.graph, 0) - self.assertEqual(res, [(0, 1), (1, 2), (2, 3), (3, 0)]) - res = retworkx.digraph_find_cycle(self.graph, 10) - self.assertEqual(res, [(10, 11), (11, 12), (12, 10)]) - - def test_invalid_types(self): - graph = retworkx.PyGraph() - with self.assertRaises(TypeError): - retworkx.digraph_find_cycle(graph) - - def test_self_loop(self): - self.graph.add_edge(1, 1, None) - res = retworkx.digraph_find_cycle(self.graph, 0) - self.assertEqual([(1, 1)], res) diff --git a/tests/retworkx_backwards_compat/digraph/test_floyd_warshall.py b/tests/retworkx_backwards_compat/digraph/test_floyd_warshall.py deleted file mode 100644 index 1643eb5dcb..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_floyd_warshall.py +++ /dev/null @@ -1,294 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import numpy - -import retworkx - - -class TestFloydWarshall(unittest.TestCase): - parallel_threshold = 300 - - def test_floyd_warshall(self): - """Test the algorithm on a 5q x 4 depth circuit.""" - dag = retworkx.PyDAG() - # inputs - qr_0 = dag.add_node("qr[0]") - qr_1 = dag.add_node("qr[1]") - qr_2 = dag.add_node("qr[2]") - cr_0 = dag.add_node("cr[0]") - cr_1 = dag.add_node("cr[1]") - # wires - cx_1 = dag.add_node("cx_1") - dag.add_edge(qr_0, cx_1, "qr[0]") - dag.add_edge(qr_1, cx_1, "qr[1]") - h_1 = dag.add_node("h_1") - dag.add_edge(cx_1, h_1, "qr[0]") - cx_2 = dag.add_node("cx_2") - dag.add_edge(cx_1, cx_2, "qr[1]") - dag.add_edge(qr_2, cx_2, "qr[2]") - cx_3 = dag.add_node("cx_3") - dag.add_edge(h_1, cx_3, "qr[0]") - dag.add_edge(cx_2, cx_3, "qr[2]") - h_2 = dag.add_node("h_2") - dag.add_edge(cx_3, h_2, "qr[2]") - # # outputs - qr_0_out = dag.add_node("qr[0]_out") - dag.add_edge(cx_3, qr_0_out, "qr[0]") - qr_1_out = dag.add_node("qr[1]_out") - dag.add_edge(cx_2, qr_1_out, "qr[1]") - qr_2_out = dag.add_node("qr[2]_out") - dag.add_edge(h_2, qr_2_out, "qr[2]") - cr_0_out = dag.add_node("cr[0]_out") - dag.add_edge(cr_0, cr_0_out, "qr[2]") - cr_1_out = dag.add_node("cr[1]_out") - dag.add_edge(cr_1, cr_1_out, "cr[1]") - - result = retworkx.floyd_warshall(dag) - expected = { - 0: {0: 0, 5: 1, 6: 2, 7: 2, 8: 3, 9: 4, 10: 4, 11: 3, 12: 5}, - 1: {1: 0, 5: 1, 6: 2, 7: 2, 8: 3, 9: 4, 10: 4, 11: 3, 12: 5}, - 2: {2: 0, 7: 1, 8: 2, 9: 3, 10: 3, 11: 2, 12: 4}, - 3: {3: 0, 13: 1}, - 4: {4: 0, 14: 1}, - 5: {5: 0, 6: 1, 7: 1, 8: 2, 9: 3, 10: 3, 11: 2, 12: 4}, - 6: {6: 0, 8: 1, 9: 2, 10: 2, 12: 3}, - 7: {7: 0, 8: 1, 9: 2, 10: 2, 11: 1, 12: 3}, - 8: {8: 0, 9: 1, 10: 1, 12: 2}, - 9: {9: 0, 12: 1}, - 10: {10: 0}, - 11: {11: 0}, - 12: {12: 0}, - 13: {13: 0}, - 14: {14: 0}, - } - - self.assertEqual(result, expected) - - def test_vs_dijkstra_all_pairs(self): - graph = retworkx.PyDiGraph() - a = graph.add_node("A") - b = graph.add_node("B") - c = graph.add_node("C") - d = graph.add_node("D") - e = graph.add_node("E") - f = graph.add_node("F") - edge_list = [ - (a, b, 7), - (c, a, 9), - (a, d, 14), - (b, c, 10), - (d, c, 2), - (d, e, 9), - (b, f, 15), - (c, f, 11), - (e, f, 6), - ] - graph.add_edges_from(edge_list) - - dijkstra_lengths = retworkx.digraph_all_pairs_dijkstra_path_lengths(graph, float) - - expected = {k: {**v, k: 0.0} for k, v in dijkstra_lengths.items()} - - result = retworkx.digraph_floyd_warshall( - graph, float, parallel_threshold=self.parallel_threshold - ) - - self.assertEqual(result, expected) - - def test_vs_dijkstra_all_pairs_with_node_removal(self): - graph = retworkx.PyDiGraph() - a = graph.add_node("A") - b = graph.add_node("B") - c = graph.add_node("C") - d = graph.add_node("D") - e = graph.add_node("E") - f = graph.add_node("F") - edge_list = [ - (a, b, 7), - (c, a, 9), - (a, d, 14), - (b, c, 10), - (d, c, 2), - (d, e, 9), - (b, f, 15), - (c, f, 11), - (e, f, 6), - ] - graph.add_edges_from(edge_list) - graph.remove_node(d) - - dijkstra_lengths = retworkx.digraph_all_pairs_dijkstra_path_lengths(graph, float) - - expected = {k: {**v, k: 0.0} for k, v in dijkstra_lengths.items()} - - result = retworkx.digraph_floyd_warshall( - graph, float, parallel_threshold=self.parallel_threshold - ) - - self.assertEqual(result, expected) - - def test_floyd_warshall_empty_graph(self): - graph = retworkx.PyDiGraph() - self.assertEqual({}, retworkx.digraph_floyd_warshall(graph, float)) - - def test_floyd_warshall_graph_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.digraph_floyd_warshall(graph, float), - ) - - def test_directed_floyd_warshall_cycle_as_undirected(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.digraph_floyd_warshall( - graph, - lambda _: 1, - as_undirected=True, - parallel_threshold=self.parallel_threshold, - ) - expected = { - 0: {0: 0.0, 1: 1.0, 2: 2.0, 3: 3.0, 4: 3.0, 5: 2.0, 6: 1.0}, - 1: {0: 1.0, 1: 0.0, 2: 1.0, 3: 2.0, 4: 3.0, 5: 3.0, 6: 2.0}, - 2: {0: 2.0, 1: 1.0, 2: 0.0, 3: 1.0, 4: 2.0, 5: 3.0, 6: 3.0}, - 3: {0: 3.0, 1: 2.0, 2: 1.0, 3: 0.0, 4: 1.0, 5: 2.0, 6: 3.0}, - 4: {0: 3.0, 1: 3.0, 2: 2.0, 3: 1.0, 4: 0.0, 5: 1.0, 6: 2.0}, - 5: {0: 2.0, 1: 3.0, 2: 3.0, 3: 2.0, 4: 1.0, 5: 0.0, 6: 1.0}, - 6: {0: 1.0, 1: 2.0, 2: 3.0, 3: 3.0, 4: 2.0, 5: 1.0, 6: 0.0}, - } - self.assertEqual(dist, expected) - - def test_directed_floyd_warshall_numpy_cycle_as_undirected(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.digraph_floyd_warshall_numpy(graph, lambda x: 1, as_undirected=True) - expected = numpy.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0], - ] - ) - self.assertTrue(numpy.array_equal(dist, expected)) - - def test_floyd_warshall_numpy_digraph_three_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(6))) - weights = [2, 12, 1, 5, 1] - graph.add_edges_from([(i, i + 1, weights[i]) for i in range(5)]) - graph.add_edge(5, 0, 10) - dist = retworkx.digraph_floyd_warshall_numpy( - graph, lambda x: x, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 15) - self.assertEqual(dist[3, 0], 16) - - def test_weighted_numpy_digraph_two_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(8))) - graph.add_edges_from( - [ - (0, 1, 2), - (1, 2, 2), - (2, 3, 1), - (3, 4, 1), - (4, 5, 1), - (5, 6, 1), - (6, 7, 1), - (7, 0, 1), - ] - ) - dist = retworkx.digraph_floyd_warshall_numpy( - graph, lambda x: x, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 2], 4) - self.assertEqual(dist[2, 0], 6) - - def test_floyd_warshall_numpy_digraph_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.digraph_floyd_warshall_numpy( - graph, lambda x: 1, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 3) - self.assertEqual(dist[0, 4], 4) - - def test_weighted_numpy_directed_negative_cycle(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - dist = retworkx.digraph_floyd_warshall_numpy(graph, lambda x: x) - self.assertTrue(numpy.all(numpy.diag(dist) < 0)) - - def test_numpy_directed_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - dist = retworkx.digraph_floyd_warshall_numpy( - graph, lambda x: x, parallel_threshold=self.parallel_threshold - ) - expected = numpy.full((4, 4), numpy.inf) - numpy.fill_diagonal(expected, 0) - self.assertTrue(numpy.array_equal(dist, expected)) - - def test_floyd_warshall_numpy_digraph_cycle_with_removals(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(8))) - graph.remove_node(0) - graph.add_edges_from_no_data([(1, 2), (1, 7), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]) - dist = retworkx.digraph_floyd_warshall_numpy( - graph, lambda x: 1, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 3) - self.assertEqual(dist[0, 4], 4) - - def test_floyd_warshall_numpy_digraph_cycle_no_weight_fn(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(8))) - graph.remove_node(0) - graph.add_edges_from_no_data([(1, 2), (1, 7), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]) - dist = retworkx.digraph_floyd_warshall_numpy(graph) - self.assertEqual(dist[0, 3], 3) - self.assertEqual(dist[0, 4], 4) - - def test_floyd_warshall_numpy_digraph_cycle_default_weight(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(8))) - graph.remove_node(0) - graph.add_edges_from_no_data([(1, 2), (1, 7), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]) - dist = retworkx.digraph_floyd_warshall_numpy( - graph, default_weight=2, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 6) - self.assertEqual(dist[0, 4], 8) - - -class TestParallelFloydWarshall(TestFloydWarshall): - parallel_threshold = 0 diff --git a/tests/retworkx_backwards_compat/digraph/test_graph_attrs.py b/tests/retworkx_backwards_compat/digraph/test_graph_attrs.py deleted file mode 100644 index 348ef3e88e..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_graph_attrs.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAttributes(unittest.TestCase): - def test_no_attrs(self): - graph = retworkx.PyDiGraph() - self.assertIsNone(graph.attrs) - - def test_attrs_set_at_init(self): - graph = retworkx.PyDiGraph(attrs=dict(foo="bar")) - self.assertEqual({"foo": "bar"}, graph.attrs) - - def test_attrs_set_at_init_override(self): - graph = retworkx.PyDiGraph(attrs=dict(foo="bar")) - self.assertEqual({"foo": "bar"}, graph.attrs) - graph.attrs = "ABC" - self.assertEqual("ABC", graph.attrs) diff --git a/tests/retworkx_backwards_compat/digraph/test_isomorphic.py b/tests/retworkx_backwards_compat/digraph/test_isomorphic.py deleted file mode 100644 index ce1e067851..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_isomorphic.py +++ /dev/null @@ -1,350 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import unittest - -import retworkx - - -class TestIsomorphic(unittest.TestCase): - def test_empty_isomorphic(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_isomorphic(dag_a, dag_b, id_order=id_order)) - - def test_empty_isomorphic_compare_nodes(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic(dag_a, dag_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_isomorphic_identical(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "a_1") - dag_a.add_child(node_a, "a_3", "a_2") - - node_b = dag_b.add_node("a_1") - dag_b.add_child(node_b, "a_2", "a_1") - dag_b.add_child(node_b, "a_3", "a_2") - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_isomorphic(dag_a, dag_b, id_order=id_order)) - - def test_isomorphic_mismatch_node_data(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "a_1") - dag_a.add_child(node_a, "a_3", "a_2") - - node_b = dag_b.add_node("b_1") - dag_b.add_child(node_b, "b_2", "b_1") - dag_b.add_child(node_b, "b_3", "b_2") - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_isomorphic(dag_a, dag_b, id_order=id_order)) - - def test_isomorphic_compare_nodes_mismatch_node_data(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "a_1") - dag_a.add_child(node_a, "a_3", "a_2") - - node_b = dag_b.add_node("b_1") - dag_b.add_child(node_b, "b_2", "b_1") - dag_b.add_child(node_b, "b_3", "b_2") - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse( - retworkx.is_isomorphic(dag_a, dag_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_is_isomorphic_nodes_compare_raises(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "a_1") - dag_a.add_child(node_a, "a_3", "a_2") - - node_b = dag_b.add_node("b_1") - dag_b.add_child(node_b, "b_2", "b_1") - dag_b.add_child(node_b, "b_3", "b_2") - - def compare_nodes(a, b): - raise TypeError("Failure") - - self.assertRaises(TypeError, retworkx.is_isomorphic, (dag_a, dag_b, compare_nodes)) - - def test_isomorphic_compare_nodes_identical(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "a_1") - dag_a.add_child(node_a, "a_3", "a_2") - - node_b = dag_b.add_node("a_1") - dag_b.add_child(node_b, "a_2", "a_1") - dag_b.add_child(node_b, "a_3", "a_2") - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic(dag_a, dag_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_isomorphic_compare_edges_identical(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "a_1") - dag_a.add_child(node_a, "a_3", "a_2") - - node_b = dag_b.add_node("a_1") - dag_b.add_child(node_b, "a_2", "a_1") - dag_b.add_child(node_b, "a_3", "a_2") - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic( - dag_a, - dag_b, - edge_matcher=lambda x, y: x == y, - id_order=id_order, - ) - ) - - def test_isomorphic_compare_nodes_with_removals(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - qr_0_in = dag_a.add_node("qr[0]") - qr_1_in = dag_a.add_node("qr[1]") - cr_0_in = dag_a.add_node("cr[0]") - qr_0_out = dag_a.add_node("qr[0]") - qr_1_out = dag_a.add_node("qr[1]") - cr_0_out = dag_a.add_node("qr[0]") - cu1 = dag_a.add_child(qr_0_in, "cu1", "qr[0]") - dag_a.add_edge(qr_1_in, cu1, "qr[1]") - measure_0 = dag_a.add_child(cr_0_in, "measure", "cr[0]") - dag_a.add_edge(cu1, measure_0, "qr[0]") - measure_1 = dag_a.add_child(cu1, "measure", "qr[1]") - dag_a.add_edge(measure_0, measure_1, "cr[0]") - dag_a.add_edge(measure_1, qr_1_out, "qr[1]") - dag_a.add_edge(measure_1, cr_0_out, "cr[0]") - dag_a.add_edge(measure_0, qr_0_out, "qr[0]") - dag_a.remove_node(cu1) - dag_a.add_edge(qr_0_in, measure_0, "qr[0]") - dag_a.add_edge(qr_1_in, measure_1, "qr[1]") - - qr_0_in = dag_b.add_node("qr[0]") - qr_1_in = dag_b.add_node("qr[1]") - cr_0_in = dag_b.add_node("cr[0]") - qr_0_out = dag_b.add_node("qr[0]") - qr_1_out = dag_b.add_node("qr[1]") - cr_0_out = dag_b.add_node("qr[0]") - measure_0 = dag_b.add_child(cr_0_in, "measure", "cr[0]") - dag_b.add_edge(qr_0_in, measure_0, "qr[0]") - measure_1 = dag_b.add_child(qr_1_in, "measure", "qr[1]") - dag_b.add_edge(measure_1, qr_1_out, "qr[1]") - dag_b.add_edge(measure_1, cr_0_out, "cr[0]") - dag_b.add_edge(measure_0, measure_1, "cr[0]") - dag_b.add_edge(measure_0, qr_0_out, "qr[0]") - - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic(dag_a, dag_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_isomorphic_compare_nodes_with_removals_deepcopy(self): - dag_a = retworkx.PyDAG() - dag_b = retworkx.PyDAG() - - qr_0_in = dag_a.add_node("qr[0]") - qr_1_in = dag_a.add_node("qr[1]") - cr_0_in = dag_a.add_node("cr[0]") - qr_0_out = dag_a.add_node("qr[0]") - qr_1_out = dag_a.add_node("qr[1]") - cr_0_out = dag_a.add_node("qr[0]") - cu1 = dag_a.add_child(qr_0_in, "cu1", "qr[0]") - dag_a.add_edge(qr_1_in, cu1, "qr[1]") - measure_0 = dag_a.add_child(cr_0_in, "measure", "cr[0]") - dag_a.add_edge(cu1, measure_0, "qr[0]") - measure_1 = dag_a.add_child(cu1, "measure", "qr[1]") - dag_a.add_edge(measure_0, measure_1, "cr[0]") - dag_a.add_edge(measure_1, qr_1_out, "qr[1]") - dag_a.add_edge(measure_1, cr_0_out, "cr[0]") - dag_a.add_edge(measure_0, qr_0_out, "qr[0]") - dag_a.remove_node(cu1) - dag_a.add_edge(qr_0_in, measure_0, "qr[0]") - dag_a.add_edge(qr_1_in, measure_1, "qr[1]") - - qr_0_in = dag_b.add_node("qr[0]") - qr_1_in = dag_b.add_node("qr[1]") - cr_0_in = dag_b.add_node("cr[0]") - qr_0_out = dag_b.add_node("qr[0]") - qr_1_out = dag_b.add_node("qr[1]") - cr_0_out = dag_b.add_node("qr[0]") - measure_0 = dag_b.add_child(cr_0_in, "measure", "cr[0]") - dag_b.add_edge(qr_0_in, measure_0, "qr[0]") - measure_1 = dag_b.add_child(qr_1_in, "measure", "qr[1]") - dag_b.add_edge(measure_1, qr_1_out, "qr[1]") - dag_b.add_edge(measure_1, cr_0_out, "cr[0]") - dag_b.add_edge(measure_0, measure_1, "cr[0]") - dag_b.add_edge(measure_0, qr_0_out, "qr[0]") - - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic( - copy.deepcopy(dag_a), - copy.deepcopy(dag_b), - lambda x, y: x == y, - id_order=id_order, - ) - ) - - def test_digraph_isomorphic_parallel_edges_with_edge_matcher(self): - graph = retworkx.PyDiGraph() - graph.extend_from_weighted_edge_list([(0, 1, "a"), (0, 1, "b"), (1, 2, "c")]) - self.assertTrue(retworkx.is_isomorphic(graph, graph, edge_matcher=lambda x, y: x == y)) - - def test_digraph_isomorphic_self_loop(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0]) - graph.add_edges_from([(0, 0, "a")]) - self.assertTrue(retworkx.is_isomorphic(graph, graph)) - - def test_digraph_non_isomorphic_edge_mismatch_self_loop(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0]) - graph.add_edges_from([(0, 0, "a")]) - second_graph = retworkx.PyDiGraph() - second_graph.add_nodes_from([0]) - second_graph.add_edges_from([(0, 0, "b")]) - self.assertFalse( - retworkx.is_isomorphic(graph, second_graph, edge_matcher=lambda x, y: x == y) - ) - - def test_digraph_non_isomorphic_rule_out_incoming(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0, 1, 2, 3]) - graph.add_edges_from_no_data([(0, 1), (0, 2), (2, 1)]) - second_graph = retworkx.PyDiGraph() - second_graph.add_nodes_from([0, 1, 2, 3]) - second_graph.add_edges_from_no_data([(0, 1), (0, 2), (3, 1)]) - self.assertFalse(retworkx.is_isomorphic(graph, second_graph, id_order=True)) - - def test_digraph_non_isomorphic_rule_ins_outgoing(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0, 1, 2, 3]) - graph.add_edges_from_no_data([(1, 0), (2, 0), (1, 2)]) - second_graph = retworkx.PyDiGraph() - second_graph.add_nodes_from([0, 1, 2, 3]) - second_graph.add_edges_from_no_data([(1, 0), (2, 0), (1, 3)]) - self.assertFalse(retworkx.is_isomorphic(graph, second_graph, id_order=True)) - - def test_digraph_non_isomorphic_rule_ins_incoming(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0, 1, 2, 3]) - graph.add_edges_from_no_data([(1, 0), (2, 0), (2, 1)]) - second_graph = retworkx.PyDiGraph() - second_graph.add_nodes_from([0, 1, 2, 3]) - second_graph.add_edges_from_no_data([(1, 0), (2, 0), (3, 1)]) - self.assertFalse(retworkx.is_isomorphic(graph, second_graph, id_order=True)) - - def test_isomorphic_parallel_edges(self): - first = retworkx.PyDiGraph() - first.extend_from_edge_list([(0, 1), (0, 1), (1, 2), (2, 3)]) - second = retworkx.PyDiGraph() - second.extend_from_edge_list([(0, 1), (1, 2), (1, 2), (2, 3)]) - self.assertFalse(retworkx.is_isomorphic(first, second)) - - def test_digraph_isomorphic_insufficient_call_limit(self): - graph = retworkx.generators.directed_path_graph(5) - self.assertFalse(retworkx.is_isomorphic(graph, graph, call_limit=2)) - - def test_digraph_vf2_mapping_identical(self): - graph = retworkx.generators.directed_grid_graph(2, 2) - second_graph = retworkx.generators.directed_grid_graph(2, 2) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph) - self.assertEqual(next(mapping), {0: 0, 1: 1, 2: 2, 3: 3}) - - def test_digraph_vf2_mapping_identical_removals(self): - graph = retworkx.generators.directed_path_graph(2) - second_graph = retworkx.generators.directed_path_graph(4) - second_graph.remove_nodes_from([1, 2]) - second_graph.add_edge(0, 3, None) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph) - self.assertEqual({0: 0, 1: 3}, next(mapping)) - - def test_digraph_vf2_mapping_identical_removals_first(self): - second_graph = retworkx.generators.directed_path_graph(2) - graph = retworkx.generators.directed_path_graph(4) - graph.remove_nodes_from([1, 2]) - graph.add_edge(0, 3, None) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph) - self.assertEqual({0: 0, 3: 1}, next(mapping)) - - def test_digraph_vf2_mapping_identical_vf2pp(self): - graph = retworkx.generators.directed_grid_graph(2, 2) - second_graph = retworkx.generators.directed_grid_graph(2, 2) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph, id_order=False) - self.assertEqual(next(mapping), {0: 0, 1: 1, 2: 2, 3: 3}) - - def test_digraph_vf2_mapping_identical_removals_vf2pp(self): - graph = retworkx.generators.directed_path_graph(2) - second_graph = retworkx.generators.directed_path_graph(4) - second_graph.remove_nodes_from([1, 2]) - second_graph.add_edge(0, 3, None) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph, id_order=False) - self.assertEqual({0: 0, 1: 3}, next(mapping)) - - def test_digraph_vf2_mapping_identical_removals_first_vf2pp(self): - second_graph = retworkx.generators.directed_path_graph(2) - graph = retworkx.generators.directed_path_graph(4) - graph.remove_nodes_from([1, 2]) - graph.add_edge(0, 3, None) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph, id_order=False) - self.assertEqual({0: 0, 3: 1}, next(mapping)) - - def test_digraph_vf2_number_of_valid_mappings(self): - graph = retworkx.generators.directed_mesh_graph(3) - mapping = retworkx.digraph_vf2_mapping(graph, graph, id_order=True) - total = 0 - for _ in mapping: - total += 1 - self.assertEqual(total, 6) - - def test_empty_digraph_vf2_mapping(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - mapping = retworkx.digraph_vf2_mapping(g_a, g_b, id_order=id_order, subgraph=False) - self.assertEqual({}, next(mapping)) diff --git a/tests/retworkx_backwards_compat/digraph/test_k_shortest_path.py b/tests/retworkx_backwards_compat/digraph/test_k_shortest_path.py deleted file mode 100644 index 1a788441b3..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_k_shortest_path.py +++ /dev/null @@ -1,96 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestKShortestpath(unittest.TestCase): - def test_digraph_k_shortest_path_lengths(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(8))) - graph.add_edges_from_no_data( - [ - (0, 1), - (1, 2), - (2, 3), - (3, 0), - (4, 5), - (1, 4), - (5, 6), - (6, 7), - (7, 5), - ] - ) - res = retworkx.digraph_k_shortest_path_lengths(graph, 1, 2, lambda _: 1) - expected = { - 0: 7.0, - 1: 4.0, - 2: 5.0, - 3: 6.0, - 4: 5.0, - 5: 5.0, - 6: 6.0, - 7: 7.0, - } - self.assertEqual(res, expected) - - def test_digraph_k_shortest_path_lengths_with_goal(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(8))) - graph.add_edges_from_no_data( - [ - (0, 1), - (1, 2), - (2, 3), - (3, 0), - (4, 5), - (1, 4), - (5, 6), - (6, 7), - (7, 5), - ] - ) - res = retworkx.digraph_k_shortest_path_lengths(graph, 1, 2, lambda _: 1, 3) - self.assertEqual(res, {3: 6}) - - def test_digraph_k_shortest_path_with_goal_node_hole(self): - graph = retworkx.generators.directed_path_graph(4) - graph.remove_node(0) - res = retworkx.digraph_k_shortest_path_lengths( - graph, start=1, k=1, edge_cost=lambda _: 1, goal=3 - ) - self.assertEqual({3: 2}, res) - - def test_digraph_k_shortest_path_with_invalid_weight(self): - graph = retworkx.generators.directed_path_graph(4) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.digraph_k_shortest_path_lengths( - graph, - start=1, - k=1, - edge_cost=lambda _: invalid_weight, - goal=3, - ) - - def test_k_shortest_path_with_no_path(self): - g = retworkx.PyDiGraph() - a = g.add_node("A") - b = g.add_node("B") - path_lenghts = retworkx.digraph_k_shortest_path_lengths( - g, start=a, k=1, edge_cost=float, goal=b - ) - expected = {} - self.assertEqual(expected, path_lenghts) diff --git a/tests/retworkx_backwards_compat/digraph/test_layers.py b/tests/retworkx_backwards_compat/digraph/test_layers.py deleted file mode 100644 index 720c1f0fb8..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_layers.py +++ /dev/null @@ -1,65 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestLayers(unittest.TestCase): - def test_dagcircuit_basic(self): - dag = retworkx.PyDAG() - qr_0_in = dag.add_node("qr[0]") - qr_0_out = dag.add_node("qr[0]") - qr_1_in = dag.add_node("qr[1]") - qr_1_out = dag.add_node("qr[1]") - cr_0_in = dag.add_node("cr[0]") - cr_0_out = dag.add_node("cr[0]") - cr_1_in = dag.add_node("cr[1]") - cr_1_out = dag.add_node("cr[1]") - input_nodes = [qr_0_in, qr_1_in, cr_0_in, cr_1_in] - - h_gate = dag.add_child(qr_0_in, "h", "qr[0]") - cx_gate = dag.add_child(h_gate, "cx", "qr[0]") - dag.add_edge(qr_1_in, cx_gate, "qr[1]") - measure_qr_1 = dag.add_child(cx_gate, "measure", "qr[1]") - dag.add_edge(cr_1_in, measure_qr_1, "cr[1]") - x_gate = dag.add_child(measure_qr_1, "x", "qr[1]") - dag.add_edge(measure_qr_1, x_gate, "cr[1]") - dag.add_edge(cr_0_in, x_gate, "cr[0]") - - measure_qr_0 = dag.add_child(cx_gate, "measure", "qr[0]") - dag.add_edge(measure_qr_0, qr_0_out, "qr[0]") - dag.add_edge(measure_qr_0, cr_0_out, "cr[0]") - dag.add_edge(x_gate, measure_qr_0, "cr[0]") - - measure_qr_1_out = dag.add_child(x_gate, "measure", "cr[1]") - dag.add_edge(x_gate, measure_qr_1_out, "qr[1]") - dag.add_edge(measure_qr_1_out, qr_1_out, "qr[1]") - dag.add_edge(measure_qr_1_out, cr_1_out, "cr[1]") - - res = retworkx.layers(dag, input_nodes) - expected = [ - ["qr[0]", "qr[1]", "cr[0]", "cr[1]"], - ["h"], - ["cx"], - ["measure"], - ["x"], - ["measure", "measure"], - ["cr[1]", "qr[1]", "cr[0]", "qr[0]"], - ] - self.assertEqual(expected, res) - - def test_first_layer_invalid_node(self): - dag = retworkx.PyDAG() - with self.assertRaises(retworkx.InvalidNode): - retworkx.layers(dag, [42]) diff --git a/tests/retworkx_backwards_compat/digraph/test_layout.py b/tests/retworkx_backwards_compat/digraph/test_layout.py deleted file mode 100644 index 1017f4f91a..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_layout.py +++ /dev/null @@ -1,477 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class LayoutTest(unittest.TestCase): - thres = 1e-6 - - def assertLayoutEquiv(self, exp, res): - for k in exp: - ev = exp[k] - rv = res[k] - if abs(ev[0] - rv[0]) > self.thres or abs(ev[1] - rv[1]) > self.thres: - self.fail( - "The position for node %s, %s, differs from the expected " - "position, %s by more than the allowed threshold of %s" - % (k, rv, ev, self.thres) - ) - - -class TestRandomLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.directed_path_graph(10) - - def test_random_layout(self): - res = retworkx.digraph_random_layout(self.graph, seed=42) - expected = { - 0: (0.2265125179283135, 0.23910669031859955), - 4: (0.8025885957751138, 0.37085692752109345), - 5: (0.23635127852185123, 0.9286365888207462), - 1: (0.760833410686741, 0.5278396573581516), - 3: (0.1879083014236631, 0.524657662927804), - 2: (0.9704763177409157, 0.37546268141451944), - 6: (0.462700947802672, 0.44025745918644743), - 7: (0.3125895420208278, 0.0893209773065271), - 8: (0.5567725240957387, 0.21079648777222115), - 9: (0.7586719404939911, 0.43090704138697045), - } - self.assertEqual(expected, res) - - def test_random_layout_center(self): - res = retworkx.digraph_random_layout(self.graph, center=(0.5, 0.5), seed=42) - expected = { - 1: [1.260833410686741, 1.0278396573581516], - 5: [0.7363512785218512, 1.4286365888207462], - 7: [0.8125895420208278, 0.5893209773065271], - 4: [1.3025885957751138, 0.8708569275210934], - 8: [1.0567725240957389, 0.7107964877722212], - 9: [1.2586719404939912, 0.9309070413869704], - 0: [0.7265125179283135, 0.7391066903185995], - 2: [1.4704763177409157, 0.8754626814145194], - 6: [0.962700947802672, 0.9402574591864474], - 3: [0.6879083014236631, 1.0246576629278041], - } - self.assertEqual(expected, res) - - def test_random_layout_no_seed(self): - res = retworkx.digraph_random_layout(self.graph) - # Random output, just assert structurally correct - self.assertIsInstance(res, retworkx.Pos2DMapping) - self.assertEqual(len(res), 10) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - -class TestBipartiteLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.directed_path_graph(10) - - def test_bipartite_layout_empty(self): - res = retworkx.bipartite_layout(retworkx.PyDiGraph(), set()) - self.assertEqual({}, res) - - def test_bipartite_layout_hole(self): - g = retworkx.generators.directed_path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.bipartite_layout(g, set()) - expected = { - 0: (0.0, -1.0), - 2: (0.0, -0.3333333333333333), - 3: (0.0, 0.3333333333333333), - 4: (0.0, 1.0), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout(self): - res = retworkx.bipartite_layout(self.graph, {0, 1, 2, 3, 4}) - expected = { - 0: (-1.0, -0.75), - 1: (-1.0, -0.375), - 2: (-1.0, 0.0), - 3: (-1.0, 0.375), - 4: (-1.0, 0.75), - 5: (1.0, -0.75), - 6: (1.0, -0.375), - 7: (1.0, 0.0), - 8: (1.0, 0.375), - 9: (1.0, 0.75), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_horizontal(self): - res = retworkx.bipartite_layout(self.graph, {0, 1, 2, 3}, horizontal=True) - expected = { - 0: (1.0, -0.9), - 1: (0.3333333333333333, -0.9), - 2: (-0.333333333333333, -0.9), - 3: (-1.0, -0.9), - 4: (1.0, 0.6), - 5: (0.6, 0.6), - 6: (0.2, 0.6), - 7: (-0.2, 0.6), - 8: (-0.6, 0.6), - 9: (-1.0, 0.6), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_scale(self): - res = retworkx.bipartite_layout(self.graph, {0, 1, 2}, scale=2) - expected = { - 0: (-2.0, -1.0714285714285714), - 1: (-2.0, 2.3790493384824785e-17), - 2: (-2.0, 1.0714285714285714), - 3: (0.8571428571428571, -1.0714285714285714), - 4: (0.8571428571428571, -0.7142857142857143), - 5: (0.8571428571428571, -0.35714285714285715), - 6: (0.8571428571428571, 2.3790493384824785e-17), - 7: (0.8571428571428571, 0.35714285714285704), - 8: (0.8571428571428571, 0.7142857142857141), - 9: (0.8571428571428571, 1.0714285714285714), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_center(self): - res = retworkx.bipartite_layout(self.graph, {4, 5, 6}, center=(0.5, 0.5)) - expected = { - 4: (-0.5, -0.0357142857142857), - 5: (-0.5, 0.5), - 6: (-0.5, 1.0357142857142856), - 0: (0.9285714285714286, -0.0357142857142857), - 1: (0.9285714285714286, 0.14285714285714285), - 2: (0.9285714285714286, 0.3214285714285714), - 3: (0.9285714285714286, 0.5), - 7: (0.9285714285714286, 0.6785714285714285), - 8: (0.9285714285714286, 0.857142857142857), - 9: (0.9285714285714286, 1.0357142857142856), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_ratio(self): - res = retworkx.bipartite_layout(self.graph, {2, 4, 8}, aspect_ratio=4) - expected = { - 8: [-1.0, 0.17857142857142858], - 2: [-1.0, -0.17857142857142858], - 4: [-1.0, 0], - 0: [0.42857142857142855, -0.17857142857142858], - 1: [0.42857142857142855, -0.11904761904761907], - 3: [0.42857142857142855, -0.05952380952380952], - 5: [0.42857142857142855, 0], - 6: [0.42857142857142855, 0.05952380952380952], - 7: [0.42857142857142855, 0.11904761904761903], - 9: [0.42857142857142855, 0.17857142857142858], - } - self.assertLayoutEquiv(expected, res) - - -class TestCircularLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.directed_path_graph(10) - - def test_circular_layout_empty(self): - res = retworkx.circular_layout(retworkx.PyDiGraph()) - self.assertEqual({}, res) - - def test_circular_layout_one_node(self): - res = retworkx.circular_layout(retworkx.generators.directed_path_graph(1)) - self.assertEqual({0: (0.0, 0.0)}, res) - - def test_circular_layout_hole(self): - g = retworkx.generators.directed_path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.circular_layout(g) - expected = { - 0: (0.999999986090933, 2.1855693665697608e-08), - 2: (-3.576476059301554e-08, 1.0), - 3: (-0.9999999701976796, -6.556708099709282e-08), - 4: (1.987150711625619e-08, -0.9999999562886126), - } - self.assertLayoutEquiv(expected, res) - - def test_circular_layout(self): - res = retworkx.circular_layout(self.graph) - expected = { - 0: (1.0, 2.662367085193061e-08), - 1: (0.8090170042900712, 0.5877852653564984), - 2: (0.3090169789580973, 0.9510565581329226), - 3: (-0.3090170206813483, 0.9510564985282783), - 4: (-0.8090170460133221, 0.5877852057518542), - 5: (-0.9999999821186069, -6.079910493992474e-08), - 6: (-0.8090169268040337, -0.5877853313184453), - 7: (-0.3090170802859925, -0.9510564452809367), - 8: (0.3090171279697079, -0.9510564452809367), - 9: (0.809016944685427, -0.587785271713801), - } - self.assertLayoutEquiv(expected, res) - - def test_circular_layout_scale(self): - res = retworkx.circular_layout(self.graph, scale=2) - expected = { - 0: (2.0, 5.324734170386122e-08), - 1: (1.6180340085801423, 1.1755705307129969), - 2: (0.6180339579161946, 1.9021131162658451), - 3: (-0.6180340413626966, 1.9021129970565567), - 4: (-1.6180340920266443, 1.1755704115037084), - 5: (-1.9999999642372137, -1.2159820987984948e-07), - 6: (-1.6180338536080674, -1.1755706626368907), - 7: (-0.618034160571985, -1.9021128905618734), - 8: (0.6180342559394159, -1.9021128905618734), - 9: (1.618033889370854, -1.175570543427602), - } - self.assertLayoutEquiv(expected, res) - - def test_circular_layout_center(self): - res = retworkx.circular_layout(self.graph, center=(0.5, 0.5)) - expected = { - 0: (1.5, 0.5000000266236708), - 1: (1.3090170042900713, 1.0877852653564983), - 2: (0.8090169789580973, 1.4510565581329224), - 3: (0.1909829793186517, 1.4510564985282783), - 4: (-0.30901704601332214, 1.0877852057518542), - 5: (-0.49999998211860686, 0.4999999392008951), - 6: (-0.3090169268040337, -0.08778533131844535), - 7: (0.1909829197140075, -0.4510564452809367), - 8: (0.8090171279697079, -0.4510564452809367), - 9: (1.309016944685427, -0.08778527171380102), - } - self.assertLayoutEquiv(expected, res) - - -class TestShellLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.directed_path_graph(10) - - def test_shell_layout_empty(self): - res = retworkx.circular_layout(retworkx.PyDiGraph()) - self.assertEqual({}, res) - - def test_shell_layout_one_node(self): - res = retworkx.shell_layout(retworkx.generators.directed_path_graph(1)) - self.assertEqual({0: (0.0, 0.0)}, res) - - def test_shell_layout_hole(self): - g = retworkx.generators.directed_path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.shell_layout(g) - expected = { - 0: (-1.0, -8.742277657347586e-08), - 2: (1.1924880638503055e-08, -1.0), - 3: (1.0, 1.7484555314695172e-07), - 4: (-3.3776623808989825e-07, 1.0), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_hole_two_shells(self): - g = retworkx.generators.directed_path_graph(5) - g.remove_nodes_from([2]) - res = retworkx.shell_layout(g, [[0, 1], [3, 4]]) - expected = { - 0: (-2.1855694143368964e-08, 0.5), - 1: (5.962440319251527e-09, -0.5), - 3: (-1.0, -8.742277657347586e-08), - 4: (1.0, 1.7484555314695172e-07), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout(self): - res = retworkx.shell_layout(self.graph) - expected = { - 0: (-1.0, -8.742277657347586e-08), - 1: (-0.8090169429779053, -0.5877853631973267), - 2: (-0.3090170919895172, -0.9510564804077148), - 3: (0.3090171217918396, -0.9510564804077148), - 4: (0.8090172410011292, -0.5877849459648132), - 5: (1.0, 1.7484555314695172e-07), - 6: (0.80901700258255, 0.5877852439880371), - 7: (0.30901679396629333, 0.9510565996170044), - 8: (-0.30901744961738586, 0.9510563611984253), - 9: (-0.8090168833732605, 0.5877854228019714), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_nlist(self): - res = retworkx.shell_layout(self.graph, nlist=[[0, 2], [1, 3], [4, 9], [8, 7], [6, 5]]) - expected = { - 0: (0.16180340945720673, 0.11755704879760742), - 2: (-0.16180339455604553, -0.11755707114934921), - 1: (0.12360679358243942, 0.3804226219654083), - 3: (-0.123606838285923, -0.38042259216308594), - 4: (-0.18541023135185242, 0.5706338882446289), - 9: (0.185410276055336, -0.5706338882446289), - 8: (-0.6472136378288269, 0.4702281653881073), - 7: (0.6472138166427612, -0.4702279567718506), - 6: (-1.0, -8.742277657347586e-08), - 5: (1.0, 1.7484555314695172e-07), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_rotate(self): - res = retworkx.shell_layout( - self.graph, nlist=[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]], rotate=0.5 - ) - expected = { - 0: (0.21939563751220703, 0.11985638737678528), - 1: (-0.21349650621414185, 0.13007399439811707), - 2: (-0.005899117328226566, -0.24993039667606354), - 3: (0.27015113830566406, 0.4207354784011841), - 4: (-0.4994432032108307, 0.023589985445141792), - 5: (0.229292094707489, -0.4443254768848419), - 6: (0.05305289849638939, 0.7481212615966797), - 7: (-0.6744184494018555, -0.3281154930591583), - 8: (0.6213656067848206, -0.420005738735199), - 9: (-0.416146844625473, 0.9092974066734314), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_scale(self): - res = retworkx.shell_layout(self.graph, nlist=[[0, 1, 2, 3, 4], [9, 8, 7, 6, 5]], scale=2) - expected = { - 0: (-4.371138828673793e-08, 1.0), - 1: (-0.9510565996170044, 0.30901679396629333), - 2: (-0.5877850651741028, -0.8090171217918396), - 3: (0.5877854824066162, -0.8090168237686157), - 4: (0.9510564208030701, 0.30901727080345154), - 9: (-2.0, -1.7484555314695172e-07), - 8: (-0.6180341839790344, -1.9021129608154297), - 7: (1.6180344820022583, -1.1755698919296265), - 6: (1.6180340051651, 1.1755704879760742), - 5: (-0.6180348992347717, 1.9021127223968506), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_center(self): - res = retworkx.shell_layout( - self.graph, - nlist=[[0, 1, 2, 3, 4], [9, 8, 7, 6, 5]], - center=(0.5, 0.5), - ) - expected = { - 0: (0.49999997814430586, 1.0), - 1: (0.024471700191497803, 0.6545083969831467), - 2: (0.2061074674129486, 0.0954914391040802), - 3: (0.7938927412033081, 0.09549158811569214), - 4: (0.975528210401535, 0.6545086354017258), - 9: (-0.5, 0.4999999125772234), - 8: (0.1909829080104828, -0.45105648040771484), - 7: (1.3090172410011292, -0.08778494596481323), - 6: (1.30901700258255, 1.087785243988037), - 5: (0.19098255038261414, 1.4510563611984253), - } - self.assertLayoutEquiv(expected, res) - - -class TestSpiralLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.directed_path_graph(10) - - def test_spiral_layout_empty(self): - res = retworkx.spiral_layout(retworkx.PyDiGraph()) - self.assertEqual({}, res) - - def test_spiral_layout_one_node(self): - res = retworkx.spiral_layout(retworkx.generators.directed_path_graph(1)) - self.assertEqual({0: (0.0, 0.0)}, res) - - def test_spiral_layout_hole(self): - g = retworkx.generators.directed_path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.spiral_layout(g) - expected = { - 0: (-0.6415327868391166, -0.6855508729419231), - 2: (-0.03307913182988828, -0.463447951079834), - 3: (0.34927952438480797, 0.1489988240217569), - 4: (0.32533239428419697, 1.0), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout(self): - res = retworkx.spiral_layout(self.graph) - expected = { - 0: (0.3083011152777303, -0.36841870322845377), - 1: (0.4448595378922136, -0.3185709877650719), - 2: (0.5306742824266687, -0.18111636841212878), - 3: (0.5252997033017661, 0.009878257518578544), - 4: (0.40713492048969163, 0.20460820654918466), - 5: (0.17874125121181098, 0.3468009691240852), - 6: (-0.1320415949011884, 0.3844997574641717), - 7: (-0.4754889029311045, 0.28057288841663486), - 8: (-0.7874803127675889, 0.021164283410983312), - 9: (-0.9999999999999999, -0.3794183030779839), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_scale(self): - res = retworkx.spiral_layout(self.graph, scale=2) - expected = { - 0: (0.6166022305554606, -0.7368374064569075), - 1: (0.8897190757844272, -0.6371419755301438), - 2: (1.0613485648533374, -0.36223273682425755), - 3: (1.0505994066035322, 0.01975651503715709), - 4: (0.8142698409793833, 0.4092164130983693), - 5: (0.35748250242362195, 0.6936019382481704), - 6: (-0.2640831898023768, 0.7689995149283434), - 7: (-0.950977805862209, 0.5611457768332697), - 8: (-1.5749606255351778, 0.042328566821966625), - 9: (-1.9999999999999998, -0.7588366061559678), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_center(self): - res = retworkx.spiral_layout(self.graph, center=(1, 1)) - expected = { - 0: (1.3083011152777302, 0.6315812967715462), - 1: (1.4448595378922136, 0.681429012234928), - 2: (1.5306742824266686, 0.8188836315878713), - 3: (1.5252997033017661, 1.0098782575185785), - 4: (1.4071349204896917, 1.2046082065491848), - 5: (1.178741251211811, 1.3468009691240852), - 6: (0.8679584050988116, 1.3844997574641718), - 7: (0.5245110970688955, 1.2805728884166347), - 8: (0.2125196872324111, 1.0211642834109833), - 9: (1.1102230246251565e-16, 0.6205816969220161), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_resolution(self): - res = retworkx.spiral_layout(self.graph, resolution=0.6) - expected = { - 0: (0.14170895375949058, 0.22421978768273812), - 1: (0.2657196183870804, 0.30906004798138936), - 2: (0.2506009612140119, 0.5043065412934762), - 3: (0.039294315670400995, 0.6631957258449066), - 4: (-0.3014789232909145, 0.6301862160709318), - 5: (-0.602046830323471, 0.3302396035952633), - 6: (-0.66674476042188, -0.17472522299849289), - 7: (-0.3739394496041176, -0.6924895145748617), - 8: (0.2468861146093996, -0.9732085843739783), - 9: (1.0, -0.8207846005213728), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_equidistant(self): - res = retworkx.spiral_layout(self.graph, equidistant=True) - expected = { - 0: (-0.13161882865656718, -0.7449342807652114), - 1: (0.7160560542246066, -0.6335352483233974), - 2: (0.6864868274284994, -0.34165899654603915), - 3: (0.5679822628330004, -0.07281296883784087), - 4: (0.375237081214659, 0.14941210155952697), - 5: (0.12730720268992277, 0.30830226777240866), - 6: (-0.15470865936858091, 0.3939608192236113), - 7: (-0.4495426197217269, 0.4027809258196645), - 8: (-0.7371993206438128, 0.33662707199446507), - 9: (-1.0, 0.2018583081028111), - } - self.assertLayoutEquiv(expected, res) diff --git a/tests/retworkx_backwards_compat/digraph/test_neighbors.py b/tests/retworkx_backwards_compat/digraph/test_neighbors.py deleted file mode 100644 index f33f49c6c3..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_neighbors.py +++ /dev/null @@ -1,59 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAdj(unittest.TestCase): - def test_single_neighbor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - res = dag.neighbors(node_a) - self.assertCountEqual([node_c, node_b], res) - - def test_unique_neighbors_on_dags(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", ["edge a->b"]) - node_c = dag.add_child(node_a, "c", ["edge a->c"]) - dag.add_edge(node_a, node_b, ["edge a->b bis"]) - res = dag.neighbors(node_a) - self.assertCountEqual([node_c, node_b], res) - - def test_single_neighbor_dir(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - res = dag.successor_indices(node_a) - self.assertEqual([node_c, node_b], res) - res = dag.predecessor_indices(node_a) - self.assertEqual([], res) - - def test_neighbor_dir_surrounded(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - res = dag.successor_indices(node_b) - self.assertEqual([node_c], res) - res = dag.predecessor_indices(node_b) - self.assertEqual([node_a], res) - - def test_no_neighbor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - self.assertEqual([], dag.neighbors(node_a)) diff --git a/tests/retworkx_backwards_compat/digraph/test_nodes.py b/tests/retworkx_backwards_compat/digraph/test_nodes.py deleted file mode 100644 index 4d9dfcd794..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_nodes.py +++ /dev/null @@ -1,403 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestNodes(unittest.TestCase): - def test_nodes(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", "Edgy") - res = dag.nodes() - self.assertEqual(["a", "b"], res) - self.assertEqual([0, 1], dag.node_indexes()) - - def test_node_indices(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node("a") - graph.add_child(node_a, "b", "Edgy") - self.assertEqual([0, 1], graph.node_indices()) - - def test_no_nodes(self): - dag = retworkx.PyDAG() - self.assertEqual([], dag.nodes()) - self.assertEqual([], dag.node_indexes()) - self.assertEqual([], dag.node_indices()) - - def test_remove_node(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node(node_b) - res = dag.nodes() - self.assertEqual(["a", "c"], res) - self.assertEqual([0, 2], dag.node_indexes()) - - def test_remove_node_invalid_index(self): - graph = retworkx.PyDAG() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.remove_node(76) - res = graph.nodes() - self.assertEqual(["a", "b", "c"], res) - self.assertEqual([0, 1, 2], graph.node_indexes()) - - def test_remove_nodes_from(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_nodes_from([node_b, node_c]) - res = dag.nodes() - self.assertEqual(["a"], res) - self.assertEqual([0], dag.node_indexes()) - - def test_remove_nodes_from_with_invalid_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_nodes_from([node_b, node_c, 76]) - res = dag.nodes() - self.assertEqual(["a"], res) - self.assertEqual([0], dag.node_indexes()) - - def test_remove_nodes_retain_edges_single_edge(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node_retain_edges(node_b) - res = dag.nodes() - self.assertEqual(["a", "c"], res) - self.assertEqual([0, 2], dag.node_indexes()) - self.assertTrue(dag.has_edge(node_a, node_c)) - self.assertEqual(dag.get_all_edge_data(node_a, node_c), ["Edgy"]) - - def test_remove_nodes_retain_edges_single_edge_outgoing_weight(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node_retain_edges(node_b, use_outgoing=True) - res = dag.nodes() - self.assertEqual(["a", "c"], res) - self.assertEqual([0, 2], dag.node_indexes()) - self.assertTrue(dag.has_edge(node_a, node_c)) - self.assertEqual(dag.get_all_edge_data(node_a, node_c), ["Edgy_mk2"]) - - def test_remove_nodes_retain_edges_multiple_in_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_d = dag.add_node("d") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_edge(node_d, node_b, "Multiple in edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node_retain_edges(node_b) - res = dag.nodes() - self.assertEqual(["a", "d", "c"], res) - self.assertEqual([0, 1, 3], dag.node_indexes()) - self.assertTrue(dag.has_edge(node_a, node_c)) - self.assertTrue(dag.has_edge(node_d, node_c)) - - def test_remove_nodes_retain_edges_multiple_out_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_d = dag.add_node("d") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_edge(node_b, node_d, "Multiple out edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node_retain_edges(node_b) - res = dag.nodes() - self.assertEqual(["a", "d", "c"], res) - self.assertEqual([0, 1, 3], dag.node_indexes()) - self.assertTrue(dag.has_edge(node_a, node_c)) - self.assertTrue(dag.has_edge(node_a, node_d)) - - def test_remove_nodes_retain_edges_multiple_in_and_out_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_d = dag.add_node("d") - node_e = dag.add_node("e") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_edge(node_b, node_d, "Multiple out edgy") - dag.add_edge(node_e, node_b, "multiple in edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node_retain_edges(node_b) - res = dag.nodes() - self.assertEqual(["a", "d", "e", "c"], res) - self.assertEqual([0, 1, 2, 4], dag.node_indexes()) - self.assertTrue(dag.has_edge(node_a, node_c)) - self.assertTrue(dag.has_edge(node_a, node_d)) - self.assertTrue(dag.has_edge(node_e, node_c)) - self.assertTrue(dag.has_edge(node_e, node_d)) - - def test_remove_node_retain_edges_with_condition(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_d = dag.add_node("d") - node_e = dag.add_node("e") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_edge(node_b, node_d, "Multiple out edgy") - dag.add_edge(node_e, node_b, "multiple in edgy") - node_c = dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node_retain_edges(node_b, condition=lambda a, b: a == "multiple in edgy") - res = dag.nodes() - self.assertEqual(["a", "d", "e", "c"], res) - self.assertEqual([0, 1, 2, 4], dag.node_indexes()) - self.assertFalse(dag.has_edge(node_a, node_c)) - self.assertFalse(dag.has_edge(node_a, node_d)) - self.assertTrue(dag.has_edge(node_e, node_c)) - self.assertTrue(dag.has_edge(node_e, node_d)) - - def test_remove_nodes_retain_edges_with_invalid_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_child(node_b, "c", "Edgy_mk2") - dag.remove_node_retain_edges(76) - res = dag.nodes() - self.assertEqual(["a", "b", "c"], res) - self.assertEqual([0, 1, 2], dag.node_indexes()) - - def test_topo_sort_empty(self): - dag = retworkx.PyDAG() - self.assertEqual([], retworkx.topological_sort(dag)) - - def test_topo_sort(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(5): - dag.add_child(node_a, i, None) - dag.add_parent(3, "A parent", None) - res = retworkx.topological_sort(dag) - self.assertEqual([6, 0, 5, 4, 3, 2, 1], res) - - def test_topo_sort_with_cycle(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {}) - dag.add_edge(node_b, node_a, {}) - self.assertRaises(retworkx.DAGHasCycle, retworkx.topological_sort, dag) - - def test_lexicographical_topo_sort(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(5): - dag.add_child(node_a, i, None) - dag.add_parent(3, "A parent", None) - res = retworkx.lexicographical_topological_sort(dag, lambda x: str(x)) - # Node values for nodes [6, 0, 5, 4, 3, 2, 1] - expected = ["A parent", "a", 0, 1, 2, 3, 4] - self.assertEqual(expected, res) - - def test_lexicographical_topo_sort_qiskit(self): - dag = retworkx.PyDAG() - # inputs - qr_0 = dag.add_node("qr[0]") - qr_1 = dag.add_node("qr[1]") - qr_2 = dag.add_node("qr[2]") - cr_0 = dag.add_node("cr[0]") - cr_1 = dag.add_node("cr[1]") - - # wires - cx_1 = dag.add_node("cx_1") - dag.add_edge(qr_0, cx_1, "qr[0]") - dag.add_edge(qr_1, cx_1, "qr[1]") - h_1 = dag.add_node("h_1") - dag.add_edge(cx_1, h_1, "qr[0]") - cx_2 = dag.add_node("cx_2") - dag.add_edge(cx_1, cx_2, "qr[1]") - dag.add_edge(qr_2, cx_2, "qr[2]") - cx_3 = dag.add_node("cx_3") - dag.add_edge(h_1, cx_3, "qr[0]") - dag.add_edge(cx_2, cx_3, "qr[2]") - h_2 = dag.add_node("h_2") - dag.add_edge(cx_3, h_2, "qr[2]") - - # outputs - qr_0_out = dag.add_node("qr[0]_out") - dag.add_edge(cx_3, qr_0_out, "qr[0]") - qr_1_out = dag.add_node("qr[1]_out") - dag.add_edge(cx_2, qr_1_out, "qr[1]") - qr_2_out = dag.add_node("qr[2]_out") - dag.add_edge(h_2, qr_2_out, "qr[2]") - cr_0_out = dag.add_node("cr[0]_out") - dag.add_edge(cr_0, cr_0_out, "qr[2]") - cr_1_out = dag.add_node("cr[1]_out") - dag.add_edge(cr_1, cr_1_out, "cr[1]") - - res = list(retworkx.lexicographical_topological_sort(dag, lambda x: str(x))) - expected = [ - "cr[0]", - "cr[0]_out", - "cr[1]", - "cr[1]_out", - "qr[0]", - "qr[1]", - "cx_1", - "h_1", - "qr[2]", - "cx_2", - "cx_3", - "h_2", - "qr[0]_out", - "qr[1]_out", - "qr[2]_out", - ] - self.assertEqual(expected, res) - - def test_get_node_data(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - self.assertEqual("b", dag.get_node_data(node_b)) - - def test_get_node_data_bad_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", "Edgy") - self.assertRaises(IndexError, dag.get_node_data, 42) - - def test_pydag_length(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", "Edgy") - self.assertEqual(2, len(dag)) - - def test_pydag_length_empty(self): - dag = retworkx.PyDAG() - self.assertEqual(0, len(dag)) - - def test_pydigraph_num_nodes(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "An_edge") - self.assertEqual(2, graph.num_nodes()) - - def test_pydigraph_num_nodes_empty(self): - graph = retworkx.PyDiGraph() - self.assertEqual(0, graph.num_nodes()) - - def test_add_nodes_from(self): - dag = retworkx.PyDAG() - nodes = list(range(100)) - res = dag.add_nodes_from(nodes) - self.assertEqual(len(res), 100) - self.assertEqual(res, nodes) - - def test_add_node_from_empty(self): - dag = retworkx.PyDAG() - res = dag.add_nodes_from([]) - self.assertEqual(len(res), 0) - - def test_get_node_data_getitem(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - self.assertEqual("b", dag[node_b]) - - def test_get_node_data_getitem_bad_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", "Edgy") - with self.assertRaises(IndexError): - dag[42] - - def test_set_node_data_setitem(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - dag[node_b] = "Oh so cool" - self.assertEqual("Oh so cool", dag[node_b]) - - def test_set_node_data_setitem_bad_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", "Edgy") - with self.assertRaises(IndexError): - dag[42] = "Oh so cool" - - def test_remove_node_delitem(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", "Edgy") - dag.add_child(node_b, "c", "Edgy_mk2") - del dag[node_b] - res = dag.nodes() - self.assertEqual(["a", "c"], res) - self.assertEqual([0, 2], dag.node_indexes()) - - def test_remove_node_delitem_invalid_index(self): - graph = retworkx.PyDAG() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - with self.assertRaises(IndexError): - del graph[76] - res = graph.nodes() - self.assertEqual(["a", "b", "c"], res) - self.assertEqual([0, 1, 2], graph.node_indexes()) - - def test_find_node_by_weight(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(10))) - res = graph.find_node_by_weight(9) - self.assertEqual(res, 9) - - def test_find_node_by_weight_no_match(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(10))) - res = graph.find_node_by_weight(42) - self.assertEqual(res, None) - - def test_find_node_by_weight_multiple_matches(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(["a", "a"]) - res = graph.find_node_by_weight("a") - self.assertEqual(res, 0) - - def test_merge_nodes(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(["a", "a", "b", "c"]) - graph.add_edge(0, 2, "edge0") - graph.add_edge(3, 0, "edge1") - graph.merge_nodes(0, 1) - self.assertEqual(graph.node_indexes(), [1, 2, 3]) - self.assertEqual([(3, 1, "edge1"), (1, 2, "edge0")], graph.weighted_edge_list()) - - def test_merge_nodes_no_match(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(["a", "a", "b", "c"]) - graph.add_edge(0, 2, "edge0") - graph.add_edge(3, 0, "edge1") - graph.merge_nodes(0, 2) - self.assertEqual(graph.node_indexes(), [0, 1, 2, 3]) - self.assertEqual([(0, 2, "edge0"), (3, 0, "edge1")], graph.weighted_edge_list()) - - def test_merge_nodes_invalid_node_first_index(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(["a", "b"]) - with self.assertRaises(IndexError): - graph.merge_nodes(2, 0) - - def test_merge_nodes_invalid_node_second_index(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(["a", "b"]) - with self.assertRaises(IndexError): - graph.merge_nodes(0, 3) diff --git a/tests/retworkx_backwards_compat/digraph/test_num_shortest_path.py b/tests/retworkx_backwards_compat/digraph/test_num_shortest_path.py deleted file mode 100644 index 07b9d41b89..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_num_shortest_path.py +++ /dev/null @@ -1,140 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestNumShortestpath(unittest.TestCase): - def test_num_shortest_path_unweighted(self): - graph = retworkx.PyDiGraph() - node_a = graph.add_node(0) - node_b = graph.add_node("end") - for i in range(3): - node = graph.add_child(node_a, i, None) - graph.add_edge(node, node_b, None) - res = retworkx.digraph_num_shortest_paths_unweighted(graph, node_a) - expected = {2: 1, 4: 1, 3: 1, 1: 3} - self.assertEqual(expected, res) - - def test_parallel_paths(self): - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list( - [ - (0, 1), - (1, 2), - (2, 3), - (0, 4), - (4, 5), - (5, 3), - ] - ) - res = retworkx.num_shortest_paths_unweighted(graph, 0) - expected = { - 1: 1, - 2: 1, - 3: 2, - 4: 1, - 5: 1, - } - self.assertEqual(expected, res) - - def test_grid_graph(self): - """Test num shortest paths for a 5x5 grid graph - 0 -> 1 -> 2 -> 3 -> 4 - | | | | | - v v v v v - 5 -> 6 -> 7 -> 8 -> 9 - | | | | | - v v v v v - 10-> 11-> 12-> 13-> 14 - | | | | | - v v v v v - 15-> 16-> 17-> 18-> 19 - | | | | | - v v v v v - 20-> 21-> 22-> 23-> 24 - """ - graph = retworkx.generators.directed_grid_graph(5, 5) - res = retworkx.num_shortest_paths_unweighted(graph, 0) - expected = { - 1: 1, - 2: 1, - 3: 1, - 4: 1, - 5: 1, - 6: 2, - 7: 3, - 8: 4, - 9: 5, - 10: 1, - 11: 3, - 12: 6, - 13: 10, - 14: 15, - 15: 1, - 16: 4, - 17: 10, - 18: 20, - 19: 35, - 20: 1, - 21: 5, - 22: 15, - 23: 35, - 24: 70, - } - self.assertEqual(expected, res) - - def test_node_with_no_path(self): - graph = retworkx.generators.directed_path_graph(5) - graph.extend_from_edge_list([(6, 7), (7, 8), (8, 9), (9, 10), (10, 11)]) - expected = {1: 1, 2: 1, 3: 1, 4: 1} - res = retworkx.num_shortest_paths_unweighted(graph, 0) - self.assertEqual(expected, res) - res = retworkx.num_shortest_paths_unweighted(graph, 6) - expected = {7: 1, 8: 1, 9: 1, 10: 1, 11: 1} - self.assertEqual(expected, res) - - def test_node_indices_with_holes(self): - graph = retworkx.generators.directed_path_graph(5) - graph.extend_from_edge_list([(6, 7), (7, 8), (8, 9), (9, 10), (10, 11)]) - graph.add_edge(4, 6, None) - graph.remove_node(5) - expected = { - 1: 1, - 2: 1, - 3: 1, - 4: 1, - 6: 1, - 7: 1, - 8: 1, - 9: 1, - 10: 1, - 11: 1, - } - res = retworkx.num_shortest_paths_unweighted(graph, 0) - self.assertEqual(expected, res) - - def test_no_edges(self): - graph = retworkx.PyDiGraph() - graph.add_node(0) - graph.add_node(1) - res = retworkx.num_shortest_paths_unweighted(graph, 0) - self.assertEqual({}, res) - - def test_invalid_source_index(self): - graph = retworkx.PyDiGraph() - graph.add_node(0) - graph.add_child(0, 1, None) - with self.assertRaises(IndexError): - retworkx.num_shortest_paths_unweighted(graph, 4) diff --git a/tests/retworkx_backwards_compat/digraph/test_pred_succ.py b/tests/retworkx_backwards_compat/digraph/test_pred_succ.py deleted file mode 100644 index 7f655044a0..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_pred_succ.py +++ /dev/null @@ -1,385 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestPredecessors(unittest.TestCase): - def test_single_predecessor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - res = dag.predecessors(node_c) - self.assertEqual(["a"], res) - - def test_single_predecessor_multiple_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - dag.add_edge(node_a, node_c, {"a": 3}) - res = dag.predecessors(node_c) - self.assertEqual(["a"], res) - - def test_many_parents(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(10): - dag.add_parent(node_a, {"numeral": i}, {"edge": i}) - res = dag.predecessors(node_a) - self.assertEqual( - [ - {"numeral": 9}, - {"numeral": 8}, - {"numeral": 7}, - {"numeral": 6}, - {"numeral": 5}, - {"numeral": 4}, - {"numeral": 3}, - {"numeral": 2}, - {"numeral": 1}, - {"numeral": 0}, - ], - res, - ) - - -class TestSuccessors(unittest.TestCase): - def test_single_successor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - dag.add_child(node_c, "d", {"a": 1}) - res = dag.successors(node_b) - self.assertEqual(["c"], res) - - def test_single_successor_multiple_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - dag.add_child(node_c, "d", {"a": 1}) - dag.add_edge(node_b, node_c, {"a": 3}) - res = dag.successors(node_b) - self.assertEqual(["c"], res) - - def test_many_children(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(10): - dag.add_child(node_a, {"numeral": i}, {"edge": i}) - res = dag.successors(node_a) - self.assertEqual( - [ - {"numeral": 9}, - {"numeral": 8}, - {"numeral": 7}, - {"numeral": 6}, - {"numeral": 5}, - {"numeral": 4}, - {"numeral": 3}, - {"numeral": 2}, - {"numeral": 1}, - {"numeral": 0}, - ], - res, - ) - - -class TestFindPredecessorsByEdge(unittest.TestCase): - def test_single_predecessor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - - res_even = dag.find_predecessors_by_edge(node_c, lambda x: x["a"] % 2 == 0) - - res_odd = dag.find_predecessors_by_edge(node_c, lambda x: x["a"] % 2 != 0) - - self.assertEqual(["a"], res_even) - self.assertEqual([], res_odd) - - def test_single_predecessor_multiple_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_a, "c", {"a": 2}) - dag.add_edge(node_a, node_c, {"a": 3}) - - res_even = dag.find_predecessors_by_edge(node_c, lambda x: x["a"] % 2 == 0) - - res_odd = dag.find_predecessors_by_edge(node_c, lambda x: x["a"] % 2 == 0) - - self.assertEqual(["a"], res_even) - self.assertEqual(["a"], res_odd) - - def test_many_parents(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(10): - dag.add_parent(node_a, {"numeral": i}, {"edge": i}) - - res_even = dag.find_predecessors_by_edge(node_a, lambda x: x["edge"] % 2 == 0) - - res_odd = dag.find_predecessors_by_edge(node_a, lambda x: x["edge"] % 2 != 0) - - self.assertEqual( - [ - {"numeral": 8}, - {"numeral": 6}, - {"numeral": 4}, - {"numeral": 2}, - {"numeral": 0}, - ], - res_even, - ) - - self.assertEqual( - [ - {"numeral": 9}, - {"numeral": 7}, - {"numeral": 5}, - {"numeral": 3}, - {"numeral": 1}, - ], - res_odd, - ) - - def test_no_parents(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - - res = dag.find_predecessors_by_edge(node_a, lambda _: True) - - self.assertEqual([], res) - - -class TestFindSuccessorsByEdge(unittest.TestCase): - def test_single_successor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - dag.add_child(node_c, "d", {"a": 1}) - - res_even = dag.find_successors_by_edge(node_b, lambda x: x["a"] % 2 == 0) - res_odd = dag.find_successors_by_edge(node_b, lambda x: x["a"] % 2 != 0) - - self.assertEqual(["c"], res_even) - self.assertEqual([], res_odd) - - def test_single_successor_multiple_edges(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - dag.add_child(node_c, "d", {"a": 1}) - dag.add_edge(node_b, node_c, {"a": 3}) - - res_even = dag.find_successors_by_edge(node_b, lambda x: x["a"] % 2 == 0) - res_odd = dag.find_successors_by_edge(node_b, lambda x: x["a"] % 2 != 0) - - self.assertEqual(["c"], res_even) - self.assertEqual(["c"], res_odd) - - def test_many_children(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(10): - dag.add_child(node_a, {"numeral": i}, {"edge": i}) - - res_even = dag.find_successors_by_edge(node_a, lambda x: x["edge"] % 2 == 0) - - res_odd = dag.find_successors_by_edge(node_a, lambda x: x["edge"] % 2 != 0) - - self.assertEqual( - [ - {"numeral": 8}, - {"numeral": 6}, - {"numeral": 4}, - {"numeral": 2}, - {"numeral": 0}, - ], - res_even, - ) - - self.assertEqual( - [ - {"numeral": 9}, - {"numeral": 7}, - {"numeral": 5}, - {"numeral": 3}, - {"numeral": 1}, - ], - res_odd, - ) - - def test_no_children(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - - res = dag.find_successors_by_edge(node_a, lambda _: True) - - self.assertEqual([], res) - - -class TestBfsSuccessors(unittest.TestCase): - def test_single_successor(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - node_b = dag.add_child(node_a, "b", {"a": 1}) - node_c = dag.add_child(node_b, "c", {"a": 2}) - dag.add_child(node_c, "d", {"a": 1}) - res = retworkx.bfs_successors(dag, node_b) - self.assertEqual([("b", ["c"]), ("c", ["d"])], res) - - def test_many_children(self): - dag = retworkx.PyDAG() - node_a = dag.add_node("a") - for i in range(10): - dag.add_child(node_a, {"numeral": i}, {"edge": i}) - res = retworkx.bfs_successors(dag, node_a) - self.assertEqual( - [ - ( - "a", - [ - {"numeral": 9}, - {"numeral": 8}, - {"numeral": 7}, - {"numeral": 6}, - {"numeral": 5}, - {"numeral": 4}, - {"numeral": 3}, - {"numeral": 2}, - {"numeral": 1}, - {"numeral": 0}, - ], - ) - ], - res, - ) - - def test_bfs_succesors(self): - dag = retworkx.PyDAG() - node_a = dag.add_node(0) - node_b = dag.add_child(node_a, 1, {}) - node_c = dag.add_child(node_b, 2, {}) - node_d = dag.add_child(node_c, 3, {}) - node_e = dag.add_child(node_d, 4, {}) - node_f = dag.add_child(node_e, 5, {}) - dag.add_child(node_f, 6, {}) - node_h = dag.add_child(node_c, 7, {}) - node_i = dag.add_child(node_h, 8, {}) - node_j = dag.add_child(node_i, 9, {}) - dag.add_child(node_j, 10, {}) - res = {n: sorted(s) for n, s in retworkx.bfs_successors(dag, node_b)} - expected = { - 1: [2], - 2: [3, 7], - 3: [4], - 4: [5], - 5: [6], - 7: [8], - 8: [9], - 9: [10], - } - self.assertEqual(expected, res) - self.assertEqual( - [(7, [8]), (8, [9]), (9, [10])], - retworkx.bfs_successors(dag, node_h), - ) - - def test_bfs_successors_sequence(self): - dag = retworkx.PyDAG() - node_a = dag.add_node(0) - node_b = dag.add_child(node_a, 1, {}) - node_c = dag.add_child(node_b, 2, {}) - node_d = dag.add_child(node_c, 3, {}) - node_e = dag.add_child(node_d, 4, {}) - node_f = dag.add_child(node_e, 5, {}) - dag.add_child(node_f, 6, {}) - node_h = dag.add_child(node_c, 7, {}) - node_i = dag.add_child(node_h, 8, {}) - node_j = dag.add_child(node_i, 9, {}) - dag.add_child(node_j, 10, {}) - res = retworkx.bfs_successors(dag, node_b) - expected = [ - (1, [2]), - (2, [7, 3]), - (7, [8]), - (3, [4]), - (8, [9]), - (4, [5]), - (9, [10]), - (5, [6]), - ] - for index, expected_value in enumerate(expected): - self.assertEqual((res[index][0], res[index][1]), expected_value) - - def test_bfs_successors_sequence_invalid_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node(0) - node_b = dag.add_child(node_a, 1, {}) - node_c = dag.add_child(node_b, 2, {}) - node_d = dag.add_child(node_c, 3, {}) - node_e = dag.add_child(node_d, 4, {}) - node_f = dag.add_child(node_e, 5, {}) - dag.add_child(node_f, 6, {}) - node_h = dag.add_child(node_c, 7, {}) - node_i = dag.add_child(node_h, 8, {}) - node_j = dag.add_child(node_i, 9, {}) - dag.add_child(node_j, 10, {}) - res = retworkx.bfs_successors(dag, node_b) - with self.assertRaises(IndexError): - res[8] - - def test_bfs_successors_sequence_negative_index(self): - dag = retworkx.PyDAG() - node_a = dag.add_node(0) - node_b = dag.add_child(node_a, 1, {}) - node_c = dag.add_child(node_b, 2, {}) - node_d = dag.add_child(node_c, 3, {}) - node_e = dag.add_child(node_d, 4, {}) - node_f = dag.add_child(node_e, 5, {}) - dag.add_child(node_f, 6, {}) - node_h = dag.add_child(node_c, 7, {}) - node_i = dag.add_child(node_h, 8, {}) - node_j = dag.add_child(node_i, 9, {}) - dag.add_child(node_j, 10, {}) - res = retworkx.bfs_successors(dag, node_b) - self.assertEqual((5, [6]), res[-1]) - self.assertEqual((4, [5]), res[-3]) - - def test_bfs_successors_sequence_stop_iterator(self): - dag = retworkx.PyDAG() - node_a = dag.add_node(0) - node_b = dag.add_child(node_a, 1, {}) - node_c = dag.add_child(node_b, 2, {}) - node_d = dag.add_child(node_c, 3, {}) - node_e = dag.add_child(node_d, 4, {}) - node_f = dag.add_child(node_e, 5, {}) - dag.add_child(node_f, 6, {}) - node_h = dag.add_child(node_c, 7, {}) - node_i = dag.add_child(node_h, 8, {}) - node_j = dag.add_child(node_i, 9, {}) - dag.add_child(node_j, 10, {}) - res = iter(retworkx.bfs_successors(dag, node_b)) - for _ in range(8): - next(res) - with self.assertRaises(StopIteration): - next(res) diff --git a/tests/retworkx_backwards_compat/digraph/test_spring_layout.py b/tests/retworkx_backwards_compat/digraph/test_spring_layout.py deleted file mode 100644 index 13d6aa0fba..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_spring_layout.py +++ /dev/null @@ -1,73 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestSpringLayout(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - node_a = self.graph.add_node(1) - node_b = self.graph.add_node(2) - self.graph.add_edge(node_a, node_b, 1) - node_c = self.graph.add_node(3) - self.graph.add_edge(node_a, node_c, 2) - - def test_empty_graph(self): - graph = retworkx.PyGraph() - res = retworkx.spring_layout(graph) - self.assertEqual({}, res) - - def test_simple_graph(self): - res = retworkx.spring_layout(self.graph, seed=42) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_simple_graph_with_edge_weights(self): - res = retworkx.spring_layout(self.graph, weight_fn=lambda e: e) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_simple_graph_center(self): - res = retworkx.spring_layout(self.graph, center=[0.5, 0.5]) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_simple_graph_fixed(self): - pos = {0: [0.1, 0.1]} - res = retworkx.spring_layout(self.graph, pos=pos, fixed={0}) - self.assertEqual(res[0], pos[0]) - - def test_simple_graph_fixed_not_pos(self): - with self.assertRaises(ValueError): - retworkx.spring_layout(self.graph, fixed={0}) - - def test_simple_graph_linear_cooling(self): - res = retworkx.spring_layout(self.graph, adaptive_cooling=False) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_graph_with_removed_nodes(self): - graph = retworkx.PyDiGraph() - nodes = graph.add_nodes_from([0, 1, 2]) - graph.remove_node(nodes[1]) - res = retworkx.spring_layout(graph) - self.assertEqual(len(res), 2) - self.assertTrue(nodes[0] in res) - self.assertTrue(nodes[2] in res) - self.assertFalse(nodes[1] in res) diff --git a/tests/retworkx_backwards_compat/digraph/test_strongly_connected.py b/tests/retworkx_backwards_compat/digraph/test_strongly_connected.py deleted file mode 100644 index 0e16790041..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_strongly_connected.py +++ /dev/null @@ -1,67 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestStronglyConnected(unittest.TestCase): - def test_number_strongly_connected_all_strong(self): - G = retworkx.PyDiGraph() - node_a = G.add_node(1) - node_b = G.add_child(node_a, 2, {}) - node_c = G.add_child(node_b, 3, {}) - self.assertEqual( - retworkx.strongly_connected_components(G), - [[node_c], [node_b], [node_a]], - ) - - def test_number_strongly_connected(self): - G = retworkx.PyDiGraph() - node_a = G.add_node(1) - node_b = G.add_child(node_a, 2, {}) - node_c = G.add_node(3) - self.assertEqual( - retworkx.strongly_connected_components(G), - [[node_c], [node_b], [node_a]], - ) - - def test_stongly_connected_no_linear(self): - G = retworkx.PyDiGraph() - G.add_nodes_from(list(range(8))) - G.add_edges_from_no_data( - [ - (0, 1), - (1, 2), - (1, 7), - (2, 3), - (2, 6), - (3, 4), - (4, 2), - (4, 5), - (6, 3), - (6, 5), - (7, 0), - (7, 6), - ] - ) - expected = [[5], [2, 3, 4, 6], [0, 1, 7]] - components = retworkx.strongly_connected_components(G) - self.assertEqual(components, expected) - - def test_number_strongly_connected_big(self): - G = retworkx.PyDiGraph() - for i in range(100000): - node = G.add_node(i) - G.add_child(node, str(i), {}) - self.assertEqual(len(retworkx.strongly_connected_components(G)), 200000) diff --git a/tests/retworkx_backwards_compat/digraph/test_subgraph.py b/tests/retworkx_backwards_compat/digraph/test_subgraph.py deleted file mode 100644 index 2b19343f03..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_subgraph.py +++ /dev/null @@ -1,150 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestSubgraph(unittest.TestCase): - def test_subgraph(self): - graph = retworkx.PyDiGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([1, 3]) - self.assertEqual([(0, 1, 4)], subgraph.weighted_edge_list()) - self.assertEqual(["b", "d"], subgraph.nodes()) - - def test_subgraph_empty_list(self): - graph = retworkx.PyDiGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([]) - self.assertEqual([], subgraph.weighted_edge_list()) - self.assertEqual(0, len(subgraph)) - - def test_subgraph_invalid_entry(self): - graph = retworkx.PyDiGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([42]) - self.assertEqual([], subgraph.weighted_edge_list()) - self.assertEqual(0, len(subgraph)) - - def test_subgraph_pass_by_reference(self): - graph = retworkx.PyDiGraph() - graph.add_node({"a": 0}) - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([0, 1, 3]) - self.assertEqual([(0, 1, 1), (0, 2, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - self.assertEqual([{"a": 0}, "b", "d"], subgraph.nodes()) - graph[0]["a"] = 4 - self.assertEqual(subgraph[0]["a"], 4) - - def test_subgraph_replace_weight_no_reference(self): - graph = retworkx.PyDiGraph() - graph.add_node({"a": 0}) - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([0, 1, 3]) - self.assertEqual([(0, 1, 1), (0, 2, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - self.assertEqual([{"a": 0}, "b", "d"], subgraph.nodes()) - graph[0] = 4 - self.assertEqual(subgraph[0]["a"], 0) - - def test_edge_subgraph(self): - graph = retworkx.PyDiGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.edge_subgraph([(0, 1), (1, 3)]) - self.assertEqual(["a", "b", "d"], subgraph.nodes()) - self.assertEqual([(0, 1, 1), (1, 3, 4)], subgraph.weighted_edge_list()) - - def test_edge_subgraph_parallel_edge(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.extend_from_weighted_edge_list( - [ - (0, 1, 2), - (0, 1, 3), - (0, 2, 2), - (1, 2, 4), - (0, 3, 5), - (2, 3, 6), - ] - ) - subgraph = graph.edge_subgraph([(0, 1), (1, 2)]) - self.assertEqual([0, 1, 2], subgraph.nodes()) - self.assertEqual([(0, 1, 2), (0, 1, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - - def test_edge_subgraph_empty_list(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.extend_from_weighted_edge_list( - [ - (0, 1, 2), - (0, 1, 3), - (0, 2, 2), - (1, 2, 4), - (0, 3, 5), - (2, 3, 6), - ] - ) - subgraph = graph.edge_subgraph([]) - self.assertEqual([], subgraph.nodes()) - - def test_edge_subgraph_non_edge(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(4))) - graph.extend_from_weighted_edge_list( - [ - (0, 1, 2), - (0, 1, 3), - (0, 2, 2), - (1, 2, 4), - (0, 3, 5), - (2, 3, 6), - ] - ) - # 1->3 isn't an edge in graph - subgraph = graph.edge_subgraph([(0, 1), (1, 2), (1, 3)]) - self.assertEqual([0, 1, 2], subgraph.nodes()) - self.assertEqual([(0, 1, 2), (0, 1, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - - def test_preserve_attrs(self): - graph = retworkx.PyGraph(attrs="My attribute") - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([1, 3], preserve_attrs=True) - self.assertEqual([(0, 1, 4)], subgraph.weighted_edge_list()) - self.assertEqual(["b", "d"], subgraph.nodes()) - self.assertEqual(graph.attrs, subgraph.attrs) diff --git a/tests/retworkx_backwards_compat/digraph/test_subgraph_isomorphic.py b/tests/retworkx_backwards_compat/digraph/test_subgraph_isomorphic.py deleted file mode 100644 index 8bcdf61e57..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_subgraph_isomorphic.py +++ /dev/null @@ -1,266 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestSubgraphIsomorphic(unittest.TestCase): - def test_empty_subgraph_isomorphic_identical(self): - g_a = retworkx.PyDiGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_a, id_order=id_order)) - - def test_empty_subgraph_isomorphic(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order)) - - def test_empty_subgraph_isomorphic_compare_nodes(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_subgraph_isomorphic( - g_a, g_b, lambda x, y: x == y, id_order=id_order - ) - ) - - def test_subgraph_isomorphic_identical(self): - g_a = retworkx.PyDiGraph() - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_a, id_order=id_order)) - - def test_subgraph_isomorphic_mismatch_node_data(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["b_1", "b_2", "b_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "b_1"), (nodes[1], nodes[2], "b_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order)) - - def test_subgraph_isomorphic_compare_nodes_mismatch_node_data(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["b_1", "b_2", "b_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "b_1"), (nodes[1], nodes[2], "b_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse( - retworkx.is_subgraph_isomorphic( - g_a, g_b, lambda x, y: x == y, id_order=id_order - ) - ) - - def test_subgraph_isomorphic_compare_nodes_identical(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_subgraph_isomorphic( - g_a, g_b, lambda x, y: x == y, id_order=id_order - ) - ) - - def test_is_subgraph_isomorphic_nodes_compare_raises(self): - g_a = retworkx.PyDiGraph() - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - def compare_nodes(a, b): - raise TypeError("Failure") - - self.assertRaises( - TypeError, - retworkx.is_subgraph_isomorphic, - (g_a, g_a, compare_nodes), - ) - - def test_subgraph_isomorphic_compare_edges_identical(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_subgraph_isomorphic( - g_a, - g_b, - edge_matcher=lambda x, y: x == y, - id_order=id_order, - ) - ) - - def test_subgraph_isomorphic_node_count_not_ge(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1")]) - - nodes = g_b.add_nodes_from(["a_0", "a_1", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse(retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order)) - - def test_subgraph_isomorphic_edge_matcher(self): - first = retworkx.PyDiGraph() - first.extend_from_weighted_edge_list([(0, 1, "a"), (1, 2, "b"), (2, 0, "c")]) - second = retworkx.PyDiGraph() - second.extend_from_weighted_edge_list([(0, 1, "a"), (1, 2, "b")]) - - self.assertTrue( - retworkx.is_subgraph_isomorphic( - first, second, induced=False, edge_matcher=lambda x, y: x == y - ) - ) - - def test_subgraph_isomorphic_mismatch_edge_data_parallel_edges(self): - first = retworkx.PyDiGraph() - first.extend_from_weighted_edge_list([(0, 1, "a"), (0, 1, "f"), (1, 2, "b"), (2, 0, "c")]) - second = retworkx.PyDiGraph() - second.extend_from_weighted_edge_list([(0, 1, "a"), (0, 1, "a"), (1, 2, "b")]) - - self.assertFalse( - retworkx.is_subgraph_isomorphic( - first, second, id_order=True, edge_matcher=lambda x, y: x == y - ) - ) - - def test_non_induced_subgraph_isomorphic(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[2], nodes[0], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order, induced=True): - self.assertFalse( - retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order, induced=True) - ) - with self.subTest(id_order=id_order, induced=False): - self.assertTrue( - retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order, induced=False) - ) - - def test_non_induced_grid_subgraph_isomorphic(self): - g_a = retworkx.generators.directed_grid_graph(2, 2) - g_b = retworkx.PyDiGraph() - g_b.add_nodes_from([0, 1, 2, 3]) - g_b.add_edges_from_no_data([(0, 1), (2, 3)]) - - self.assertFalse(retworkx.is_subgraph_isomorphic(g_a, g_b, induced=True)) - - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_b, induced=False)) - - def test_subgraph_vf2_mapping(self): - graph = retworkx.generators.directed_grid_graph(10, 10) - second_graph = retworkx.generators.directed_grid_graph(2, 2) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph, subgraph=True) - self.assertEqual(next(mapping), {0: 0, 1: 1, 10: 2, 11: 3}) - - def test_subgraph_vf2_all_mappings(self): - graph = retworkx.generators.directed_path_graph(3) - second_graph = retworkx.generators.directed_path_graph(2) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph, subgraph=True, id_order=True) - self.assertEqual(next(mapping), {0: 0, 1: 1}) - self.assertEqual(next(mapping), {2: 1, 1: 0}) - - def test_subgraph_vf2_mapping_vf2pp(self): - graph = retworkx.generators.directed_grid_graph(3, 3) - second_graph = retworkx.generators.directed_grid_graph(2, 2) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph, subgraph=True, id_order=False) - self.assertEqual(next(mapping), {4: 0, 5: 1, 7: 2, 8: 3}) - - def test_vf2pp_remapping(self): - temp = retworkx.generators.directed_grid_graph(3, 3) - - graph = retworkx.PyDiGraph() - dummy = graph.add_node(0) - - graph.compose(temp, dict()) - graph.remove_node(dummy) - - second_graph = retworkx.generators.directed_grid_graph(2, 2) - mapping = retworkx.digraph_vf2_mapping(graph, second_graph, subgraph=True, id_order=False) - self.assertEqual(next(mapping), {5: 0, 6: 1, 8: 2, 9: 3}) - - def test_empty_digraph_subgraph_vf2_mapping(self): - g_a = retworkx.PyDiGraph() - g_b = retworkx.PyDiGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - mapping = retworkx.digraph_vf2_mapping(g_a, g_b, id_order=id_order, subgraph=True) - self.assertEqual({}, next(mapping)) diff --git a/tests/retworkx_backwards_compat/digraph/test_substitute_node_with_subgraph.py b/tests/retworkx_backwards_compat/digraph/test_substitute_node_with_subgraph.py deleted file mode 100644 index c6f7996bca..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_substitute_node_with_subgraph.py +++ /dev/null @@ -1,163 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestSubstitute(unittest.TestCase): - def setUp(self): - super().setUp() - self.graph = retworkx.generators.directed_path_graph(5) - - def test_empty_replacement(self): - in_graph = retworkx.PyDiGraph() - res = self.graph.substitute_node_with_subgraph(2, in_graph, lambda _, __, ___: None) - self.assertEqual(res, {}) - self.assertEqual([(0, 1), (3, 4)], self.graph.edge_list()) - - def test_single_node(self): - in_graph = retworkx.PyDiGraph() - in_graph.add_node(0) - in_graph.add_child(0, 1, "edge") - res = self.graph.substitute_node_with_subgraph(2, in_graph, lambda _, __, ___: 0) - self.assertEqual([(0, 1), (3, 4), (5, 6), (1, 5), (5, 3)], self.graph.edge_list()) - self.assertEqual("edge", self.graph.get_edge_data(5, 6)) - self.assertEqual(res, {0: 5, 1: 6}) - - def test_node_filter(self): - in_graph = retworkx.PyDiGraph() - in_graph.add_node(0) - in_graph.add_child(0, 1, "edge") - res = self.graph.substitute_node_with_subgraph( - 2, - in_graph, - lambda _, __, ___: 0, - node_filter=lambda node: node == 0, - ) - self.assertEqual([(0, 1), (3, 4), (1, 5), (5, 3)], self.graph.edge_list()) - self.assertEqual(res, {0: 5}) - - def test_edge_weight_modifier(self): - in_graph = retworkx.PyDiGraph() - in_graph.add_node(0) - in_graph.add_child(0, 1, "edge") - res = self.graph.substitute_node_with_subgraph( - 2, - in_graph, - lambda _, __, ___: 0, - edge_weight_map=lambda edge: edge + "-migrated", - ) - self.assertEqual([(0, 1), (3, 4), (5, 6), (1, 5), (5, 3)], self.graph.edge_list()) - self.assertEqual("edge-migrated", self.graph.get_edge_data(5, 6)) - self.assertEqual(res, {0: 5, 1: 6}) - - def test_none_mapping(self): - in_graph = retworkx.PyDiGraph() - in_graph.add_node(0) - in_graph.add_child(0, 1, "edge") - res = self.graph.substitute_node_with_subgraph(2, in_graph, lambda _, __, ___: None) - self.assertEqual([(0, 1), (3, 4), (5, 6)], self.graph.edge_list()) - self.assertEqual(res, {0: 5, 1: 6}) - - def test_multiple_mapping(self): - graph = retworkx.generators.directed_star_graph(5) - in_graph = retworkx.generators.directed_star_graph(3, inward=True) - - def map_function(source, target, _weight): - if target > 2: - return 2 - return 1 - - res = graph.substitute_node_with_subgraph(0, in_graph, map_function) - self.assertEqual({0: 5, 1: 6, 2: 7}, res) - expected = [(6, 5), (7, 5), (7, 4), (7, 3), (6, 2), (6, 1)] - self.assertEqual(expected, graph.edge_list()) - - def test_multiple_mapping_full(self): - graph = retworkx.generators.directed_star_graph(5) - in_graph = retworkx.generators.directed_star_graph(weights=list(range(3)), inward=True) - in_graph.add_edge(1, 2, None) - - def map_function(source, target, _weight): - if target > 2: - return 2 - return 1 - - def filter_fn(node): - return node > 0 - - def map_weight(_): - return "migrated" - - res = graph.substitute_node_with_subgraph(0, in_graph, map_function, filter_fn, map_weight) - self.assertEqual({1: 5, 2: 6}, res) - expected = [ - (5, 6, "migrated"), - (6, 4, None), - (6, 3, None), - (5, 2, None), - (5, 1, None), - ] - self.assertEqual(expected, graph.weighted_edge_list()) - - def test_invalid_target(self): - in_graph = retworkx.generators.directed_grid_graph(5, 5) - with self.assertRaises(IndexError): - self.graph.substitute_node_with_subgraph(0, in_graph, lambda *args: 42) - - def test_invalid_target_both_directions(self): - graph = retworkx.generators.directed_star_graph(4, inward=True) - in_graph = retworkx.generators.directed_grid_graph(5, 5) - with self.assertRaises(IndexError): - graph.substitute_node_with_subgraph(0, in_graph, lambda *args: 42) - graph = retworkx.generators.directed_star_graph(4, inward=False) - with self.assertRaises(IndexError): - graph.substitute_node_with_subgraph(0, in_graph, lambda *args: 42) - - def test_invalid_node_id(self): - in_graph = retworkx.generators.directed_grid_graph(5, 5) - with self.assertRaises(IndexError): - self.graph.substitute_node_with_subgraph(16, in_graph, lambda *args: None) - - def test_bidrectional(self): - graph = retworkx.generators.directed_path_graph(5, bidirectional=True) - in_graph = retworkx.generators.directed_star_graph(5, bidirectional=True) - - def map_function(source, target, _weight): - if source != 2: - return 0 - else: - return target - - res = graph.substitute_node_with_subgraph(2, in_graph, map_function) - expected_node_map = {0: 5, 1: 6, 2: 7, 3: 8, 4: 9} - self.assertEqual(expected_node_map, res) - expected_edge_list = [ - (0, 1), # From graph - (1, 0), # From graph - (3, 4), # From graph - (4, 3), # From graph - (6, 5), # From in_graph - (5, 6), # From in_graph - (7, 5), # From in_graph - (5, 7), # From in_graph - (8, 5), # From in_graph - (5, 8), # From in_graph - (9, 5), # From in_graph - (5, 9), # From in_graph - (3, 5), # output of res[map_function(3, 2, None)] -> 5 - (1, 5), # output of res[map_function(1, 2, None)] -> 5 - (8, 3), # output of res[map_function(2, 3, None)] -> 8 - (6, 1), # output of res[map_function(2, 1, None)] -> 6 - ] - self.assertEqual(expected_edge_list, graph.edge_list()) diff --git a/tests/retworkx_backwards_compat/digraph/test_symmetric.py b/tests/retworkx_backwards_compat/digraph/test_symmetric.py deleted file mode 100644 index 4cb54708e4..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_symmetric.py +++ /dev/null @@ -1,39 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestSymmetric(unittest.TestCase): - def test_single_neighbor(self): - digraph = retworkx.PyDiGraph() - node_a = digraph.add_node("a") - digraph.add_child(node_a, "b", {"a": 1}) - digraph.add_child(node_a, "c", {"a": 2}) - self.assertFalse(digraph.is_symmetric()) - - def test_bidirectional_ring(self): - digraph = retworkx.PyDiGraph() - edge_list = [ - (0, 1), - (1, 0), - (1, 2), - (2, 1), - (2, 3), - (3, 2), - (3, 0), - (0, 3), - ] - digraph.extend_from_edge_list(edge_list) - self.assertTrue(digraph.is_symmetric()) diff --git a/tests/retworkx_backwards_compat/digraph/test_tensor_product.py b/tests/retworkx_backwards_compat/digraph/test_tensor_product.py deleted file mode 100644 index 8e38674c6d..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_tensor_product.py +++ /dev/null @@ -1,110 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestTensorProduct(unittest.TestCase): - def test_directed_null_tensor_null(self): - graph_1 = retworkx.PyDiGraph() - graph_2 = retworkx.PyDiGraph() - - graph_product, _ = retworkx.digraph_tensor_product(graph_1, graph_2) - self.assertEqual(graph_product.num_nodes(), 0) - self.assertEqual(graph_product.num_edges(), 0) - - def test_directed_path_2_tensor_path_2(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_2 = retworkx.generators.directed_path_graph(2) - - graph_product, node_map = retworkx.digraph_tensor_product(graph_1, graph_2) - expected_node_map = {(0, 0): 0, (0, 1): 1, (1, 0): 2, (1, 1): 3} - self.assertEqual(node_map, expected_node_map) - - expected_edges = [(0, 3)] - self.assertEqual(graph_product.num_nodes(), 4) - self.assertEqual(graph_product.num_edges(), 1) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_directed_path_2_tensor_path_3(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_2 = retworkx.generators.directed_path_graph(3) - - graph_product, node_map = retworkx.digraph_tensor_product(graph_1, graph_2) - expected_node_map = {(0, 1): 1, (1, 0): 3, (0, 0): 0, (1, 2): 5, (0, 2): 2, (1, 1): 4} - self.assertEqual(dict(node_map), expected_node_map) - - expected_edges = [(0, 4), (1, 5)] - self.assertEqual(graph_product.num_nodes(), 6) - self.assertEqual(graph_product.num_edges(), 2) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_directed_node_weights_tensor(self): - graph_1 = retworkx.PyDiGraph() - graph_1.add_node("a_1") - graph_2 = retworkx.PyDiGraph() - graph_2.add_node(0) - - graph_product, _ = retworkx.digraph_tensor_product(graph_1, graph_2) - self.assertEqual([("a_1", 0)], graph_product.nodes()) - - def test_directed_edge_weights_tensor(self): - graph_1 = retworkx.PyDiGraph() - graph_1.add_nodes_from([0, 1]) - graph_1.add_edge(0, 1, "w_1") - graph_2 = retworkx.PyDiGraph() - graph_2.add_nodes_from([0, 1]) - graph_2.add_edge(0, 1, "w_2") - - graph_product, _ = retworkx.digraph_tensor_product(graph_1, graph_2) - self.assertEqual([("w_1", "w_2")], graph_product.edges()) - - def test_multi_graph_1(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_1.add_edge(0, 1, None) - graph_2 = retworkx.generators.directed_path_graph(2) - - graph_product, _ = retworkx.digraph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 3)] - self.assertEqual(graph_product.num_edges(), 2) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_multi_graph_2(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_1.add_edge(0, 0, None) - graph_2 = retworkx.generators.directed_path_graph(2) - - graph_product, _ = retworkx.digraph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 1)] - self.assertEqual(graph_product.num_edges(), 2) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_multi_graph_3(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_2 = retworkx.generators.directed_path_graph(2) - graph_2.add_edge(0, 1, None) - - graph_product, _ = retworkx.digraph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 3)] - self.assertEqual(graph_product.num_edges(), 2) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_multi_graph_4(self): - graph_1 = retworkx.generators.directed_path_graph(2) - graph_2 = retworkx.generators.directed_path_graph(2) - graph_2.add_edge(0, 0, None) - - graph_product, _ = retworkx.digraph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 2)] - self.assertEqual(graph_product.num_edges(), 2) - self.assertEqual(graph_product.edge_list(), expected_edges) diff --git a/tests/retworkx_backwards_compat/digraph/test_to_undirected.py b/tests/retworkx_backwards_compat/digraph/test_to_undirected.py deleted file mode 100644 index 14b135dd8c..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_to_undirected.py +++ /dev/null @@ -1,66 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestToUndirected(unittest.TestCase): - def test_to_undirected_empty_graph(self): - digraph = retworkx.PyDiGraph() - graph = digraph.to_undirected() - self.assertEqual(0, len(graph)) - - def test_single_direction_graph(self): - digraph = retworkx.generators.directed_path_graph(5) - graph = digraph.to_undirected() - self.assertEqual(digraph.weighted_edge_list(), graph.weighted_edge_list()) - - def test_bidirectional_graph(self): - digraph = retworkx.generators.directed_path_graph(5) - for i in range(0, 4): - digraph.add_edge(i + 1, i, None) - graph = digraph.to_undirected() - self.assertEqual(digraph.weighted_edge_list(), graph.weighted_edge_list()) - - def test_bidirectional_not_multigraph(self): - digraph = retworkx.generators.directed_path_graph(5) - for i in range(0, 4): - digraph.add_edge(i + 1, i, None) - graph = digraph.to_undirected(multigraph=False) - self.assertEqual(graph.edge_list(), [(0, 1), (1, 2), (2, 3), (3, 4)]) - - def test_multiple_edges_combo_weight_not_multigraph(self): - digraph = retworkx.PyDiGraph() - digraph.add_nodes_from([0, 1]) - digraph.add_edges_from([(0, 1, "a"), (0, 1, "b")]) - graph = digraph.to_undirected(multigraph=False, weight_combo_fn=lambda x, y: x + y) - self.assertEqual(graph.weighted_edge_list(), [(0, 1, "ab")]) - - def test_shared_ref(self): - digraph = retworkx.PyDiGraph() - node_weight = {"a": 1} - node_a = digraph.add_node(node_weight) - edge_weight = {"a": 1} - digraph.add_child(node_a, "b", edge_weight) - graph = digraph.to_undirected() - self.assertEqual(digraph[node_a], {"a": 1}) - self.assertEqual(graph[node_a], {"a": 1}) - node_weight["b"] = 2 - self.assertEqual(digraph[node_a], {"a": 1, "b": 2}) - self.assertEqual(graph[node_a], {"a": 1, "b": 2}) - self.assertEqual(digraph.get_edge_data(0, 1), {"a": 1}) - self.assertEqual(graph.get_edge_data(0, 1), {"a": 1}) - edge_weight["b"] = 2 - self.assertEqual(digraph.get_edge_data(0, 1), {"a": 1, "b": 2}) - self.assertEqual(graph.get_edge_data(0, 1), {"a": 1, "b": 2}) diff --git a/tests/retworkx_backwards_compat/digraph/test_toposort.py b/tests/retworkx_backwards_compat/digraph/test_toposort.py deleted file mode 100644 index 08acd6352d..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_toposort.py +++ /dev/null @@ -1,84 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestTopologicalSorter(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyDiGraph() - self.graph.extend_from_edge_list( - [ - (0, 2), - (1, 2), - (2, 3), - (2, 4), - (3, 5), - ] - ) - - def test_topo_sort(self): - sorter = retworkx.TopologicalSorter(self.graph) - nodes = sorter.get_ready() - self.assertEqual(nodes, [0, 1]) - sorter.done(nodes) - nodes = sorter.get_ready() - self.assertEqual(nodes, [2]) - sorter.done(nodes) - nodes = sorter.get_ready() - self.assertEqual(nodes, [4, 3]) - sorter.done(nodes) - nodes = sorter.get_ready() - self.assertEqual(nodes, [5]) - sorter.done(nodes) - nodes = sorter.get_ready() - self.assertEqual(nodes, []) - - def test_topo_sort_do_not_emit_if_node_has_undone_preds(self): - sorter = retworkx.TopologicalSorter(self.graph) - nodes = sorter.get_ready() - self.assertEqual(nodes, [0, 1]) - sorter.done([0]) - nodes = sorter.get_ready() - self.assertEqual(nodes, []) - - def test_topo_sort_raises_if_node_not_ready(self): - sorter = retworkx.TopologicalSorter(self.graph) - with self.assertRaises(ValueError): - sorter.done([0]) - - def test_topo_sort_raises_if_node_already_done(self): - sorter = retworkx.TopologicalSorter(self.graph) - sorter.get_ready() - sorter.done([0]) - with self.assertRaises(ValueError): - sorter.done([0]) - - def test_topo_sort_raises_if_graph_has_cycle(self): - graph = retworkx.generators.directed_cycle_graph(5) - with self.assertRaises(retworkx.DAGHasCycle): - _ = retworkx.TopologicalSorter(graph) - - def test_topo_sort_progress_if_graph_has_cycle_and_cycle_check_disabled( - self, - ): - graph = retworkx.generators.directed_cycle_graph(5) - starting_node = graph.add_node("starting node") - graph.add_edge(starting_node, 0, "starting edge") - - sorter = retworkx.TopologicalSorter(graph, check_cycle=False) - nodes = sorter.get_ready() - self.assertEqual(nodes, [starting_node]) - sorter.done(nodes) - self.assertFalse(sorter.is_active()) diff --git a/tests/retworkx_backwards_compat/digraph/test_transitivity.py b/tests/retworkx_backwards_compat/digraph/test_transitivity.py deleted file mode 100644 index 5b95efe4c7..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_transitivity.py +++ /dev/null @@ -1,43 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestTransitivity(unittest.TestCase): - def test_transitivity_directed(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(5))) - graph.add_edges_from_no_data([(0, 1), (0, 2), (0, 3), (1, 2)]) - res = retworkx.transitivity(graph) - self.assertEqual(res, 3 / 10) - - def test_transitivity_triangle_directed(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(3))) - graph.add_edges_from_no_data([(0, 1), (0, 2), (1, 2)]) - res = retworkx.transitivity(graph) - self.assertEqual(res, 0.5) - - def test_transitivity_fulltriangle_directed(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(list(range(3))) - graph.add_edges_from_no_data([(0, 1), (1, 0), (0, 2), (2, 0), (1, 2), (2, 1)]) - res = retworkx.transitivity(graph) - self.assertEqual(res, 1.0) - - def test_transitivity_empty_directed(self): - graph = retworkx.PyDiGraph() - res = retworkx.transitivity(graph) - self.assertEqual(res, 0.0) diff --git a/tests/retworkx_backwards_compat/digraph/test_union.py b/tests/retworkx_backwards_compat/digraph/test_union.py deleted file mode 100644 index d1fcaf2e90..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_union.py +++ /dev/null @@ -1,105 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestUnion(unittest.TestCase): - def test_union_merge_all(self): - dag_a = retworkx.PyDiGraph() - dag_b = retworkx.PyDiGraph() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "e_1") - dag_a.add_child(node_a, "a_3", "e_2") - - node_b = dag_b.add_node("a_1") - dag_b.add_child(node_b, "a_2", "e_1") - dag_b.add_child(node_b, "a_3", "e_2") - - dag_c = retworkx.digraph_union(dag_a, dag_b, True, True) - - self.assertTrue(retworkx.is_isomorphic(dag_a, dag_c)) - - def test_union_basic_merge_nodes_only(self): - dag_a = retworkx.PyDiGraph() - dag_b = retworkx.PyDiGraph() - - node_a = dag_a.add_node("a_1") - child_a = dag_a.add_child(node_a, "a_2", "e_1") - dag_a.add_child(node_a, "a_3", "e_2") - - node_b = dag_b.add_node("a_1") - dag_b.add_child(node_b, "a_2", "e_1") - dag_b.add_child(node_b, "a_3", "e_2") - - dag_c = retworkx.digraph_union(dag_a, dag_b, True, False) - - self.assertTrue(len(dag_c.edge_list()) == 4) - self.assertTrue(len(dag_c.get_all_edge_data(node_a, child_a)) == 2) - self.assertTrue(len(dag_c.nodes()) == 3) - - def test_union_basic_merge_none(self): - dag_a = retworkx.PyDiGraph() - dag_b = retworkx.PyDiGraph() - - node_a = dag_a.add_node("a_1") - dag_a.add_child(node_a, "a_2", "e_1") - dag_a.add_child(node_a, "a_3", "r_2") - - node_b = dag_b.add_node("a_1") - dag_b.add_child(node_b, "a_2", "e_1") - dag_b.add_child(node_b, "a_3", "e_2") - - dag_c = retworkx.digraph_union(dag_a, dag_b, False, False) - - self.assertTrue(len(dag_c.nodes()) == 6) - self.assertTrue(len(dag_c.edge_list()) == 4) - - def test_union_mismatch_edge_weight(self): - first = retworkx.PyDiGraph() - nodes = first.add_nodes_from([0, 1]) - first.add_edges_from([(nodes[0], nodes[1], "a")]) - - second = retworkx.PyDiGraph() - nodes = second.add_nodes_from([0, 1]) - second.add_edges_from([(nodes[0], nodes[1], "b")]) - - final = retworkx.digraph_union(first, second, merge_nodes=True, merge_edges=True) - self.assertEqual(final.weighted_edge_list(), [(0, 1, "a"), (0, 1, "b")]) - - def test_union_node_hole(self): - first = retworkx.PyDiGraph() - nodes = first.add_nodes_from([0, 1]) - first.add_edges_from([(nodes[0], nodes[1], "a")]) - - second = retworkx.PyDiGraph() - dummy = second.add_node("dummy") - nodes = second.add_nodes_from([0, 1]) - second.add_edges_from([(nodes[0], nodes[1], "a")]) - second.remove_node(dummy) - - final = retworkx.digraph_union(first, second, merge_nodes=True, merge_edges=True) - self.assertEqual(final.weighted_edge_list(), [(0, 1, "a")]) - - def test_union_edge_between_merged_and_unmerged_nodes(self): - first = retworkx.PyDiGraph() - nodes = first.add_nodes_from([0, 1]) - first.add_edges_from([(nodes[0], nodes[1], "a")]) - - second = retworkx.PyDiGraph() - nodes = second.add_nodes_from([0, 2]) - second.add_edges_from([(nodes[0], nodes[1], "b")]) - - final = retworkx.digraph_union(first, second, merge_nodes=True, merge_edges=True) - self.assertEqual(final.weighted_edge_list(), [(0, 1, "a"), (0, 2, "b")]) diff --git a/tests/retworkx_backwards_compat/digraph/test_weakly_connected.py b/tests/retworkx_backwards_compat/digraph/test_weakly_connected.py deleted file mode 100644 index 93fdcbdde9..0000000000 --- a/tests/retworkx_backwards_compat/digraph/test_weakly_connected.py +++ /dev/null @@ -1,81 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestWeaklyConnected(unittest.TestCase): - def test_number_weakly_connected_all_strong(self): - G = retworkx.PyDAG() - node_a = G.add_node(1) - node_b = G.add_child(node_a, 2, {}) - G.add_child(node_b, 3, {}) - self.assertEqual(retworkx.number_weakly_connected_components(G), 1) - - def test_number_weakly_connected(self): - G = retworkx.PyDAG() - node_a = G.add_node(1) - G.add_child(node_a, 2, {}) - G.add_node(3) - self.assertEqual(retworkx.number_weakly_connected_components(G), 2) - - def test_number_weakly_connected_big(self): - G = retworkx.PyDAG() - for i in range(100000): - node = G.add_node(i) - G.add_child(node, str(i), {}) - self.assertEqual(retworkx.number_weakly_connected_components(G), 100000) - - def test_number_weakly_connected_node_holes(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from([0, 1, 2]) - graph.remove_node(1) - self.assertEqual(retworkx.number_weakly_connected_components(graph), 2) - - def test_weakly_connected_components(self): - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list( - [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4)] - ) - components = retworkx.weakly_connected_components(graph) - self.assertEqual([{0, 1, 2, 3}, {4, 5, 6, 7}], components) - - def test_is_weakly_connected_false(self): - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list( - [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4)] - ) - self.assertFalse(retworkx.is_weakly_connected(graph)) - - def test_is_weakly_connected_true(self): - graph = retworkx.PyDiGraph() - graph.extend_from_edge_list( - [ - (0, 1), - (1, 2), - (2, 3), - (3, 0), - (2, 4), - (4, 5), - (5, 6), - (6, 7), - (7, 4), - ] - ) - self.assertTrue(retworkx.is_weakly_connected(graph)) - - def test_is_weakly_connected_null_graph(self): - graph = retworkx.PyDiGraph() - with self.assertRaises(retworkx.NullGraph): - retworkx.is_weakly_connected(graph) diff --git a/tests/retworkx_backwards_compat/generators/__init__.py b/tests/retworkx_backwards_compat/generators/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/retworkx_backwards_compat/generators/test_barbell.py b/tests/retworkx_backwards_compat/generators/test_barbell.py deleted file mode 100644 index 596ca95adb..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_barbell.py +++ /dev/null @@ -1,57 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestBarbellGraph(unittest.TestCase): - def test_barbell_graph_count(self): - graph = retworkx.generators.barbell_graph(17, 3) - self.assertEqual(len(graph), 37) - self.assertEqual(len(graph.edges()), 276) - - def test_barbell_graph_edge(self): - graph = retworkx.generators.barbell_graph(4, 3) - edge_list = graph.edge_list() - expected_edge_list = set( - [ - (0, 1), - (0, 2), - (0, 3), - (1, 2), - (1, 3), - (2, 3), - (3, 4), - (4, 5), - (5, 6), - (6, 7), - (7, 8), - (7, 9), - (7, 10), - (8, 9), - (8, 10), - (9, 10), - ] - ) - self.assertEqual(set(edge_list), set(expected_edge_list)) - - def test_barbell_graph_no_path_num(self): - graph = retworkx.generators.barbell_graph(4) - mesh = retworkx.generators.mesh_graph(4) - mesh.compose(mesh.copy(), {3: (0, None)}) - self.assertEqual(set(graph.edge_list()), set(mesh.edge_list())) - - def test_barbell_graph_no_mesh_num(self): - with self.assertRaises(IndexError): - retworkx.generators.barbell_graph() diff --git a/tests/retworkx_backwards_compat/generators/test_binomial_tree.py b/tests/retworkx_backwards_compat/generators/test_binomial_tree.py deleted file mode 100644 index f055bbbc08..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_binomial_tree.py +++ /dev/null @@ -1,195 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestBinomialTreeGraph(unittest.TestCase): - def test_binomial_tree_graph(self): - expected_edges = { - 0: [], - 1: [(0, 1)], - 2: [(0, 1), (2, 3), (0, 2)], - 3: [(0, 1), (2, 3), (0, 2), (4, 5), (6, 7), (4, 6), (0, 4)], - 4: [ - (0, 1), - (2, 3), - (0, 2), - (4, 5), - (6, 7), - (4, 6), - (0, 4), - (8, 9), - (10, 11), - (8, 10), - (12, 13), - (14, 15), - (12, 14), - (8, 12), - (0, 8), - ], - } - for n in range(5): - with self.subTest(n=n): - graph = retworkx.generators.binomial_tree_graph(n) - self.assertEqual(len(graph), 2**n) - self.assertEqual(len(graph.edges()), 2**n - 1) - self.assertEqual(list(graph.edge_list()), expected_edges[n]) - - def test_binomial_tree_graph_weights(self): - graph = retworkx.generators.binomial_tree_graph(2, weights=list(range(4))) - expected_edges = [(0, 1), (2, 3), (0, 2)] - self.assertEqual(len(graph), 4) - self.assertEqual([x for x in range(4)], graph.nodes()) - self.assertEqual(len(graph.edges()), 3) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_binomial_tree_graph_weight_less_nodes(self): - graph = retworkx.generators.binomial_tree_graph(2, weights=list(range(2))) - self.assertEqual(len(graph), 4) - expected_weights = [x for x in range(2)] - expected_weights.extend([None, None]) - self.assertEqual(expected_weights, graph.nodes()) - self.assertEqual(len(graph.edges()), 3) - - def test_binomial_tree_graph_weights_greater_nodes(self): - with self.assertRaises(IndexError): - retworkx.generators.binomial_tree_graph(2, weights=list(range(7))) - - def test_binomial_tree_no_order(self): - with self.assertRaises(TypeError): - retworkx.generators.binomial_tree_graph(weights=list(range(4))) - - def test_directed_binomial_tree_graph(self): - expected_edges = { - 0: [], - 1: [(0, 1)], - 2: [(0, 1), (2, 3), (0, 2)], - 3: [(0, 1), (2, 3), (0, 2), (4, 5), (6, 7), (4, 6), (0, 4)], - 4: [ - (0, 1), - (2, 3), - (0, 2), - (4, 5), - (6, 7), - (4, 6), - (0, 4), - (8, 9), - (10, 11), - (8, 10), - (12, 13), - (14, 15), - (12, 14), - (8, 12), - (0, 8), - ], - } - - for n in range(5): - with self.subTest(n=n): - graph = retworkx.generators.directed_binomial_tree_graph(n) - self.assertEqual(len(graph), 2**n) - self.assertEqual(len(graph.edges()), 2**n - 1) - self.assertEqual(list(graph.edge_list()), expected_edges[n]) - - def test_directed_binomial_tree_graph_weights(self): - graph = retworkx.generators.directed_binomial_tree_graph(2, weights=list(range(4))) - self.assertEqual(len(graph), 4) - self.assertEqual([x for x in range(4)], graph.nodes()) - self.assertEqual(len(graph.edges()), 3) - - def test_directed_binomial_tree_graph_weight_less_nodes(self): - graph = retworkx.generators.directed_binomial_tree_graph(2, weights=list(range(2))) - self.assertEqual(len(graph), 4) - expected_weights = [x for x in range(2)] - expected_weights.extend([None, None]) - self.assertEqual(expected_weights, graph.nodes()) - self.assertEqual(len(graph.edges()), 3) - - def test_directed_binomial_tree_graph_weights_greater_nodes(self): - with self.assertRaises(IndexError): - retworkx.generators.directed_binomial_tree_graph(2, weights=list(range(7))) - - def test_directed_binomial_tree_no_order(self): - with self.assertRaises(TypeError): - retworkx.generators.directed_binomial_tree_graph(weights=list(range(4))) - - def test_directed_binomial_tree_graph_bidirectional(self): - expected_edges = { - 0: [], - 1: [(0, 1), (1, 0)], - 2: [(0, 1), (1, 0), (2, 3), (3, 2), (0, 2), (2, 0)], - 3: [ - (0, 1), - (1, 0), - (2, 3), - (3, 2), - (0, 2), - (2, 0), - (4, 5), - (5, 4), - (6, 7), - (7, 6), - (4, 6), - (6, 4), - (0, 4), - (4, 0), - ], - 4: [ - (0, 1), - (1, 0), - (2, 3), - (3, 2), - (0, 2), - (2, 0), - (4, 5), - (5, 4), - (6, 7), - (7, 6), - (4, 6), - (6, 4), - (0, 4), - (4, 0), - (8, 9), - (9, 8), - (10, 11), - (11, 10), - (8, 10), - (10, 8), - (12, 13), - (13, 12), - (14, 15), - (15, 14), - (12, 14), - (14, 12), - (8, 12), - (12, 8), - (0, 8), - (8, 0), - ], - } - for n in range(5): - with self.subTest(n=n): - graph = retworkx.generators.directed_binomial_tree_graph(n, bidirectional=True) - self.assertEqual(len(graph), 2**n) - self.assertEqual(len(graph.edges()), 2 * (2**n - 1)) - self.assertEqual(list(graph.edge_list()), expected_edges[n]) - - def test_overflow_binomial_tree(self): - with self.assertRaises(OverflowError): - retworkx.generators.binomial_tree_graph(75) - - def test_overflow_directed_binomial_tree(self): - with self.assertRaises(OverflowError): - retworkx.generators.directed_binomial_tree_graph(75) diff --git a/tests/retworkx_backwards_compat/generators/test_cycle.py b/tests/retworkx_backwards_compat/generators/test_cycle.py deleted file mode 100644 index 72199776e7..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_cycle.py +++ /dev/null @@ -1,71 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCycleGraph(unittest.TestCase): - def test_directed_cycle_graph(self): - graph = retworkx.generators.directed_cycle_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 20) - for i in range(19): - self.assertEqual(graph.out_edges(i), [(i, i + 1, None)]) - self.assertEqual(graph.out_edges(19), [(19, 0, None)]) - - def test_directed_cycle_graph_weights(self): - graph = retworkx.generators.directed_cycle_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 20) - for i in range(19): - self.assertEqual(graph.out_edges(i), [(i, i + 1, None)]) - self.assertEqual(graph.out_edges(19), [(19, 0, None)]) - - def test_directed_cycle_graph_bidirectional(self): - graph = retworkx.generators.directed_cycle_graph(20, bidirectional=True) - self.assertEqual(graph.out_edges(0), [(0, 19, None), (0, 1, None)]) - self.assertEqual(graph.in_edges(0), [(19, 0, None), (1, 0, None)]) - for i in range(1, 19): - self.assertEqual(graph.out_edges(i), [(i, i + 1, None), (i, i - 1, None)]) - self.assertEqual(graph.in_edges(i), [(i + 1, i, None), (i - 1, i, None)]) - self.assertEqual(graph.out_edges(19), [(19, 0, None), (19, 18, None)]) - self.assertEqual(graph.in_edges(19), [(0, 19, None), (18, 19, None)]) - - def test_cycle_directed_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.directed_cycle_graph() - - def test_cycle_graph(self): - graph = retworkx.generators.cycle_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 20) - - def test_cycle_graph_weights(self): - graph = retworkx.generators.cycle_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 20) - - def test_cycle_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.cycle_graph() - - def test_zero_length_cycle_graph(self): - graph = retworkx.generators.cycle_graph(0) - self.assertEqual(0, len(graph)) - - def test_zero_length_directed_cycle_graph(self): - graph = retworkx.generators.directed_cycle_graph(0) - self.assertEqual(0, len(graph)) diff --git a/tests/retworkx_backwards_compat/generators/test_full_rary_tree.py b/tests/retworkx_backwards_compat/generators/test_full_rary_tree.py deleted file mode 100644 index 93195a99a8..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_full_rary_tree.py +++ /dev/null @@ -1,89 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestFullRaryTreeTreeGraph(unittest.TestCase): - def test_full_rary_tree_graph(self): - b_factors = { - 0: 0, - 1: 2, - 2: 2, - 3: 5, - } - num_nodes = { - 0: 0, - 1: 4, - 2: 10, - 3: 15, - } - expected_edges = { - 0: [], - 1: [(0, 1), (0, 2), (1, 3)], - 2: [ - (0, 1), - (0, 2), - (1, 3), - (1, 4), - (2, 5), - (2, 6), - (3, 7), - (3, 8), - (4, 9), - ], - 3: [ - (0, 1), - (0, 2), - (0, 3), - (0, 4), - (0, 5), - (1, 6), - (1, 7), - (1, 8), - (1, 9), - (1, 10), - (2, 11), - (2, 12), - (2, 13), - (2, 14), - ], - } - for n in range(4): - with self.subTest(n=n): - graph = retworkx.generators.full_rary_tree(b_factors[n], num_nodes[n]) - self.assertEqual(list(graph.edge_list()), expected_edges[n]) - - def test_full_rary_tree_graph_weights(self): - graph = retworkx.generators.full_rary_tree(2, 4, weights=list(range(4))) - expected_edges = [(0, 1), (0, 2), (1, 3)] - self.assertEqual(len(graph), 4) - self.assertEqual([x for x in range(4)], graph.nodes()) - self.assertEqual(len(graph.edges()), 3) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_full_rary_tree_graph_weight_less_nodes(self): - graph = retworkx.generators.full_rary_tree(2, 6, weights=list(range(4))) - self.assertEqual(len(graph), 6) - expected_weights = [x for x in range(4)] - expected_weights.extend([None, None]) - self.assertEqual(expected_weights, graph.nodes()) - self.assertEqual(len(graph.edges()), 5) - - def test_full_rary_tree_graph_weights_greater_nodes(self): - with self.assertRaises(IndexError): - retworkx.generators.full_rary_tree(2, 4, weights=list(range(7))) - - def test_full_rary_tree_no_order(self): - with self.assertRaises(TypeError): - retworkx.generators.full_rary_tree(weights=list(range(4))) diff --git a/tests/retworkx_backwards_compat/generators/test_grid.py b/tests/retworkx_backwards_compat/generators/test_grid.py deleted file mode 100644 index a50c4653dc..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_grid.py +++ /dev/null @@ -1,131 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestGridGraph(unittest.TestCase): - def test_directed_grid_graph_dimensions(self): - graph = retworkx.generators.directed_grid_graph(4, 5) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 31) - self.assertEqual(graph.out_edges(0), [(0, 1, None), (0, 5, None)]) - self.assertEqual(graph.out_edges(7), [(7, 8, None), (7, 12, None)]) - self.assertEqual(graph.out_edges(9), [(9, 14, None)]) - self.assertEqual(graph.out_edges(17), [(17, 18, None)]) - self.assertEqual(graph.out_edges(19), []) - self.assertEqual(graph.in_edges(0), []) - self.assertEqual(graph.in_edges(2), [(1, 2, None)]) - self.assertEqual(graph.in_edges(5), [(0, 5, None)]) - self.assertEqual(graph.in_edges(7), [(6, 7, None), (2, 7, None)]) - self.assertEqual(graph.in_edges(19), [(18, 19, None), (14, 19, None)]) - - def test_directed_grid_graph_weights(self): - graph = retworkx.generators.directed_grid_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 19) - for i in range(19): - self.assertEqual(graph.out_edges(i), [(i, i + 1, None)]) - self.assertEqual(graph.out_edges(19), []) - for i in range(1, 20): - self.assertEqual(graph.in_edges(i), [(i - 1, i, None)]) - self.assertEqual(graph.in_edges(0), []) - - def test_directed_grid_graph_dimensions_weights(self): - graph = retworkx.generators.directed_grid_graph(4, 5, weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 31) - self.assertEqual(graph.out_edges(0), [(0, 1, None), (0, 5, None)]) - self.assertEqual(graph.out_edges(7), [(7, 8, None), (7, 12, None)]) - self.assertEqual(graph.out_edges(9), [(9, 14, None)]) - self.assertEqual(graph.out_edges(17), [(17, 18, None)]) - self.assertEqual(graph.out_edges(19), []) - self.assertEqual(graph.in_edges(0), []) - self.assertEqual(graph.in_edges(2), [(1, 2, None)]) - self.assertEqual(graph.in_edges(5), [(0, 5, None)]) - self.assertEqual(graph.in_edges(7), [(6, 7, None), (2, 7, None)]) - self.assertEqual(graph.in_edges(19), [(18, 19, None), (14, 19, None)]) - - def test_directed_grid_graph_more_dimensions_weights(self): - graph = retworkx.generators.directed_grid_graph(4, 5, weights=list(range(16))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(16)] + [None] * 4, graph.nodes()) - self.assertEqual(len(graph.edges()), 31) - self.assertEqual(graph.out_edges(0), [(0, 1, None), (0, 5, None)]) - self.assertEqual(graph.out_edges(7), [(7, 8, None), (7, 12, None)]) - self.assertEqual(graph.out_edges(9), [(9, 14, None)]) - self.assertEqual(graph.out_edges(17), [(17, 18, None)]) - self.assertEqual(graph.out_edges(19), []) - self.assertEqual(graph.in_edges(0), []) - self.assertEqual(graph.in_edges(2), [(1, 2, None)]) - self.assertEqual(graph.in_edges(5), [(0, 5, None)]) - self.assertEqual(graph.in_edges(7), [(6, 7, None), (2, 7, None)]) - self.assertEqual(graph.in_edges(19), [(18, 19, None), (14, 19, None)]) - - def test_directed_grid_graph_less_dimensions_weights(self): - graph = retworkx.generators.directed_grid_graph(4, 5, weights=list(range(24))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 31) - self.assertEqual(graph.out_edges(0), [(0, 1, None), (0, 5, None)]) - self.assertEqual(graph.out_edges(7), [(7, 8, None), (7, 12, None)]) - self.assertEqual(graph.out_edges(9), [(9, 14, None)]) - self.assertEqual(graph.out_edges(17), [(17, 18, None)]) - self.assertEqual(graph.out_edges(19), []) - self.assertEqual(graph.in_edges(0), []) - self.assertEqual(graph.in_edges(2), [(1, 2, None)]) - self.assertEqual(graph.in_edges(5), [(0, 5, None)]) - self.assertEqual(graph.in_edges(7), [(6, 7, None), (2, 7, None)]) - self.assertEqual(graph.in_edges(19), [(18, 19, None), (14, 19, None)]) - - def test_grid_directed_no_weights_or_dim(self): - with self.assertRaises(IndexError): - retworkx.generators.directed_grid_graph() - retworkx.generators.directed_grid_graph(rows=5, weights=[1] * 5) - retworkx.generators.directed_grid_graph(cols=5, weights=[1] * 5) - - def test_grid_graph_dimensions(self): - graph = retworkx.generators.grid_graph(4, 5) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 31) - - def test_grid_graph_weights(self): - graph = retworkx.generators.grid_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 19) - - def test_grid_graph_dimensions_weights(self): - graph = retworkx.generators.grid_graph(4, 5, weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 31) - - graph = retworkx.generators.grid_graph(4, 5, weights=list(range(16))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(16)] + [None] * 4, graph.nodes()) - self.assertEqual(len(graph.edges()), 31) - - graph = retworkx.generators.grid_graph(4, 5, weights=list(range(24))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 31) - - def test_grid_no_weights_or_dim(self): - with self.assertRaises(IndexError): - retworkx.generators.grid_graph() - retworkx.generators.grid_graph(rows=5, weights=[1] * 5) - retworkx.generators.grid_graph(cols=5, weights=[1] * 5) diff --git a/tests/retworkx_backwards_compat/generators/test_heavy_hex.py b/tests/retworkx_backwards_compat/generators/test_heavy_hex.py deleted file mode 100644 index 09e5093fcc..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_heavy_hex.py +++ /dev/null @@ -1,424 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestHeavyHexGraph(unittest.TestCase): - def test_directed_heavy_hex_graph_1(self): - d = 1 - graph = retworkx.generators.directed_heavy_hex_graph(d) - self.assertEqual(1, len(graph)) - self.assertEqual(graph.edge_list(), []) - - def test_heavy_hex_graph_1(self): - d = 1 - graph = retworkx.generators.heavy_hex_graph(d) - self.assertEqual(1, len(graph)) - self.assertEqual(graph.edge_list(), []) - - def test_directed_heavy_hex_graph_3(self): - d = 3 - graph = retworkx.generators.directed_heavy_hex_graph(d) - self.assertEqual(len(graph), (5 * d * d - 2 * d - 1) / 2) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + (d + 1) * (d - 1)) - expected_edges = [ - (0, 13), - (1, 13), - (1, 14), - (2, 14), - (3, 15), - (4, 15), - (4, 16), - (5, 16), - (6, 17), - (7, 17), - (7, 18), - (8, 18), - (0, 9), - (3, 9), - (5, 12), - (8, 12), - (10, 14), - (10, 16), - (11, 15), - (11, 17), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_heavy_hex_graph_3_bidirectional(self): - d = 3 - graph = retworkx.generators.directed_heavy_hex_graph(d, bidirectional=True) - self.assertEqual(len(graph), (5 * d * d - 2 * d - 1) / 2) - self.assertEqual(len(graph.edges()), 2 * (2 * d * (d - 1) + (d + 1) * (d - 1))) - expected_edges = [ - (0, 13), - (1, 13), - (13, 0), - (13, 1), - (1, 14), - (2, 14), - (14, 1), - (14, 2), - (3, 15), - (4, 15), - (15, 3), - (15, 4), - (4, 16), - (5, 16), - (16, 4), - (16, 5), - (6, 17), - (7, 17), - (17, 6), - (17, 7), - (7, 18), - (8, 18), - (18, 7), - (18, 8), - (0, 9), - (3, 9), - (9, 0), - (9, 3), - (5, 12), - (8, 12), - (12, 5), - (12, 8), - (10, 14), - (10, 16), - (14, 10), - (16, 10), - (11, 15), - (11, 17), - (15, 11), - (17, 11), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_heavy_hex_graph_3(self): - d = 3 - graph = retworkx.generators.heavy_hex_graph(d) - self.assertEqual(len(graph), (5 * d * d - 2 * d - 1) / 2) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + (d + 1) * (d - 1)) - expected_edges = [ - (0, 13), - (1, 13), - (1, 14), - (2, 14), - (3, 15), - (4, 15), - (4, 16), - (5, 16), - (6, 17), - (7, 17), - (7, 18), - (8, 18), - (0, 9), - (3, 9), - (5, 12), - (8, 12), - (10, 14), - (10, 16), - (11, 15), - (11, 17), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_heavy_hex_graph_5(self): - d = 5 - graph = retworkx.generators.directed_heavy_hex_graph(d) - self.assertEqual(len(graph), (5 * d * d - 2 * d - 1) / 2) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + (d + 1) * (d - 1)) - expected_edges = [ - (0, 37), - (1, 37), - (1, 38), - (2, 38), - (2, 39), - (3, 39), - (3, 40), - (4, 40), - (5, 41), - (6, 41), - (6, 42), - (7, 42), - (7, 43), - (8, 43), - (8, 44), - (9, 44), - (10, 45), - (11, 45), - (11, 46), - (12, 46), - (12, 47), - (13, 47), - (13, 48), - (14, 48), - (15, 49), - (16, 49), - (16, 50), - (17, 50), - (17, 51), - (18, 51), - (18, 52), - (19, 52), - (20, 53), - (21, 53), - (21, 54), - (22, 54), - (22, 55), - (23, 55), - (23, 56), - (24, 56), - (0, 25), - (5, 25), - (9, 30), - (14, 30), - (10, 31), - (15, 31), - (19, 36), - (24, 36), - (26, 38), - (26, 42), - (27, 40), - (27, 44), - (28, 41), - (28, 45), - (29, 43), - (29, 47), - (32, 46), - (32, 50), - (33, 48), - (33, 52), - (34, 49), - (34, 53), - (35, 51), - (35, 55), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_heavy_hex_graph_5_bidirectional(self): - d = 5 - graph = retworkx.generators.directed_heavy_hex_graph(d, bidirectional=True) - self.assertEqual(len(graph), (5 * d * d - 2 * d - 1) / 2) - self.assertEqual(len(graph.edges()), 2 * (2 * d * (d - 1) + (d + 1) * (d - 1))) - expected_edges = [ - (0, 37), - (1, 37), - (37, 0), - (37, 1), - (1, 38), - (2, 38), - (38, 1), - (38, 2), - (2, 39), - (3, 39), - (39, 2), - (39, 3), - (3, 40), - (4, 40), - (40, 3), - (40, 4), - (5, 41), - (6, 41), - (41, 5), - (41, 6), - (6, 42), - (7, 42), - (42, 6), - (42, 7), - (7, 43), - (8, 43), - (43, 7), - (43, 8), - (8, 44), - (9, 44), - (44, 8), - (44, 9), - (10, 45), - (11, 45), - (45, 10), - (45, 11), - (11, 46), - (12, 46), - (46, 11), - (46, 12), - (12, 47), - (13, 47), - (47, 12), - (47, 13), - (13, 48), - (14, 48), - (48, 13), - (48, 14), - (15, 49), - (16, 49), - (49, 15), - (49, 16), - (16, 50), - (17, 50), - (50, 16), - (50, 17), - (17, 51), - (18, 51), - (51, 17), - (51, 18), - (18, 52), - (19, 52), - (52, 18), - (52, 19), - (20, 53), - (21, 53), - (53, 20), - (53, 21), - (21, 54), - (22, 54), - (54, 21), - (54, 22), - (22, 55), - (23, 55), - (55, 22), - (55, 23), - (23, 56), - (24, 56), - (56, 23), - (56, 24), - (0, 25), - (5, 25), - (25, 0), - (25, 5), - (9, 30), - (14, 30), - (30, 9), - (30, 14), - (10, 31), - (15, 31), - (31, 10), - (31, 15), - (19, 36), - (24, 36), - (36, 19), - (36, 24), - (26, 38), - (26, 42), - (38, 26), - (42, 26), - (27, 40), - (27, 44), - (40, 27), - (44, 27), - (28, 41), - (28, 45), - (41, 28), - (45, 28), - (29, 43), - (29, 47), - (43, 29), - (47, 29), - (32, 46), - (32, 50), - (46, 32), - (50, 32), - (33, 48), - (33, 52), - (48, 33), - (52, 33), - (34, 49), - (34, 53), - (49, 34), - (53, 34), - (35, 51), - (35, 55), - (51, 35), - (55, 35), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_heavy_hex_graph_5(self): - d = 5 - graph = retworkx.generators.heavy_hex_graph(d) - self.assertEqual(len(graph), (5 * d * d - 2 * d - 1) / 2) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + (d + 1) * (d - 1)) - expected_edges = [ - (0, 37), - (1, 37), - (1, 38), - (2, 38), - (2, 39), - (3, 39), - (3, 40), - (4, 40), - (5, 41), - (6, 41), - (6, 42), - (7, 42), - (7, 43), - (8, 43), - (8, 44), - (9, 44), - (10, 45), - (11, 45), - (11, 46), - (12, 46), - (12, 47), - (13, 47), - (13, 48), - (14, 48), - (15, 49), - (16, 49), - (16, 50), - (17, 50), - (17, 51), - (18, 51), - (18, 52), - (19, 52), - (20, 53), - (21, 53), - (21, 54), - (22, 54), - (22, 55), - (23, 55), - (23, 56), - (24, 56), - (0, 25), - (5, 25), - (9, 30), - (14, 30), - (10, 31), - (15, 31), - (19, 36), - (24, 36), - (26, 38), - (26, 42), - (27, 40), - (27, 44), - (28, 41), - (28, 45), - (29, 43), - (29, 47), - (32, 46), - (32, 50), - (33, 48), - (33, 52), - (34, 49), - (34, 53), - (35, 51), - (35, 55), - ] - - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_heavy_hex_graph_even_d(self): - with self.assertRaises(IndexError): - retworkx.generators.heavy_hex_graph(2) diff --git a/tests/retworkx_backwards_compat/generators/test_heavy_square.py b/tests/retworkx_backwards_compat/generators/test_heavy_square.py deleted file mode 100644 index c47e7d9e76..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_heavy_square.py +++ /dev/null @@ -1,503 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestHeavyHexGraph(unittest.TestCase): - def test_directed_heavy_hex_graph_1(self): - d = 1 - graph = retworkx.generators.directed_heavy_square_graph(d) - self.assertEqual(1, len(graph)) - self.assertEqual(graph.edge_list(), []) - - def test_heavy_hex_graph_1(self): - d = 1 - graph = retworkx.generators.heavy_square_graph(d) - self.assertEqual(1, len(graph)) - self.assertEqual(graph.edge_list(), []) - - def test_directed_heavy_square_graph_5(self): - d = 5 - graph = retworkx.generators.directed_heavy_square_graph(d) - self.assertEqual(len(graph), 3 * d * d - 2 * d) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + 2 * d * (d - 1)) - expected_edges = [ - (0, 45), - (45, 1), - (1, 46), - (46, 2), - (2, 47), - (47, 3), - (3, 48), - (48, 4), - (5, 49), - (49, 6), - (6, 50), - (50, 7), - (7, 51), - (51, 8), - (8, 52), - (52, 9), - (10, 53), - (53, 11), - (11, 54), - (54, 12), - (12, 55), - (55, 13), - (13, 56), - (56, 14), - (15, 57), - (57, 16), - (16, 58), - (58, 17), - (17, 59), - (59, 18), - (18, 60), - (60, 19), - (20, 61), - (61, 21), - (21, 62), - (62, 22), - (22, 63), - (63, 23), - (23, 64), - (64, 24), - (4, 29), - (9, 29), - (5, 30), - (10, 30), - (14, 39), - (19, 39), - (15, 40), - (20, 40), - (25, 45), - (25, 49), - (26, 46), - (26, 50), - (27, 47), - (27, 51), - (28, 48), - (28, 52), - (31, 49), - (31, 53), - (32, 50), - (32, 54), - (33, 51), - (33, 55), - (34, 52), - (34, 56), - (35, 53), - (35, 57), - (36, 54), - (36, 58), - (37, 55), - (37, 59), - (38, 56), - (38, 60), - (41, 57), - (41, 61), - (42, 58), - (42, 62), - (43, 59), - (43, 63), - (44, 60), - (44, 64), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_heavy_square_graph_5_bidirectional(self): - d = 5 - graph = retworkx.generators.directed_heavy_square_graph(d, bidirectional=True) - self.assertEqual(len(graph), 3 * d * d - 2 * d) - self.assertEqual(len(graph.edges()), 2 * (2 * d * (d - 1) + 2 * d * (d - 1))) - expected_edges = [ - (0, 45), - (45, 1), - (45, 0), - (1, 45), - (1, 46), - (46, 2), - (46, 1), - (2, 46), - (2, 47), - (47, 3), - (47, 2), - (3, 47), - (3, 48), - (48, 4), - (48, 3), - (4, 48), - (5, 49), - (49, 6), - (49, 5), - (6, 49), - (6, 50), - (50, 7), - (50, 6), - (7, 50), - (7, 51), - (51, 8), - (51, 7), - (8, 51), - (8, 52), - (52, 9), - (52, 8), - (9, 52), - (10, 53), - (53, 11), - (53, 10), - (11, 53), - (11, 54), - (54, 12), - (54, 11), - (12, 54), - (12, 55), - (55, 13), - (55, 12), - (13, 55), - (13, 56), - (56, 14), - (56, 13), - (14, 56), - (15, 57), - (57, 16), - (57, 15), - (16, 57), - (16, 58), - (58, 17), - (58, 16), - (17, 58), - (17, 59), - (59, 18), - (59, 17), - (18, 59), - (18, 60), - (60, 19), - (60, 18), - (19, 60), - (20, 61), - (61, 21), - (61, 20), - (21, 61), - (21, 62), - (62, 22), - (62, 21), - (22, 62), - (22, 63), - (63, 23), - (63, 22), - (23, 63), - (23, 64), - (64, 24), - (64, 23), - (24, 64), - (4, 29), - (9, 29), - (29, 4), - (29, 9), - (5, 30), - (10, 30), - (30, 5), - (30, 10), - (14, 39), - (19, 39), - (39, 14), - (39, 19), - (15, 40), - (20, 40), - (40, 15), - (40, 20), - (25, 45), - (25, 49), - (45, 25), - (49, 25), - (26, 46), - (26, 50), - (46, 26), - (50, 26), - (27, 47), - (27, 51), - (47, 27), - (51, 27), - (28, 48), - (28, 52), - (48, 28), - (52, 28), - (31, 49), - (31, 53), - (49, 31), - (53, 31), - (32, 50), - (32, 54), - (50, 32), - (54, 32), - (33, 51), - (33, 55), - (51, 33), - (55, 33), - (34, 52), - (34, 56), - (52, 34), - (56, 34), - (35, 53), - (35, 57), - (53, 35), - (57, 35), - (36, 54), - (36, 58), - (54, 36), - (58, 36), - (37, 55), - (37, 59), - (55, 37), - (59, 37), - (38, 56), - (38, 60), - (56, 38), - (60, 38), - (41, 57), - (41, 61), - (57, 41), - (61, 41), - (42, 58), - (42, 62), - (58, 42), - (62, 42), - (43, 59), - (43, 63), - (59, 43), - (63, 43), - (44, 60), - (44, 64), - (60, 44), - (64, 44), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_heavy_square_graph_5(self): - d = 5 - graph = retworkx.generators.heavy_square_graph(d) - self.assertEqual(len(graph), 3 * d * d - 2 * d) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + 2 * d * (d - 1)) - expected_edges = [ - (0, 45), - (45, 1), - (1, 46), - (46, 2), - (2, 47), - (47, 3), - (3, 48), - (48, 4), - (5, 49), - (49, 6), - (6, 50), - (50, 7), - (7, 51), - (51, 8), - (8, 52), - (52, 9), - (10, 53), - (53, 11), - (11, 54), - (54, 12), - (12, 55), - (55, 13), - (13, 56), - (56, 14), - (15, 57), - (57, 16), - (16, 58), - (58, 17), - (17, 59), - (59, 18), - (18, 60), - (60, 19), - (20, 61), - (61, 21), - (21, 62), - (62, 22), - (22, 63), - (63, 23), - (23, 64), - (64, 24), - (4, 29), - (9, 29), - (5, 30), - (10, 30), - (14, 39), - (19, 39), - (15, 40), - (20, 40), - (25, 45), - (25, 49), - (26, 46), - (26, 50), - (27, 47), - (27, 51), - (28, 48), - (28, 52), - (31, 49), - (31, 53), - (32, 50), - (32, 54), - (33, 51), - (33, 55), - (34, 52), - (34, 56), - (35, 53), - (35, 57), - (36, 54), - (36, 58), - (37, 55), - (37, 59), - (38, 56), - (38, 60), - (41, 57), - (41, 61), - (42, 58), - (42, 62), - (43, 59), - (43, 63), - (44, 60), - (44, 64), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_heavy_square_graph_3(self): - d = 3 - graph = retworkx.generators.directed_heavy_square_graph(d) - self.assertEqual(len(graph), 3 * d * d - 2 * d) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + 2 * d * (d - 1)) - expected_edges = [ - (0, 15), - (15, 1), - (1, 16), - (16, 2), - (3, 17), - (17, 4), - (4, 18), - (18, 5), - (6, 19), - (19, 7), - (7, 20), - (20, 8), - (2, 11), - (5, 11), - (3, 12), - (6, 12), - (9, 15), - (9, 17), - (10, 16), - (10, 18), - (13, 17), - (13, 19), - (14, 18), - (14, 20), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_heavy_square_graph_3_bidirectional(self): - d = 3 - graph = retworkx.generators.directed_heavy_square_graph(d, bidirectional=True) - self.assertEqual(len(graph), 3 * d * d - 2 * d) - self.assertEqual(len(graph.edges()), 2 * (2 * d * (d - 1) + 2 * d * (d - 1))) - expected_edges = [ - (0, 15), - (15, 1), - (15, 0), - (1, 15), - (1, 16), - (16, 2), - (16, 1), - (2, 16), - (3, 17), - (17, 4), - (17, 3), - (4, 17), - (4, 18), - (18, 5), - (18, 4), - (5, 18), - (6, 19), - (19, 7), - (19, 6), - (7, 19), - (7, 20), - (20, 8), - (20, 7), - (8, 20), - (2, 11), - (5, 11), - (11, 2), - (11, 5), - (3, 12), - (6, 12), - (12, 3), - (12, 6), - (9, 15), - (9, 17), - (15, 9), - (17, 9), - (10, 16), - (10, 18), - (16, 10), - (18, 10), - (13, 17), - (13, 19), - (17, 13), - (19, 13), - (14, 18), - (14, 20), - (18, 14), - (20, 14), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_heavy_square_graph_3(self): - d = 3 - graph = retworkx.generators.heavy_square_graph(d) - self.assertEqual(len(graph), 3 * d * d - 2 * d) - self.assertEqual(len(graph.edges()), 2 * d * (d - 1) + 2 * d * (d - 1)) - expected_edges = [ - (0, 15), - (15, 1), - (1, 16), - (16, 2), - (3, 17), - (17, 4), - (4, 18), - (18, 5), - (6, 19), - (19, 7), - (7, 20), - (20, 8), - (2, 11), - (5, 11), - (3, 12), - (6, 12), - (9, 15), - (9, 17), - (10, 16), - (10, 18), - (13, 17), - (13, 19), - (14, 18), - (14, 20), - ] - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_heavy_square_graph_no_d(self): - with self.assertRaises(TypeError): - retworkx.generators.heavy_square_graph() diff --git a/tests/retworkx_backwards_compat/generators/test_hexagonal.py b/tests/retworkx_backwards_compat/generators/test_hexagonal.py deleted file mode 100644 index 88fa25ca32..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_hexagonal.py +++ /dev/null @@ -1,417 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestHexagonalLatticeGraph(unittest.TestCase): - def test_directed_hexagonal_graph_2_2(self): - graph = retworkx.generators.directed_hexagonal_lattice_graph(2, 2) - expected_edges = [ - (0, 1), - (1, 2), - (2, 3), - (3, 4), - (5, 6), - (6, 7), - (7, 8), - (8, 9), - (9, 10), - (11, 12), - (12, 13), - (13, 14), - (14, 15), - (0, 5), - (2, 7), - (4, 9), - (6, 11), - (8, 13), - (10, 15), - ] - self.assertEqual(len(graph), 16) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_hexagonal_graph_3_2(self): - graph = retworkx.generators.directed_hexagonal_lattice_graph(3, 2) - expected_edges = [ - (0, 1), - (1, 2), - (2, 3), - (3, 4), - (4, 5), - (5, 6), - (7, 8), - (8, 9), - (9, 10), - (10, 11), - (11, 12), - (12, 13), - (13, 14), - (15, 16), - (16, 17), - (17, 18), - (18, 19), - (19, 20), - (20, 21), - (0, 7), - (2, 9), - (4, 11), - (6, 13), - (8, 15), - (10, 17), - (12, 19), - (14, 21), - ] - self.assertEqual(len(graph), 22) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_hexagonal_graph_2_4(self): - graph = retworkx.generators.directed_hexagonal_lattice_graph(2, 4) - expected_edges = [ - (0, 1), - (1, 2), - (2, 3), - (3, 4), - (5, 6), - (6, 7), - (7, 8), - (8, 9), - (9, 10), - (11, 12), - (12, 13), - (13, 14), - (14, 15), - (15, 16), - (17, 18), - (18, 19), - (19, 20), - (20, 21), - (21, 22), - (23, 24), - (24, 25), - (25, 26), - (26, 27), - (0, 5), - (2, 7), - (4, 9), - (6, 12), - (8, 14), - (10, 16), - (11, 17), - (13, 19), - (15, 21), - (18, 23), - (20, 25), - (22, 27), - ] - self.assertEqual(len(graph), 28) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_hexagonal_graph_2_2_bidirectional(self): - graph = retworkx.generators.directed_hexagonal_lattice_graph(2, 2, bidirectional=True) - expected_edges = [ - (0, 1), - (1, 0), - (1, 2), - (2, 1), - (2, 3), - (3, 2), - (3, 4), - (4, 3), - (5, 6), - (6, 5), - (6, 7), - (7, 6), - (7, 8), - (8, 7), - (8, 9), - (9, 8), - (9, 10), - (10, 9), - (11, 12), - (12, 11), - (12, 13), - (13, 12), - (13, 14), - (14, 13), - (14, 15), - (15, 14), - (0, 5), - (5, 0), - (2, 7), - (7, 2), - (4, 9), - (9, 4), - (6, 11), - (11, 6), - (8, 13), - (13, 8), - (10, 15), - (15, 10), - ] - self.assertEqual(len(graph), 16) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_hexagonal_graph_3_2_bidirectional(self): - graph = retworkx.generators.directed_hexagonal_lattice_graph(3, 2, bidirectional=True) - expected_edges = [ - (0, 1), - (1, 0), - (1, 2), - (2, 1), - (2, 3), - (3, 2), - (3, 4), - (4, 3), - (4, 5), - (5, 4), - (5, 6), - (6, 5), - (7, 8), - (8, 7), - (8, 9), - (9, 8), - (9, 10), - (10, 9), - (10, 11), - (11, 10), - (11, 12), - (12, 11), - (12, 13), - (13, 12), - (13, 14), - (14, 13), - (15, 16), - (16, 15), - (16, 17), - (17, 16), - (17, 18), - (18, 17), - (18, 19), - (19, 18), - (19, 20), - (20, 19), - (20, 21), - (21, 20), - (0, 7), - (7, 0), - (2, 9), - (9, 2), - (4, 11), - (11, 4), - (6, 13), - (13, 6), - (8, 15), - (15, 8), - (10, 17), - (17, 10), - (12, 19), - (19, 12), - (14, 21), - (21, 14), - ] - self.assertEqual(len(graph), 22) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_directed_hexagonal_graph_2_4_bidirectional(self): - graph = retworkx.generators.directed_hexagonal_lattice_graph(2, 4, bidirectional=True) - expected_edges = [ - (0, 1), - (1, 0), - (1, 2), - (2, 1), - (2, 3), - (3, 2), - (3, 4), - (4, 3), - (5, 6), - (6, 5), - (6, 7), - (7, 6), - (7, 8), - (8, 7), - (8, 9), - (9, 8), - (9, 10), - (10, 9), - (11, 12), - (12, 11), - (12, 13), - (13, 12), - (13, 14), - (14, 13), - (14, 15), - (15, 14), - (15, 16), - (16, 15), - (17, 18), - (18, 17), - (18, 19), - (19, 18), - (19, 20), - (20, 19), - (20, 21), - (21, 20), - (21, 22), - (22, 21), - (23, 24), - (24, 23), - (24, 25), - (25, 24), - (25, 26), - (26, 25), - (26, 27), - (27, 26), - (0, 5), - (5, 0), - (2, 7), - (7, 2), - (4, 9), - (9, 4), - (6, 12), - (12, 6), - (8, 14), - (14, 8), - (10, 16), - (16, 10), - (11, 17), - (17, 11), - (13, 19), - (19, 13), - (15, 21), - (21, 15), - (18, 23), - (23, 18), - (20, 25), - (25, 20), - (22, 27), - (27, 22), - ] - self.assertEqual(len(graph), 28) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_hexagonal_graph_2_2(self): - graph = retworkx.generators.hexagonal_lattice_graph(2, 2) - expected_edges = [ - (0, 1), - (1, 2), - (2, 3), - (3, 4), - (5, 6), - (6, 7), - (7, 8), - (8, 9), - (9, 10), - (11, 12), - (12, 13), - (13, 14), - (14, 15), - (0, 5), - (2, 7), - (4, 9), - (6, 11), - (8, 13), - (10, 15), - ] - self.assertEqual(len(graph), 16) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_hexagonal_graph_3_2(self): - graph = retworkx.generators.hexagonal_lattice_graph(3, 2) - expected_edges = [ - (0, 1), - (1, 2), - (2, 3), - (3, 4), - (4, 5), - (5, 6), - (7, 8), - (8, 9), - (9, 10), - (10, 11), - (11, 12), - (12, 13), - (13, 14), - (15, 16), - (16, 17), - (17, 18), - (18, 19), - (19, 20), - (20, 21), - (0, 7), - (2, 9), - (4, 11), - (6, 13), - (8, 15), - (10, 17), - (12, 19), - (14, 21), - ] - self.assertEqual(len(graph), 22) - self.assertEqual(len(graph.edges()), 27) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_hexagonal_graph_2_4(self): - graph = retworkx.generators.hexagonal_lattice_graph(2, 4) - expected_edges = [ - (0, 1), - (1, 2), - (2, 3), - (3, 4), - (5, 6), - (6, 7), - (7, 8), - (8, 9), - (9, 10), - (11, 12), - (12, 13), - (13, 14), - (14, 15), - (15, 16), - (17, 18), - (18, 19), - (19, 20), - (20, 21), - (21, 22), - (23, 24), - (24, 25), - (25, 26), - (26, 27), - (0, 5), - (2, 7), - (4, 9), - (6, 12), - (8, 14), - (10, 16), - (11, 17), - (13, 19), - (15, 21), - (18, 23), - (20, 25), - (22, 27), - ] - self.assertEqual(len(graph), 28) - self.assertEqual(len(graph.edges()), len(expected_edges)) - self.assertEqual(list(graph.edge_list()), expected_edges) - - def test_hexagonal_graph_0_0(self): - graph = retworkx.generators.hexagonal_lattice_graph(0, 0) - self.assertEqual(len(graph), 0) - self.assertEqual(len(graph.edges()), 0) diff --git a/tests/retworkx_backwards_compat/generators/test_lollipop.py b/tests/retworkx_backwards_compat/generators/test_lollipop.py deleted file mode 100644 index 47f66c3e2d..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_lollipop.py +++ /dev/null @@ -1,79 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestLollipopGraph(unittest.TestCase): - def test_lollipop_graph_count(self): - graph = retworkx.generators.lollipop_graph(17, 3) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 139) - - def test_lollipop_graph_weights_count(self): - graph = retworkx.generators.lollipop_graph( - mesh_weights=list(range(17)), path_weights=list(range(17, 20)) - ) - self.assertEqual(len(graph), 20) - self.assertEqual(list(range(20)), graph.nodes()) - self.assertEqual(len(graph.edges()), 139) - - def test_lollipop_graph_edge(self): - graph = retworkx.generators.lollipop_graph(4, 3) - edge_list = graph.edge_list() - expected_edge_list = [ - (0, 1), - (0, 2), - (0, 3), - (1, 2), - (1, 3), - (2, 3), - (3, 4), - (4, 5), - (5, 6), - ] - self.assertEqual(edge_list, expected_edge_list) - - def test_lollipop_graph_weights_edge(self): - graph = retworkx.generators.lollipop_graph( - mesh_weights=list(range(4)), path_weights=list(range(3)) - ) - weighted_edge_list = graph.weighted_edge_list() - expected_weighted_edge_list = [ - (0, 1, None), - (0, 2, None), - (0, 3, None), - (1, 2, None), - (1, 3, None), - (2, 3, None), - (3, 4, None), - (4, 5, None), - (5, 6, None), - ] - self.assertEqual(weighted_edge_list, expected_weighted_edge_list) - self.assertEqual(graph.nodes(), [0, 1, 2, 3, 0, 1, 2]) - - def test_lollipop_graph_no_path_weights_or_num(self): - graph = retworkx.generators.lollipop_graph(mesh_weights=list(range(4))) - mesh = retworkx.generators.mesh_graph(weights=list(range(4))) - self.assertEqual(graph.nodes(), mesh.nodes()) - self.assertEqual(graph.weighted_edge_list(), mesh.weighted_edge_list()) - self.assertEqual( - retworkx.generators.lollipop_graph(4).edge_list(), - retworkx.generators.mesh_graph(4).edge_list(), - ) - - def test_lollipop_graph_no_mesh_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.lollipop_graph() diff --git a/tests/retworkx_backwards_compat/generators/test_mesh.py b/tests/retworkx_backwards_compat/generators/test_mesh.py deleted file mode 100644 index 02e1548578..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_mesh.py +++ /dev/null @@ -1,67 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestMeshGraph(unittest.TestCase): - def test_directed_mesh_graph(self): - graph = retworkx.generators.directed_mesh_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 380) - for i in range(20): - ls = [] - for j in range(19, -1, -1): - if i != j: - ls.append((i, j, None)) - self.assertEqual(graph.out_edges(i), ls) - - def test_directed_mesh_graph_weights(self): - graph = retworkx.generators.directed_mesh_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 380) - for i in range(20): - ls = [] - for j in range(19, -1, -1): - if i != j: - ls.append((i, j, None)) - self.assertEqual(graph.out_edges(i), ls) - - def test_mesh_directed_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.directed_mesh_graph() - - def test_mesh_graph(self): - graph = retworkx.generators.mesh_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 190) - - def test_mesh_graph_weights(self): - graph = retworkx.generators.mesh_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 190) - - def test_mesh_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.mesh_graph() - - def test_zero_size_mesh_graph(self): - graph = retworkx.generators.mesh_graph(0) - self.assertEqual(0, len(graph)) - - def test_zero_size_directed_mesh_graph(self): - graph = retworkx.generators.directed_mesh_graph(0) - self.assertEqual(0, len(graph)) diff --git a/tests/retworkx_backwards_compat/generators/test_path.py b/tests/retworkx_backwards_compat/generators/test_path.py deleted file mode 100644 index 958851bb2b..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_path.py +++ /dev/null @@ -1,71 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestPathGraph(unittest.TestCase): - def test_directed_path_graph(self): - graph = retworkx.generators.directed_path_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 19) - for i in range(19): - self.assertEqual(graph.out_edges(i), [(i, i + 1, None)]) - self.assertEqual(graph.out_edges(19), []) - - def test_directed_path_graph_weights(self): - graph = retworkx.generators.directed_path_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 19) - for i in range(19): - self.assertEqual(graph.out_edges(i), [(i, i + 1, None)]) - self.assertEqual(graph.out_edges(19), []) - - def test_directed_path_graph_bidirectional(self): - graph = retworkx.generators.directed_path_graph(20, bidirectional=True) - self.assertEqual(graph.out_edges(0), [(0, 1, None)]) - self.assertEqual(graph.in_edges(0), [(1, 0, None)]) - for i in range(1, 19): - self.assertEqual(graph.out_edges(i), [(i, i + 1, None), (i, i - 1, None)]) - self.assertEqual(graph.in_edges(i), [(i + 1, i, None), (i - 1, i, None)]) - self.assertEqual(graph.out_edges(19), [(19, 18, None)]) - self.assertEqual(graph.in_edges(19), [(18, 19, None)]) - - def test_path_directed_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.directed_path_graph() - - def test_path_graph(self): - graph = retworkx.generators.path_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 19) - - def test_path_graph_weights(self): - graph = retworkx.generators.path_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 19) - - def test_path_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.path_graph() - - def test_zero_length_path_graph(self): - graph = retworkx.generators.path_graph(0) - self.assertEqual(0, len(graph)) - - def test_zero_length_directed_path_graph(self): - graph = retworkx.generators.directed_path_graph(0) - self.assertEqual(0, len(graph)) diff --git a/tests/retworkx_backwards_compat/generators/test_petersen.py b/tests/retworkx_backwards_compat/generators/test_petersen.py deleted file mode 100644 index 907f528340..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_petersen.py +++ /dev/null @@ -1,56 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestPetersenGraph(unittest.TestCase): - def test_petersen_graph_count(self): - n = 99 - k = 23 - graph = retworkx.generators.generalized_petersen_graph(n, k) - self.assertEqual(len(graph), 2 * n) - self.assertEqual(len(graph.edges()), 3 * n) - - def test_petersen_graph_edge(self): - graph = retworkx.generators.generalized_petersen_graph(5, 2) - edge_list = graph.edge_list() - expected_edge_list = [ - (0, 2), - (1, 3), - (2, 4), - (3, 0), - (4, 1), - (5, 6), - (6, 7), - (7, 8), - (8, 9), - (9, 5), - (5, 0), - (6, 1), - (7, 2), - (8, 3), - (9, 4), - ] - self.assertEqual(edge_list, expected_edge_list) - - def test_petersen_invalid_n_k(self): - with self.assertRaises(IndexError): - retworkx.generators.generalized_petersen_graph(2, 1) - - with self.assertRaises(IndexError): - retworkx.generators.generalized_petersen_graph(5, 0) - - with self.assertRaises(IndexError): - retworkx.generators.generalized_petersen_graph(5, 4) diff --git a/tests/retworkx_backwards_compat/generators/test_star.py b/tests/retworkx_backwards_compat/generators/test_star.py deleted file mode 100644 index 698d5368d5..0000000000 --- a/tests/retworkx_backwards_compat/generators/test_star.py +++ /dev/null @@ -1,108 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestStarGraph(unittest.TestCase): - def test_directed_star_graph(self): - graph = retworkx.generators.directed_star_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 19) - expected_edges = [(0, i, None) for i in range(1, 20)] - self.assertEqual(sorted(graph.out_edges(0)), sorted(expected_edges)) - - def test_star_directed_graph_inward(self): - graph = retworkx.generators.directed_star_graph(20, inward=True) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 19) - expected_edges = [(i, 0, None) for i in range(1, 20)] - self.assertEqual(sorted(graph.in_edges(0)), sorted(expected_edges)) - - def test_directed_star_graph_weights(self): - graph = retworkx.generators.directed_star_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 19) - expected_edges = sorted([(0, i, None) for i in range(1, 20)]) - self.assertEqual(sorted(graph.out_edges(0)), expected_edges) - - def test_directed_star_graph_bidirectional(self): - graph = retworkx.generators.directed_star_graph(20, bidirectional=True) - outw = [] - inw = [] - for i in range(1, 20): - outw.append((0, i, None)) - inw.append((i, 0, None)) - self.assertEqual(graph.out_edges(i), [(i, 0, None)]) - self.assertEqual(graph.in_edges(i), [(0, i, None)]) - self.assertEqual(graph.out_edges(0), outw[::-1]) - self.assertEqual(graph.in_edges(0), inw[::-1]) - - def test_directed_star_graph_bidirectional_inward(self): - graph = retworkx.generators.directed_star_graph(20, bidirectional=True, inward=True) - outw = [] - inw = [] - for i in range(1, 20): - outw.append((0, i, None)) - inw.append((i, 0, None)) - self.assertEqual(graph.out_edges(i), [(i, 0, None)]) - self.assertEqual(graph.in_edges(i), [(0, i, None)]) - self.assertEqual(graph.out_edges(0), outw[::-1]) - self.assertEqual(graph.in_edges(0), inw[::-1]) - graph = retworkx.generators.directed_star_graph(20, bidirectional=True, inward=False) - outw = [] - inw = [] - for i in range(1, 20): - outw.append((0, i, None)) - inw.append((i, 0, None)) - self.assertEqual(graph.out_edges(i), [(i, 0, None)]) - self.assertEqual(graph.in_edges(i), [(0, i, None)]) - self.assertEqual(graph.out_edges(0), outw[::-1]) - self.assertEqual(graph.in_edges(0), inw[::-1]) - - def test_star_directed_graph_weights_inward(self): - graph = retworkx.generators.directed_star_graph(weights=list(range(20)), inward=True) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 19) - expected_edges = [(i, 0, None) for i in range(1, 20)] - self.assertEqual(sorted(graph.in_edges(0)), sorted(expected_edges)) - - def test_star_directed_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.directed_star_graph() - - def test_star_graph(self): - graph = retworkx.generators.star_graph(20) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 19) - - def test_star_graph_weights(self): - graph = retworkx.generators.star_graph(weights=list(range(20))) - self.assertEqual(len(graph), 20) - self.assertEqual([x for x in range(20)], graph.nodes()) - self.assertEqual(len(graph.edges()), 19) - - def test_star_no_weights_or_num(self): - with self.assertRaises(IndexError): - retworkx.generators.star_graph() - - def test_zero_length_star_graph(self): - graph = retworkx.generators.star_graph(0) - self.assertEqual(0, len(graph)) - - def test_zero_length_directed_star_graph(self): - graph = retworkx.generators.directed_star_graph(0) - self.assertEqual(0, len(graph)) diff --git a/tests/retworkx_backwards_compat/graph/__init__.py b/tests/retworkx_backwards_compat/graph/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/retworkx_backwards_compat/graph/test_adj.py b/tests/retworkx_backwards_compat/graph/test_adj.py deleted file mode 100644 index 43b4a6d9f1..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_adj.py +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAdj(unittest.TestCase): - def test_single_neighbor(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, {"a": 1}) - node_c = graph.add_node("c") - graph.add_edge(node_a, node_c, {"a": 2}) - res = graph.adj(node_a) - self.assertEqual({node_b: {"a": 1}, node_c: {"a": 2}}, res) - - def test_no_neighbor(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - self.assertEqual({}, graph.adj(node_a)) diff --git a/tests/retworkx_backwards_compat/graph/test_adjencency_matrix.py b/tests/retworkx_backwards_compat/graph/test_adjencency_matrix.py deleted file mode 100644 index 32c3df44db..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_adjencency_matrix.py +++ /dev/null @@ -1,262 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx -import numpy as np - - -class TestGraphAdjacencyMatrix(unittest.TestCase): - def test_single_neighbor(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edge_a") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "edge_b") - res = retworkx.graph_adjacency_matrix(graph, lambda x: 1) - self.assertIsInstance(res, np.ndarray) - self.assertTrue( - np.array_equal( - np.array( - [[0.0, 1.0, 0.0], [1.0, 0.0, 1.0], [0.0, 1.0, 0.0]], - dtype=np.float64, - ), - res, - ) - ) - - def test_no_weight_fn(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edge_a") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "edge_b") - res = retworkx.graph_adjacency_matrix(graph) - self.assertIsInstance(res, np.ndarray) - self.assertTrue( - np.array_equal( - np.array( - [[0.0, 1.0, 0.0], [1.0, 0.0, 1.0], [0.0, 1.0, 0.0]], - dtype=np.float64, - ), - res, - ) - ) - - def test_default_weight(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edge_a") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "edge_b") - res = retworkx.graph_adjacency_matrix(graph, default_weight=4) - self.assertIsInstance(res, np.ndarray) - self.assertTrue( - np.array_equal( - np.array( - [[0.0, 4.0, 0.0], [4.0, 0.0, 4.0], [0.0, 4.0, 0.0]], - dtype=np.float64, - ), - res, - ) - ) - - def test_float_cast_weight_func(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, 7.0) - res = retworkx.graph_adjacency_matrix(graph, lambda x: float(x)) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[0.0, 7.0], [7.0, 0.0]]), res)) - - def test_multigraph_sum_cast_weight_func(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, 7.0) - graph.add_edge(node_a, node_b, 0.5) - res = retworkx.graph_adjacency_matrix(graph, lambda x: float(x)) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[0.0, 7.5], [7.5, 0.0]]), res)) - - def test_multigraph_sum_cast_weight_func_non_zero_null(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, 7.0) - graph.add_edge(node_a, node_b, 0.5) - res = retworkx.graph_adjacency_matrix(graph, lambda x: float(x), null_value=np.inf) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[np.inf, 7.5], [7.5, np.inf]]), res)) - - def test_dag_to_graph_adjacency_matrix(self): - dag = retworkx.PyDAG() - self.assertRaises(TypeError, retworkx.graph_adjacency_matrix, dag) - - def test_no_edge_graph_adjacency_matrix(self): - graph = retworkx.PyGraph() - for i in range(50): - graph.add_node(i) - res = retworkx.graph_adjacency_matrix(graph, lambda x: 1) - self.assertTrue(np.array_equal(np.zeros([50, 50]), res)) - - def test_graph_with_index_holes(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, 1) - node_c = graph.add_node("c") - graph.add_edge(node_a, node_c, 1) - graph.remove_node(node_b) - res = retworkx.graph_adjacency_matrix(graph, lambda x: 1) - self.assertIsInstance(res, np.ndarray) - self.assertTrue(np.array_equal(np.array([[0, 1], [1, 0]]), res)) - - def test_from_adjacency_matrix(self): - input_array = np.array( - [[0.0, 4.0, 0.0], [4.0, 0.0, 4.0], [0.0, 4.0, 0.0]], - dtype=np.float64, - ) - graph = retworkx.PyGraph.from_adjacency_matrix(input_array) - out_array = retworkx.graph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(input_array, out_array)) - - def test_random_graph_full_path(self): - graph = retworkx.undirected_gnp_random_graph(100, 0.95, seed=42) - adjacency_matrix = retworkx.graph_adjacency_matrix(graph) - new_graph = retworkx.PyGraph.from_adjacency_matrix(adjacency_matrix) - new_adjacency_matrix = retworkx.graph_adjacency_matrix(new_graph) - self.assertTrue(np.array_equal(adjacency_matrix, new_adjacency_matrix)) - - def test_random_graph_different_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - with self.assertRaises(TypeError): - retworkx.PyGraph.from_adjacency_matrix(input_matrix) - - def test_random_graph_different_dtype_astype_no_copy(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - graph = retworkx.PyGraph.from_adjacency_matrix(input_matrix.astype(np.float64, copy=False)) - adj_matrix = retworkx.graph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(adj_matrix, input_matrix)) - - def test_random_graph_float_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=float) - graph = retworkx.PyGraph.from_adjacency_matrix(input_matrix) - adj_matrix = retworkx.graph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(adj_matrix, input_matrix)) - - def test_graph_to_digraph_adjacency_matrix(self): - graph = retworkx.PyGraph() - self.assertRaises(TypeError, retworkx.digraph_adjacency_matrix, graph) - - def test_non_zero_null(self): - input_matrix = np.array( - [[np.Inf, 1, np.Inf], [1, np.Inf, 1], [np.Inf, 1, np.Inf]], - dtype=np.float64, - ) - graph = retworkx.PyGraph.from_adjacency_matrix(input_matrix, null_value=np.Inf) - adj_matrix = retworkx.adjacency_matrix(graph, float) - expected_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.float64) - self.assertTrue(np.array_equal(adj_matrix, expected_matrix)) - - def test_negative_weight(self): - input_matrix = np.array([[0, -1, 0], [-1, 0, -1], [0, -1, 0]], dtype=float) - graph = retworkx.PyGraph.from_adjacency_matrix(input_matrix) - adj_matrix = retworkx.graph_adjacency_matrix(graph, lambda x: x) - self.assertTrue(np.array_equal(adj_matrix, input_matrix)) - self.assertEqual([(0, 1, -1), (1, 2, -1)], graph.weighted_edge_list()) - - def test_nan_null(self): - input_matrix = np.array( - [[np.nan, 1, np.nan], [1, np.nan, 1], [np.nan, 1, np.nan]], - dtype=np.float64, - ) - graph = retworkx.PyGraph.from_adjacency_matrix(input_matrix, null_value=np.nan) - adj_matrix = retworkx.adjacency_matrix(graph, float) - expected_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.float64) - self.assertTrue(np.array_equal(adj_matrix, expected_matrix)) - - -class TestFromComplexAdjacencyMatrix(unittest.TestCase): - def test_from_adjacency_matrix(self): - input_array = np.array( - [[0.0, 4.0, 0.0], [4.0, 0.0, 4.0], [0.0, 4.0, 0.0]], - dtype=np.complex128, - ) - graph = retworkx.PyGraph.from_complex_adjacency_matrix(input_array) - expected = [ - (0, 1, 4 + 0j), - (1, 2, 4 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_random_graph_different_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - with self.assertRaises(TypeError): - retworkx.PyGraph.from_complex_adjacency_matrix(input_matrix) - - def test_random_graph_different_dtype_astype_no_copy(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=np.int64) - graph = retworkx.PyGraph.from_complex_adjacency_matrix( - input_matrix.astype(np.complex128, copy=False) - ) - expected = [ - (0, 1, 1 + 0j), - (1, 2, 1 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_random_graph_complex_dtype(self): - input_matrix = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=complex) - graph = retworkx.PyGraph.from_complex_adjacency_matrix(input_matrix) - expected = [ - (0, 1, 1 + 0j), - (1, 2, 1 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_non_zero_null(self): - input_matrix = np.array( - [[np.Inf, 1, np.Inf], [1, np.Inf, 1], [np.Inf, 1, np.Inf]], - dtype=np.complex128, - ) - graph = retworkx.PyGraph.from_complex_adjacency_matrix(input_matrix, null_value=np.Inf) - expected = [ - (0, 1, 1 + 0j), - (1, 2, 1 + 0j), - ] - self.assertEqual(graph.weighted_edge_list(), expected) - - def test_negative_weight(self): - input_matrix = np.array([[0, 1, 0], [-1, 0, -1], [0, 1, 0]], dtype=complex) - graph = retworkx.PyGraph.from_complex_adjacency_matrix(input_matrix) - self.assertEqual( - [(0, 1, 1), (1, 2, -1)], - graph.weighted_edge_list(), - ) - - def test_nan_null(self): - input_matrix = np.array( - [[np.nan, 1, np.nan], [1, np.nan, 1], [np.nan, 1, np.nan]], - dtype=np.complex128, - ) - graph = retworkx.PyGraph.from_complex_adjacency_matrix(input_matrix, null_value=np.nan) - edge_list = graph.weighted_edge_list() - self.assertEqual( - edge_list, - [(0, 1, 1 + 0j), (1, 2, 1 + 0j)], - ) diff --git a/tests/retworkx_backwards_compat/graph/test_all_simple_paths.py b/tests/retworkx_backwards_compat/graph/test_all_simple_paths.py deleted file mode 100644 index 7e8d76f004..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_all_simple_paths.py +++ /dev/null @@ -1,245 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestGraphAllSimplePaths(unittest.TestCase): - def setUp(self): - super().setUp() - self.edges = [ - (0, 1), - (0, 2), - (0, 3), - (1, 2), - (1, 3), - (2, 3), - (2, 4), - (3, 2), - (3, 4), - (4, 2), - (4, 5), - (5, 2), - (5, 3), - ] - - def test_all_simple_paths(self): - graph = retworkx.PyGraph() - for i in range(6): - graph.add_node(i) - graph.add_edges_from_no_data(self.edges) - paths = retworkx.graph_all_simple_paths(graph, 0, 5) - 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 = retworkx.PyGraph() - for i in range(6): - graph.add_node(i) - graph.add_edges_from_no_data(self.edges) - paths = retworkx.graph_all_simple_paths(graph, 0, 5, min_depth=6) - expected = [ - [0, 3, 1, 2, 4, 5], - [0, 3, 1, 2, 4, 5], - [0, 2, 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, 4, 5], - [0, 1, 3, 2, 4, 5], - [0, 1, 3, 2, 4, 5], - [0, 1, 2, 4, 3, 5], - [0, 1, 2, 3, 4, 5], - [0, 1, 2, 4, 3, 5], - [0, 1, 2, 3, 4, 5], - ] - self.assertEqual(len(expected), len(paths)) - for i in expected: - self.assertIn(i, paths) - - def test_all_simple_paths_with_cutoff(self): - graph = retworkx.PyGraph() - for i in range(6): - graph.add_node(i) - graph.add_edges_from_no_data(self.edges) - paths = retworkx.graph_all_simple_paths(graph, 0, 5, cutoff=4) - expected = [ - [0, 3, 4, 5], - [0, 3, 2, 5], - [0, 3, 5], - [0, 3, 2, 5], - [0, 2, 4, 5], - [0, 2, 3, 5], - [0, 2, 5], - [0, 2, 4, 5], - [0, 2, 3, 5], - [0, 1, 3, 5], - [0, 1, 2, 5], - ] - self.assertEqual(len(expected), len(paths)) - for i in expected: - self.assertIn(i, paths) - - def test_all_simple_paths_with_min_depth_and_cutoff(self): - graph = retworkx.PyGraph() - for i in range(6): - graph.add_node(i) - graph.add_edges_from_no_data(self.edges) - paths = retworkx.graph_all_simple_paths(graph, 0, 5, min_depth=4, cutoff=4) - expected = [ - [0, 3, 4, 5], - [0, 3, 2, 5], - [0, 3, 2, 5], - [0, 2, 4, 5], - [0, 2, 3, 5], - [0, 2, 4, 5], - [0, 2, 3, 5], - [0, 1, 3, 5], - [0, 1, 2, 5], - ] - self.assertEqual(len(expected), len(paths)) - for i in expected: - self.assertIn(i, paths) - - def test_all_simple_path_no_path(self): - dag = retworkx.PyGraph() - dag.add_node(0) - dag.add_node(1) - self.assertEqual([], retworkx.graph_all_simple_paths(dag, 0, 1)) - - def test_all_simple_path_invalid_node_index(self): - dag = retworkx.PyGraph() - dag.add_node(0) - dag.add_node(1) - with self.assertRaises(retworkx.InvalidNode): - retworkx.graph_all_simple_paths(dag, 0, 5) - - def test_digraph_graph_all_simple_paths(self): - dag = retworkx.PyDAG() - dag.add_node(0) - dag.add_node(1) - self.assertRaises(TypeError, retworkx.graph_all_simple_paths, (dag, 0, 1)) - - -class TestGraphAllSimplePathsAllPairs(unittest.TestCase): - def setUp(self): - super().setUp() - self.graph = retworkx.generators.cycle_graph(4) - - def test_all_simple_paths(self): - paths = retworkx.all_pairs_all_simple_paths(self.graph) - expected = { - 0: {1: [[0, 1], [0, 3, 2, 1]], 2: [[0, 1, 2], [0, 3, 2]], 3: [[0, 1, 2, 3], [0, 3]]}, - 1: {2: [[1, 2], [1, 0, 3, 2]], 3: [[1, 2, 3], [1, 0, 3]], 0: [[1, 2, 3, 0], [1, 0]]}, - 2: { - 3: [[2, 3], [2, 1, 0, 3]], - 0: [[2, 3, 0], [2, 1, 0]], - 1: [[2, 3, 0, 1], [2, 1]], - }, - 3: {0: [[3, 0], [3, 2, 1, 0]], 1: [[3, 0, 1], [3, 2, 1]], 2: [[3, 0, 1, 2], [3, 2]]}, - } - self.assertEqual(paths, expected) - - def test_all_simple_paths_min_depth(self): - paths = retworkx.all_pairs_all_simple_paths(self.graph, min_depth=3) - expected = { - 0: {1: [[0, 3, 2, 1]], 2: [[0, 1, 2], [0, 3, 2]], 3: [[0, 1, 2, 3]]}, - 1: {2: [[1, 0, 3, 2]], 3: [[1, 2, 3], [1, 0, 3]], 0: [[1, 2, 3, 0]]}, - 2: { - 3: [[2, 1, 0, 3]], - 0: [[2, 3, 0], [2, 1, 0]], - 1: [[2, 3, 0, 1]], - }, - 3: {0: [[3, 2, 1, 0]], 1: [[3, 0, 1], [3, 2, 1]], 2: [[3, 0, 1, 2]]}, - } - self.assertEqual(paths, expected) - - def test_all_simple_paths_with_cutoff(self): - paths = retworkx.all_pairs_all_simple_paths(self.graph, cutoff=3) - expected = { - 0: {1: [[0, 1]], 2: [[0, 1, 2], [0, 3, 2]], 3: [[0, 3]]}, - 1: {2: [[1, 2]], 3: [[1, 2, 3], [1, 0, 3]], 0: [[1, 0]]}, - 2: { - 3: [[2, 3]], - 0: [[2, 3, 0], [2, 1, 0]], - 1: [[2, 1]], - }, - 3: {0: [[3, 0]], 1: [[3, 0, 1], [3, 2, 1]], 2: [[3, 2]]}, - } - self.assertEqual(paths, expected) - - def test_all_simple_paths_with_min_depth_and_cutoff(self): - paths = retworkx.all_pairs_all_simple_paths(self.graph, min_depth=3, cutoff=3) - expected = { - 0: {2: [[0, 1, 2], [0, 3, 2]]}, - 1: {3: [[1, 2, 3], [1, 0, 3]]}, - 2: {0: [[2, 3, 0], [2, 1, 0]]}, - 3: {1: [[3, 0, 1], [3, 2, 1]]}, - } - self.assertEqual(paths, expected) - - def test_all_simple_path_no_path(self): - graph = retworkx.PyGraph() - graph.add_node(0) - graph.add_node(1) - self.assertEqual({0: {}, 1: {}}, retworkx.all_pairs_all_simple_paths(graph)) - - def test_all_simple_paths_empty(self): - self.assertEqual({}, retworkx.all_pairs_all_simple_paths(retworkx.PyGraph())) diff --git a/tests/retworkx_backwards_compat/graph/test_astar.py b/tests/retworkx_backwards_compat/graph/test_astar.py deleted file mode 100644 index 6f1525e237..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_astar.py +++ /dev/null @@ -1,114 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAstarGraph(unittest.TestCase): - def test_astar_null_heuristic(self): - g = retworkx.PyGraph() - a = g.add_node("A") - b = g.add_node("B") - c = g.add_node("C") - d = g.add_node("D") - e = g.add_node("E") - f = g.add_node("F") - g.add_edge(a, b, 7) - g.add_edge(c, a, 9) - g.add_edge(a, d, 14) - g.add_edge(b, c, 10) - g.add_edge(d, c, 2) - g.add_edge(d, e, 9) - g.add_edge(b, f, 15) - g.add_edge(c, f, 11) - g.add_edge(e, f, 6) - path = retworkx.graph_astar_shortest_path( - g, a, lambda goal: goal == "E", lambda x: float(x), lambda y: 0 - ) - expected = [a, c, d, e] - self.assertEqual(expected, path) - - def test_astar_manhattan_heuristic(self): - g = retworkx.PyGraph() - a = g.add_node((0.0, 0.0)) - b = g.add_node((2.0, 0.0)) - c = g.add_node((1.0, 1.0)) - d = g.add_node((0.0, 2.0)) - e = g.add_node((3.0, 3.0)) - f = g.add_node((4.0, 2.0)) - no_path = g.add_node((5.0, 5.0)) # no path to node - g.add_edge(a, b, 2.0) - g.add_edge(a, d, 4.0) - g.add_edge(b, c, 1.0) - g.add_edge(b, f, 7.0) - g.add_edge(c, e, 5.0) - g.add_edge(e, f, 1.0) - g.add_edge(d, e, 1.0) - - def heuristic_func(f): - x1, x2 = f - return abs(x2 - x1) - - def finish_func(node, x): - return x == g.get_node_data(node) - - expected = [ - [0], - [0, 1], - [0, 1, 2], - [0, 3], - [0, 3, 4], - [0, 3, 4, 5], - ] - - for index, end in enumerate([a, b, c, d, e, f]): - path = retworkx.graph_astar_shortest_path( - g, - a, - lambda finish: finish_func(end, finish), - lambda x: float(x), - heuristic_func, - ) - self.assertEqual(expected[index], path) - - with self.assertRaises(retworkx.NoPathFound): - retworkx.graph_astar_shortest_path( - g, - a, - lambda finish: finish_func(no_path, finish), - lambda x: float(x), - heuristic_func, - ) - - def test_astar_graph_with_digraph_input(self): - g = retworkx.PyDAG() - g.add_node(0) - with self.assertRaises(TypeError): - retworkx.graph_astar_shortest_path(g, 0, lambda x: x, lambda y: 1, lambda z: 0) - - def test_astar_with_invalid_weights(self): - g = retworkx.PyGraph() - a = g.add_node("A") - b = g.add_node("B") - g.add_edge(a, b, 7) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.graph_astar_shortest_path( - g, - a, - goal_fn=lambda goal: goal == "B", - edge_cost_fn=lambda _: invalid_weight, - estimate_cost_fn=lambda _: 0, - ) diff --git a/tests/retworkx_backwards_compat/graph/test_avg_shortest_path.py b/tests/retworkx_backwards_compat/graph/test_avg_shortest_path.py deleted file mode 100644 index 18ff98ab05..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_avg_shortest_path.py +++ /dev/null @@ -1,89 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import math -import unittest - -import retworkx - - -class TestUnweightedAvgShortestPath(unittest.TestCase): - def test_simple_example(self): - edge_list = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (3, 6), (6, 7)] - graph = retworkx.PyGraph() - graph.extend_from_edge_list(edge_list) - res = retworkx.graph_unweighted_average_shortest_path_length(graph) - self.assertAlmostEqual(2.5714285714285716, res, delta=1e-7) - - def test_cycle_graph(self): - graph = retworkx.generators.cycle_graph(7) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertAlmostEqual(2, res, delta=1e-7) - - def test_path_graph(self): - graph = retworkx.generators.path_graph(5) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertAlmostEqual(2, res, delta=1e-7) - - def test_parallel_grid(self): - graph = retworkx.generators.grid_graph(30, 11) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertAlmostEqual(13.666666666666666, res, delta=1e-7) - - def test_empty(self): - graph = retworkx.PyGraph() - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_single_node(self): - graph = retworkx.PyGraph() - graph.add_node(0) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_single_node_self_edge(self): - graph = retworkx.PyGraph() - node = graph.add_node(0) - graph.add_edge(node, node, 0) - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_disconnected_graph(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(32))) - with self.subTest(disconnected=False): - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isinf(res), "Output is not infinity") - - with self.subTest(disconnected=True): - res = retworkx.unweighted_average_shortest_path_length(graph, disconnected=True) - self.assertTrue(math.isnan(res), "Output is not NaN") - - def test_partially_connected_graph(self): - graph = retworkx.generators.cycle_graph(32) - graph.add_nodes_from(list(range(32))) - with self.subTest(disconnected=False): - res = retworkx.unweighted_average_shortest_path_length(graph) - self.assertTrue(math.isinf(res), "Output is not infinity") - - with self.subTest(disconnected=True): - s = 8192 - den = 992 # n*(n-1), n=32 (only connected pairs considered) - res = retworkx.unweighted_average_shortest_path_length(graph, disconnected=True) - self.assertAlmostEqual(s / den, res, delta=1e-7) - - def test_connected_cycle_graph(self): - graph = retworkx.generators.cycle_graph(32) - res = retworkx.unweighted_average_shortest_path_length(graph) - s = 8192 - den = 992 # n*(n-1) - self.assertAlmostEqual(s / den, res, delta=1e-7) diff --git a/tests/retworkx_backwards_compat/graph/test_bellman_ford.py b/tests/retworkx_backwards_compat/graph/test_bellman_ford.py deleted file mode 100644 index 6511e3ea32..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_bellman_ford.py +++ /dev/null @@ -1,308 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestBellmanFordGraph(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - self.d = self.graph.add_node("D") - self.e = self.graph.add_node("E") - self.f = self.graph.add_node("F") - self.graph.add_edge(self.a, self.b, 7) - self.graph.add_edge(self.c, self.a, 9) - self.graph.add_edge(self.a, self.d, 14) - self.graph.add_edge(self.b, self.c, 10) - self.graph.add_edge(self.d, self.c, 2) - self.graph.add_edge(self.d, self.e, 9) - self.graph.add_edge(self.b, self.f, 15) - self.graph.add_edge(self.c, self.f, 11) - self.graph.add_edge(self.e, self.f, 6) - - def test_bellman_ford(self): - path = retworkx.graph_bellman_ford_shortest_path_lengths( - self.graph, self.a, lambda x: float(x) - ) - path_dijkstra = retworkx.graph_dijkstra_shortest_path_lengths( - self.graph, self.a, lambda x: float(x) - ) - self.assertEqual(path_dijkstra, path) - - def test_bellman_ford_path(self): - path = retworkx.graph_bellman_ford_shortest_paths( - self.graph, self.a, weight_fn=lambda x: float(x) - ) - # a -> d -> e = 23 - # a -> c -> d -> e = 20 - expected = retworkx.graph_dijkstra_shortest_paths( - self.graph, self.a, weight_fn=lambda x: float(x) - ) - self.assertEqual(expected, path) - - def test_bellman_ford_with_no_goal_set(self): - path = retworkx.graph_bellman_ford_shortest_path_lengths(self.graph, self.a, lambda x: 1) - expected = retworkx.graph_dijkstra_shortest_path_lengths(self.graph, self.a, lambda x: 1) - self.assertEqual(expected, path) - - def test_bellman_path(self): - path = retworkx.graph_bellman_ford_shortest_paths( - self.graph, self.a, weight_fn=lambda x: float(x), target=self.e - ) - expected = retworkx.graph_dijkstra_shortest_paths( - self.graph, self.a, weight_fn=lambda x: float(x), target=self.e - ) - self.assertEqual(expected, path) - - def test_bellman_path_lengths(self): - path = retworkx.graph_bellman_ford_shortest_path_lengths( - self.graph, self.a, lambda x: float(x), goal=self.e - ) - expected = retworkx.graph_dijkstra_shortest_path_lengths( - self.graph, self.a, lambda x: float(x), goal=self.e - ) - self.assertEqual(expected, path) - - def test_bellman_ford_length_with_no_path_and_goal(self): - g = retworkx.PyGraph() - a = g.add_node("A") - b = g.add_node("B") - path_lenghts = retworkx.graph_bellman_ford_shortest_path_lengths( - g, a, edge_cost_fn=float, goal=b - ) - expected = retworkx.graph_dijkstra_shortest_path_lengths(g, a, edge_cost_fn=float, goal=b) - self.assertEqual(expected, path_lenghts) - - def test_bellman_ford_length_with_no_path(self): - g = retworkx.PyGraph() - a = g.add_node("A") - g.add_node("B") - path_lenghts = retworkx.graph_bellman_ford_shortest_path_lengths(g, a, edge_cost_fn=float) - expected = {} - self.assertEqual(expected, path_lenghts) - - def test_bellman_ford_path_with_no_goal_set(self): - path = retworkx.graph_bellman_ford_shortest_paths(self.graph, self.a) - expected = { - 1: [0, 1], - 2: [0, 2], - 3: [0, 3], - 4: [0, 3, 4], - 5: [0, 1, 5], - } - self.assertEqual(expected, path) - - def test_bellman_ford_with_no_path(self): - g = retworkx.PyGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.graph_bellman_ford_shortest_path_lengths(g, a, lambda x: float(x)) - expected = {} - self.assertEqual(expected, path) - - def test_bellman_ford_path_with_no_path(self): - g = retworkx.PyGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.graph_bellman_ford_shortest_paths(g, a, weight_fn=lambda x: float(x)) - expected = {} - self.assertEqual(expected, path) - - def test_bellman_ford_with_disconnected_nodes(self): - g = retworkx.PyGraph() - a = g.add_node("A") - b = g.add_node("B") - g.add_edge(a, b, 1.2) - g.add_node("C") - d = g.add_node("D") - g.add_edge(b, d, 2.4) - path = retworkx.graph_bellman_ford_shortest_path_lengths(g, a, lambda x: round(x, 1)) - # Computers never work: - expected = {1: 1.2, 3: 3.5999999999999996} - self.assertEqual(expected, path) - - def test_bellman_ford_graph_with_digraph_input(self): - g = retworkx.PyDAG() - g.add_node(0) - with self.assertRaises(TypeError): - retworkx.graph_bellman_ford_shortest_path_lengths(g, 0, lambda x: x) - - def bellman_ford_with_invalid_weights(self): - graph = retworkx.generators.path_graph(2) - for as_undirected in [False, True]: - with self.subTest(as_undirected=as_undirected): - with self.assertRaises(ValueError): - retworkx.graph_bellman_ford_shortest_paths( - graph, - source=0, - weight_fn=lambda _: float("nan"), - as_undirected=as_undirected, - ) - - def bellman_ford_lengths_with_invalid_weights(self): - graph = retworkx.generators.path_graph(2) - with self.assertRaises(ValueError): - retworkx.graph_bellman_ford_shortest_path_lengths( - graph, node=0, edge_cost_fn=lambda _: float("nan") - ) - - def test_raises_negative_cycle_bellman_ford_paths(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.bellman_ford_shortest_paths(graph, 0, weight_fn=float) - - def test_raises_negative_cycle_bellman_ford_path_lenghts(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.bellman_ford_shortest_path_lengths(graph, 0, edge_cost_fn=float) - - def test_bellman_all_pair_path_lengths(self): - lengths = retworkx.all_pairs_bellman_ford_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 9.0, 3: 11.0, 4: 20.0, 5: 20.0}, - 1: {0: 7.0, 2: 10.0, 3: 12.0, 4: 21.0, 5: 15.0}, - 2: {0: 9.0, 1: 10.0, 3: 2.0, 4: 11.0, 5: 11.0}, - 3: {0: 11.0, 1: 12.0, 2: 2.0, 4: 9.0, 5: 13.0}, - 4: {0: 20.0, 1: 21.0, 2: 11.0, 3: 9.0, 5: 6.0}, - 5: {0: 20.0, 1: 15.0, 2: 11.0, 3: 13.0, 4: 6.0}, - } - self.assertEqual(expected, lengths) - - def test_bellman_ford_all_pair_paths(self): - paths = retworkx.graph_all_pairs_bellman_ford_shortest_paths(self.graph, float) - expected = { - 0: { - 1: [0, 1], - 2: [0, 2], - 3: [0, 2, 3], - 4: [0, 2, 3, 4], - 5: [0, 2, 5], - }, - 1: {0: [1, 0], 2: [1, 2], 3: [1, 2, 3], 4: [1, 5, 4], 5: [1, 5]}, - 2: {0: [2, 0], 1: [2, 1], 3: [2, 3], 4: [2, 3, 4], 5: [2, 5]}, - 3: {0: [3, 2, 0], 1: [3, 2, 1], 2: [3, 2], 4: [3, 4], 5: [3, 2, 5]}, - 4: { - 0: [4, 3, 2, 0], - 1: [4, 5, 1], - 2: [4, 3, 2], - 3: [4, 3], - 5: [4, 5], - }, - 5: {0: [5, 2, 0], 1: [5, 1], 2: [5, 2], 3: [5, 2, 3], 4: [5, 4]}, - } - - self.assertEqual(expected, paths) - - def test_bellman_ford_all_pair_path_lengths_with_node_removal(self): - self.graph.remove_node(3) - lengths = retworkx.graph_all_pairs_bellman_ford_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 9.0, 4: 26.0, 5: 20.0}, - 1: {0: 7.0, 2: 10.0, 4: 21.0, 5: 15.0}, - 2: {0: 9.0, 1: 10.0, 4: 17.0, 5: 11.0}, - 4: {0: 26.0, 1: 21.0, 2: 17.0, 5: 6.0}, - 5: {0: 20.0, 1: 15.0, 2: 11.0, 4: 6.0}, - } - self.assertEqual(expected, lengths) - - def test_bellman_ford_all_pair_paths_with_node_removal(self): - self.graph.remove_node(3) - paths = retworkx.graph_all_pairs_bellman_ford_shortest_paths(self.graph, float) - expected = { - 0: {1: [0, 1], 2: [0, 2], 4: [0, 2, 5, 4], 5: [0, 2, 5]}, - 1: {0: [1, 0], 2: [1, 2], 4: [1, 5, 4], 5: [1, 5]}, - 2: {0: [2, 0], 1: [2, 1], 4: [2, 5, 4], 5: [2, 5]}, - 4: {0: [4, 5, 2, 0], 1: [4, 5, 1], 2: [4, 5, 2], 5: [4, 5]}, - 5: {0: [5, 2, 0], 1: [5, 1], 2: [5, 2], 4: [5, 4]}, - } - self.assertEqual(expected, paths) - - def test_bellman_ford_all_pair_path_lengths_empty_graph(self): - graph = retworkx.PyGraph() - self.assertEqual({}, retworkx.graph_all_pairs_bellman_ford_path_lengths(graph, float)) - - def test_bellman_ford_all_pair_shortest_paths_empty_graph(self): - graph = retworkx.PyGraph() - self.assertEqual({}, retworkx.graph_all_pairs_bellman_ford_shortest_paths(graph, float)) - - def test_bellman_ford_all_pair_path_lengths_graph_no_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.graph_all_pairs_bellman_ford_path_lengths(graph, float), - ) - - def test_bellman_ford_all_pair_shortest_paths_no_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.graph_all_pairs_bellman_ford_shortest_paths(graph, float), - ) - - def test_raises_negative_cycle_all_pairs_bellman_ford_paths(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.all_pairs_bellman_ford_shortest_paths(graph, float) - - def test_raises_negative_cycle_all_pairs_bellman_ford_path_lenghts(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - - with self.assertRaises(retworkx.NegativeCycle): - retworkx.all_pairs_bellman_ford_path_lengths(graph, float) diff --git a/tests/retworkx_backwards_compat/graph/test_bfs_search.py b/tests/retworkx_backwards_compat/graph/test_bfs_search.py deleted file mode 100644 index 0559873013..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_bfs_search.py +++ /dev/null @@ -1,162 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestBfsSearch(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.graph.extend_from_edge_list( - [ - (0, 1), - (0, 2), - (1, 3), - (2, 1), - (2, 5), - (2, 6), - (5, 3), - (4, 7), - ] - ) - - def test_graph_bfs_tree_edges(self): - class TreeEdgesRecorder(retworkx.visit.BFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.graph_bfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 2), (0, 1), (2, 6), (2, 5), (1, 3)]) - - def test_graph_bfs_tree_edges_no_starting_point(self): - class TreeEdgesRecorder(retworkx.visit.BFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.graph_bfs_search(self.graph, None, vis) - self.assertEqual(vis.edges, [(0, 2), (0, 1), (2, 6), (2, 5), (1, 3), (4, 7)]) - - def test_graph_bfs_tree_edges_restricted(self): - class TreeEdgesRecorderRestricted(retworkx.visit.BFSVisitor): - - prohibited = [(0, 2), (1, 2)] - - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - edge = (edge[0], edge[1]) - if edge in self.prohibited: - raise retworkx.visit.PruneSearch - self.edges.append(edge) - - vis = TreeEdgesRecorderRestricted() - retworkx.graph_bfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 1), (1, 3), (3, 5), (5, 2), (2, 6)]) - - def test_graph_bfs_goal_search_with_stop_search_exception(self): - class GoalSearch(retworkx.visit.BFSVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - - def tree_edge(self, edge): - u, v, _ = edge - self.parents[v] = u - - if v == self.goal: - raise retworkx.visit.StopSearch - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - retworkx.graph_bfs_search(self.graph, [0], vis) - self.assertEqual(vis.reconstruct_path(), [0, 1, 3]) - - def test_graph_bfs_goal_search_with_custom_exception(self): - class StopIfGoalFound(Exception): - pass - - class GoalSearch(retworkx.visit.BFSVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - - def tree_edge(self, edge): - u, v, _ = edge - self.parents[v] = u - - if v == self.goal: - raise StopIfGoalFound - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - try: - retworkx.graph_bfs_search(self.graph, [0], vis) - except StopIfGoalFound: - pass - self.assertEqual(vis.reconstruct_path(), [0, 1, 3]) - - def test_graph_prune_non_tree_edge(self): - class PruneNonTreeEdge(retworkx.visit.BFSVisitor): - def non_tree_edge(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneNonTreeEdge() - retworkx.graph_bfs_search(self.graph, [0], vis) - - def test_graph_prune_black_target_edge(self): - class PruneBlackTargetEdge(retworkx.visit.BFSVisitor): - def black_target_edge(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneBlackTargetEdge() - retworkx.graph_bfs_search(self.graph, [0], vis) - - def test_graph_prune_gray_target_edge(self): - class PruneGrayTargetEdge(retworkx.visit.BFSVisitor): - def gray_target_edge(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneGrayTargetEdge() - retworkx.graph_bfs_search(self.graph, [0], vis) diff --git a/tests/retworkx_backwards_compat/graph/test_biconnected.py b/tests/retworkx_backwards_compat/graph/test_biconnected.py deleted file mode 100644 index 1ab99ae56a..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_biconnected.py +++ /dev/null @@ -1,138 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestBiconnected(unittest.TestCase): - def setUp(self): - super().setUp() - self.graph = retworkx.PyGraph() - self.graph.extend_from_edge_list( - [ - # back edges - (0, 2), - (0, 3), - (1, 4), - (4, 9), - (5, 7), - # tree edges - (0, 1), - (1, 2), - (2, 3), - (2, 4), - (4, 5), - (4, 8), - (5, 6), - (6, 7), - (8, 9), - ] - ) - - self.barbell_graph = retworkx.PyGraph() - self.barbell_graph.extend_from_edge_list( - [ - (0, 1), - (0, 2), - (1, 2), - (3, 4), - (3, 5), - (4, 5), - (2, 3), - ] - ) - - def test_null_graph(self): - graph = retworkx.PyGraph() - self.assertEqual(retworkx.articulation_points(graph), set()) - self.assertEqual(retworkx.biconnected_components(graph), {}) - - def test_graph(self): - components = { - (4, 8): 0, - (8, 9): 0, - (9, 4): 0, - (5, 6): 1, - (6, 7): 1, - (7, 5): 1, - (4, 5): 2, - (0, 1): 3, - (1, 2): 3, - (2, 3): 3, - (2, 4): 3, - (2, 0): 3, - (3, 0): 3, - (4, 1): 3, - } - self.assertEqual(retworkx.biconnected_components(self.graph), components) - self.assertEqual(retworkx.articulation_points(self.graph), {4, 5}) - - def test_barbell_graph(self): - components = { - (0, 2): 2, - (2, 1): 2, - (1, 0): 2, - (3, 5): 0, - (5, 4): 0, - (4, 3): 0, - (2, 3): 1, - } - self.assertEqual(retworkx.biconnected_components(self.barbell_graph), components) - self.assertEqual(retworkx.articulation_points(self.barbell_graph), {2, 3}) - - def test_disconnected_graph(self): - graph = retworkx.union(self.barbell_graph, self.barbell_graph) - components = { - # first copy - (0, 2): 2, - (2, 1): 2, - (1, 0): 2, - (3, 5): 0, - (5, 4): 0, - (4, 3): 0, - (2, 3): 1, - # second copy - (6, 8): 5, - (8, 7): 5, - (7, 6): 5, - (9, 11): 3, - (11, 10): 3, - (10, 9): 3, - (8, 9): 4, - } - self.assertEqual(retworkx.biconnected_components(graph), components) - self.assertEqual(retworkx.articulation_points(graph), {2, 3, 8, 9}) - - def test_biconnected_graph(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [ - (0, 1), - (0, 2), - (0, 5), - (1, 5), - (2, 3), - (2, 4), - (3, 4), - (3, 5), - (3, 6), - (4, 5), - (4, 6), - ] - ) - num_edges = graph.num_edges() - self.assertEqual(retworkx.articulation_points(graph), set()) - bicomp = retworkx.biconnected_components(graph) - self.assertEqual(len(bicomp), num_edges) - self.assertEqual(list(bicomp.values()), [0] * num_edges) diff --git a/tests/retworkx_backwards_compat/graph/test_cartesian_product.py b/tests/retworkx_backwards_compat/graph/test_cartesian_product.py deleted file mode 100644 index 5acd0f35ce..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_cartesian_product.py +++ /dev/null @@ -1,60 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestCartesianProduct(unittest.TestCase): - def test_null_cartesian_null(self): - graph_1 = retworkx.PyGraph() - graph_2 = retworkx.PyGraph() - - graph_product, _ = retworkx.graph_cartesian_product(graph_1, graph_2) - self.assertEqual(graph_product.num_nodes(), 0) - self.assertEqual(graph_product.num_edges(), 0) - - def test_path_2_cartesian_path_2(self): - graph_1 = retworkx.generators.path_graph(2) - graph_2 = retworkx.generators.path_graph(2) - - graph_product, _ = retworkx.graph_cartesian_product(graph_1, graph_2) - self.assertEqual(graph_product.num_nodes(), 4) - self.assertEqual(graph_product.num_edges(), 4) - - def test_path_2_cartesian_path_3(self): - graph_1 = retworkx.generators.path_graph(2) - graph_2 = retworkx.generators.path_graph(3) - - graph_product, _ = retworkx.graph_cartesian_product(graph_1, graph_2) - self.assertEqual(graph_product.num_nodes(), 6) - self.assertEqual(graph_product.num_edges(), 7) - - def test_node_weights_cartesian(self): - graph_1 = retworkx.PyGraph() - graph_1.add_node("a_1") - graph_2 = retworkx.PyGraph() - graph_2.add_node(0) - - graph_product, _ = retworkx.graph_cartesian_product(graph_1, graph_2) - self.assertEqual([("a_1", 0)], graph_product.nodes()) - - def test_edge_weights_cartesian(self): - graph_1 = retworkx.PyGraph() - graph_1.add_nodes_from([0, 1]) - graph_1.add_edge(0, 1, "w_1") - graph_2 = retworkx.PyGraph() - graph_2.add_nodes_from([0, 1]) - graph_1.add_edge(0, 1, "w_2") - - graph_product, _ = retworkx.graph_cartesian_product(graph_1, graph_2) - self.assertEqual(["w_1", "w_1", "w_2", "w_2"], graph_product.edges()) diff --git a/tests/retworkx_backwards_compat/graph/test_centrality.py b/tests/retworkx_backwards_compat/graph/test_centrality.py deleted file mode 100644 index 2c0dabee89..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_centrality.py +++ /dev/null @@ -1,133 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import math -import unittest - -import retworkx - - -class TestCentralityGraph(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - self.d = self.graph.add_node("D") - edge_list = [ - (self.a, self.b, 1), - (self.b, self.c, 1), - (self.c, self.d, 1), - ] - self.graph.add_edges_from(edge_list) - - def test_betweenness_centrality(self): - betweenness = retworkx.graph_betweenness_centrality(self.graph) - expected = { - 0: 0.0, - 1: 0.6666666666666666, - 2: 0.6666666666666666, - 3: 0.0, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_endpoints(self): - betweenness = retworkx.graph_betweenness_centrality(self.graph, endpoints=True) - expected = { - 0: 0.5, - 1: 0.8333333333333333, - 2: 0.8333333333333333, - 3: 0.5, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_unnormalized(self): - betweenness = retworkx.graph_betweenness_centrality( - self.graph, endpoints=False, normalized=False - ) - expected = {0: 0.0, 1: 2.0, 2: 2.0, 3: 0.0} - self.assertEqual(expected, betweenness) - - def test_closeness_centrality(self): - closeness = retworkx.graph_closeness_centrality(self.graph) - expected = {0: 0.5, 1: 0.75, 2: 0.75, 3: 0.5} - self.assertEqual(expected, closeness) - - def test_closeness_centrality_wf_improved(self): - closeness = retworkx.graph_closeness_centrality(self.graph, wf_improved=False) - expected = {0: 0.5, 1: 0.75, 2: 0.75, 3: 0.5} - self.assertEqual(expected, closeness) - - -class TestCentralityGraphDeletedNode(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - c0 = self.graph.add_node("C0") - self.d = self.graph.add_node("D") - edge_list = [ - (self.a, self.b, 1), - (self.b, self.c, 1), - (self.c, self.d, 1), - ] - self.graph.add_edges_from(edge_list) - self.graph.remove_node(c0) - - def test_betweenness_centrality(self): - betweenness = retworkx.graph_betweenness_centrality(self.graph) - expected = { - 0: 0.0, - 1: 0.6666666666666666, - 2: 0.6666666666666666, - 4: 0.0, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_endpoints(self): - betweenness = retworkx.graph_betweenness_centrality(self.graph, endpoints=True) - expected = { - 0: 0.5, - 1: 0.8333333333333333, - 2: 0.8333333333333333, - 4: 0.5, - } - self.assertEqual(expected, betweenness) - - def test_betweenness_centrality_unnormalized(self): - betweenness = retworkx.graph_betweenness_centrality( - self.graph, endpoints=False, normalized=False - ) - expected = {0: 0.0, 1: 2.0, 2: 2.0, 4: 0.0} - self.assertEqual(expected, betweenness) - - -class TestEigenvectorCentrality(unittest.TestCase): - def test_complete_graph(self): - graph = retworkx.generators.mesh_graph(5) - centrality = retworkx.eigenvector_centrality(graph) - expected_value = math.sqrt(1.0 / 5.0) - for value in centrality.values(): - self.assertAlmostEqual(value, expected_value) - - def test_path_graph(self): - graph = retworkx.generators.path_graph(3) - centrality = retworkx.eigenvector_centrality(graph) - expected = [0.5, 0.7071, 0.5] - for k, v in centrality.items(): - self.assertAlmostEqual(v, expected[k], 4) - - def test_no_convergence(self): - graph = retworkx.PyGraph() - with self.assertRaises(retworkx.FailedToConverge): - retworkx.eigenvector_centrality(graph, max_iter=0) diff --git a/tests/retworkx_backwards_compat/graph/test_chain_decomposition.py b/tests/retworkx_backwards_compat/graph/test_chain_decomposition.py deleted file mode 100644 index f089163643..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_chain_decomposition.py +++ /dev/null @@ -1,89 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestChainDecomposition(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.graph.extend_from_edge_list( - [ - (0, 1), - (0, 2), - (1, 2), - (3, 4), - (3, 5), - (4, 5), - (2, 3), - ] - ) - return super().setUp() - - def test_graph(self): - edges = [ - # back edges - (0, 2), - (0, 3), - (1, 4), - (4, 9), - (5, 7), - # tree edges - (0, 1), - (1, 2), - (2, 3), - (2, 4), - (4, 5), - (4, 8), - (5, 6), - (6, 7), - (8, 9), - ] - - graph = retworkx.PyGraph() - graph.extend_from_edge_list(edges) - chains = retworkx.chain_decomposition(graph, source=0) - expected = [ - [(0, 3), (3, 2), (2, 1), (1, 0)], - [(0, 2)], - [(1, 4), (4, 2)], - [(4, 9), (9, 8), (8, 4)], - [(5, 7), (7, 6), (6, 5)], - ] - self.assertEqual(expected, chains) - - def test_barbell_graph(self): - chains = retworkx.chain_decomposition(self.graph, source=0) - expected = [[(0, 1), (1, 2), (2, 0)], [(3, 4), (4, 5), (5, 3)]] - self.assertEqual(expected, chains) - - def test_disconnected_graph(self): - graph = retworkx.union(self.graph, self.graph) - chains = retworkx.chain_decomposition(graph) - expected = [ - [(0, 1), (1, 2), (2, 0)], - [(3, 4), (4, 5), (5, 3)], - [(6, 7), (7, 8), (8, 6)], - [(9, 10), (10, 11), (11, 9)], - ] - self.assertEqual(expected, chains) - - def test_disconnected_graph_root_node(self): - graph = retworkx.union(self.graph, self.graph) - chains = retworkx.chain_decomposition(graph, source=0) - expected = [ - [(0, 1), (1, 2), (2, 0)], - [(3, 4), (4, 5), (5, 3)], - ] - self.assertEqual(expected, chains) diff --git a/tests/retworkx_backwards_compat/graph/test_coloring.py b/tests/retworkx_backwards_compat/graph/test_coloring.py deleted file mode 100644 index acc431f04c..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_coloring.py +++ /dev/null @@ -1,46 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestGraphColoring(unittest.TestCase): - def test_empty_graph(self): - graph = retworkx.PyGraph() - res = retworkx.graph_greedy_color(graph) - self.assertEqual({}, res) - - def test_simple_graph(self): - graph = retworkx.PyGraph() - node_a = graph.add_node(1) - node_b = graph.add_node(2) - graph.add_edge(node_a, node_b, 1) - node_c = graph.add_node(3) - graph.add_edge(node_a, node_c, 1) - res = retworkx.graph_greedy_color(graph) - self.assertEqual({0: 0, 1: 1, 2: 1}, res) - - def test_simple_graph_large_degree(self): - graph = retworkx.PyGraph() - node_a = graph.add_node(1) - node_b = graph.add_node(2) - graph.add_edge(node_a, node_b, 1) - node_c = graph.add_node(3) - graph.add_edge(node_a, node_c, 1) - graph.add_edge(node_a, node_c, 1) - graph.add_edge(node_a, node_c, 1) - graph.add_edge(node_a, node_c, 1) - graph.add_edge(node_a, node_c, 1) - res = retworkx.graph_greedy_color(graph) - self.assertEqual({0: 0, 1: 1, 2: 1}, res) diff --git a/tests/retworkx_backwards_compat/graph/test_complement.py b/tests/retworkx_backwards_compat/graph/test_complement.py deleted file mode 100644 index 6ae7962287..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_complement.py +++ /dev/null @@ -1,83 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestComplement(unittest.TestCase): - def test_clique(self): - N = 5 - graph = retworkx.PyGraph() - graph.extend_from_edge_list([(i, j) for i in range(N) for j in range(N) if i < j]) - - complement_graph = retworkx.complement(graph) - self.assertEqual(graph.nodes(), complement_graph.nodes()) - self.assertEqual(0, len(complement_graph.edges())) - - def test_empty(self): - N = 5 - graph = retworkx.PyGraph() - graph.add_nodes_from([i for i in range(N)]) - - expected_graph = retworkx.PyGraph() - expected_graph.extend_from_edge_list([(i, j) for i in range(N) for j in range(N) if i < j]) - - complement_graph = retworkx.complement(graph) - self.assertTrue( - retworkx.is_isomorphic( - expected_graph, - complement_graph, - ) - ) - - def test_null_graph(self): - graph = retworkx.PyGraph() - complement_graph = retworkx.complement(graph) - self.assertEqual(0, len(complement_graph.nodes())) - self.assertEqual(0, len(complement_graph.edges())) - - def test_complement(self): - N = 8 - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [(j, i) for i in range(N) for j in range(N) if i < j and (i + j) % 3 == 0] - ) - - expected_graph = retworkx.PyGraph() - expected_graph.extend_from_edge_list( - [(i, j) for i in range(N) for j in range(N) if i < j and (i + j) % 3 != 0] - ) - - complement_graph = retworkx.complement(graph) - self.assertTrue( - retworkx.is_isomorphic( - expected_graph, - complement_graph, - ) - ) - - def test_multigraph(self): - graph = retworkx.PyGraph(multigraph=True) - graph.extend_from_edge_list([(0, 0), (0, 1), (1, 1), (2, 2), (1, 0)]) - - expected_graph = retworkx.PyGraph(multigraph=True) - expected_graph.extend_from_edge_list([(0, 2), (1, 2)]) - - complement_graph = retworkx.complement(graph) - self.assertTrue( - retworkx.is_isomorphic( - expected_graph, - complement_graph, - ) - ) diff --git a/tests/retworkx_backwards_compat/graph/test_compose.py b/tests/retworkx_backwards_compat/graph/test_compose.py deleted file mode 100644 index 751309f24d..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_compose.py +++ /dev/null @@ -1,97 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCompose(unittest.TestCase): - def test_simple_graph_composition(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, {"a": 1}) - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, {"a": 2}) - graph_other = retworkx.PyGraph() - node_d = graph_other.add_node("d") - node_e = graph_other.add_node("e") - graph_other.add_edge(node_d, node_e, {"a": 3}) - res = graph.compose(graph_other, {node_c: (node_d, {"b": 1})}) - self.assertEqual({0: 3, 1: 4}, res) - self.assertEqual([0, 1, 2, 3, 4], graph.node_indexes()) - - def test_edge_map_and_node_map_funcs_graph_compose(self): - graph = retworkx.PyGraph() - original_input_nodes = graph.add_nodes_from(["qr[0]", "qr[1]"]) - original_op_nodes = graph.add_nodes_from(["h"]) - output_nodes = graph.add_nodes_from(["qr[0]", "qr[1]"]) - graph.add_edge(original_input_nodes[0], original_op_nodes[0], "qr[0]") - graph.add_edge(original_op_nodes[0], output_nodes[0], "qr[0]") - # Setup other graph - other_graph = retworkx.PyGraph() - input_nodes = other_graph.add_nodes_from(["qr[2]", "qr[3]"]) - op_nodes = other_graph.add_nodes_from(["cx"]) - other_output_nodes = other_graph.add_nodes_from(["qr[2]", "qr[3]"]) - other_graph.add_edges_from( - [ - (input_nodes[0], op_nodes[0], "qr[2]"), - (input_nodes[1], op_nodes[0], "qr[3]"), - ] - ) - other_graph.add_edges_from( - [ - (op_nodes[0], other_output_nodes[0], "qr[2]"), - (op_nodes[0], other_output_nodes[1], "qr[3]"), - ] - ) - - def map_fn(weight): - if weight == "qr[2]": - return "qr[0]" - elif weight == "qr[3]": - return "qr[1]" - else: - return weight - - graph.remove_nodes_from(output_nodes) - other_graph.remove_nodes_from(input_nodes) - node_map = { - original_op_nodes[0]: (op_nodes[0], "qr[0]"), - original_input_nodes[1]: (op_nodes[0], "qr[1]"), - } - res = graph.compose(other_graph, node_map, node_map_func=map_fn, edge_map_func=map_fn) - self.assertEqual({2: 4, 3: 3, 4: 5}, res) - self.assertEqual(graph[res[other_output_nodes[0]]], "qr[0]") - self.assertEqual(graph[res[other_output_nodes[1]]], "qr[1]") - # qr[0] -> h - self.assertTrue(graph.has_edge(0, 2)) - self.assertTrue(graph.get_all_edge_data(0, 2), ["qr[0]"]) - # qr[1] -> cx - self.assertTrue(graph.has_edge(1, 4)) - self.assertTrue(graph.get_all_edge_data(0, 2), ["qr[1]"]) - # h -> cx - self.assertTrue(graph.has_edge(2, 4)) - self.assertTrue(graph.get_all_edge_data(0, 2), ["qr[0]"]) - # cx -> qr[0] - self.assertTrue(graph.has_edge(4, 3)) - self.assertTrue(graph.get_all_edge_data(0, 2), ["qr[0]"]) - # cx -> qr[1] - self.assertTrue(graph.has_edge(4, 5)) - self.assertTrue(graph.get_all_edge_data(0, 2), ["qr[1]"]) - - def test_compose_digraph_onto_graph_error(self): - digraph = retworkx.PyDiGraph() - graph = retworkx.PyGraph() - with self.assertRaises(TypeError): - graph.compose(digraph, {}) diff --git a/tests/retworkx_backwards_compat/graph/test_connected_components.py b/tests/retworkx_backwards_compat/graph/test_connected_components.py deleted file mode 100644 index ecd7929be1..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_connected_components.py +++ /dev/null @@ -1,88 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestConnectedComponents(unittest.TestCase): - def test_number_connected(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(range(3)) - graph.add_edge(0, 1, None) - self.assertEqual(retworkx.number_connected_components(graph), 2) - - def test_number_connected_direct(self): - graph = retworkx.PyDiGraph() - graph.add_nodes_from(range(4)) - graph.add_edges_from_no_data([(3, 2), (2, 1), (1, 0)]) - self.assertEqual(len(retworkx.weakly_connected_components(graph)), 1) - - def test_number_connected_node_holes(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(range(3)) - graph.remove_node(1) - self.assertEqual(retworkx.number_connected_components(graph), 2) - - def test_connected_components(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4)] - ) - components = retworkx.connected_components(graph) - self.assertEqual([{0, 1, 2, 3}, {4, 5, 6, 7}], components) - - def test_node_connected_component(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4)] - ) - component = retworkx.node_connected_component(graph, 0) - self.assertEqual({0, 1, 2, 3}, component) - - def test_node_connected_component_invalid_node(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4)] - ) - with self.assertRaises(retworkx.InvalidNode): - retworkx.node_connected_component(graph, 10) - - def test_is_connected_false(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4)] - ) - self.assertFalse(retworkx.is_connected(graph)) - - def test_is_connected_true(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [ - (0, 1), - (1, 2), - (2, 3), - (3, 0), - (2, 4), - (4, 5), - (5, 6), - (6, 7), - (7, 4), - ] - ) - self.assertTrue(retworkx.is_connected(graph)) - - def test_is_connected_null_graph(self): - graph = retworkx.PyGraph() - with self.assertRaises(retworkx.NullGraph): - retworkx.is_connected(graph) diff --git a/tests/retworkx_backwards_compat/graph/test_contract_nodes.py b/tests/retworkx_backwards_compat/graph/test_contract_nodes.py deleted file mode 100644 index b43fe19c54..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_contract_nodes.py +++ /dev/null @@ -1,242 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class UndirectedEdge(tuple): - """An edge tuple wrapper for comparing expected edges with actual graph - edges where endpoint order doesn't matter (undirected). Supports both - edges and weighted edges. - - For example, the following become true: - ``UndirectedEdge((2, 3)) == UndirectedEdge((3, 2))`` - ``UndirectedEdge((4, 5, "a")) == UndirectedEdge((5, 4, "a"))`` - - """ - - def __eq__(self, o: object) -> bool: - return (frozenset(self[:2]), tuple(self[2:])) == ( - frozenset(o[:2]), - tuple(o[2:]), - ) - - def __hash__(self) -> int: - return hash((frozenset(self[:2]), tuple(self[2:]))) - - -class TestContractNodes(unittest.TestCase): - def test_empty_nodes(self): - """Replacing empty nodes is functionally equivalent to add_node.""" - dag = retworkx.PyGraph() - dag.contract_nodes([], "m") - - self.assertEqual(set(dag.nodes()), {"m"}) - - def test_unknown_nodes(self): - """ - Replacing all unknown nodes is functionally equivalent to add_node, - since unknown nodes should be ignored. - """ - dag = retworkx.PyGraph() - dag.contract_nodes([0, 1, 2], "m") - - self.assertEqual(set(dag.nodes()), {"m"}) - - def test_cycle_path_len_gt_1(self): - """ - ┌─┐ ┌─┐ - ┌4─┤a├─1┐ │m├──1───┐ - │ └─┘ │ └┬┘ │ - ┌┴┐ ┌┴┐ │ ┌┴┐ - │d│ │b│ ───► │ │b│ - └┬┘ └┬┘ │ └┬┘ - │ ┌─┐ 2 │ ┌─┐ 2 - └3─┤c├──┘ └3─┤c├──┘ - └─┘ └─┘ - """ - dag = retworkx.PyGraph() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - node_c = dag.add_node("c") - node_d = dag.add_node("d") - - dag.add_edge(node_a, node_b, 1) - dag.add_edge(node_b, node_c, 2) - dag.add_edge(node_c, node_d, 3) - dag.add_edge(node_a, node_d, 4) - - node_m = dag.contract_nodes([node_a, node_d], "m") - - self.assertEqual([node_b, node_c, node_m], dag.node_indexes()) - self.assertEqual( - { - UndirectedEdge((node_b, node_c)), - UndirectedEdge((node_c, node_m)), - UndirectedEdge((node_b, node_m)), - }, - set(UndirectedEdge(e) for e in dag.edge_list()), - ) - - def test_multiple_paths_would_cycle(self): - """ - ┌─┐ ┌─┐ ┌─┐ ┌─┐ - ┌3─┤c│ │e├─5┐ ┌──┤c│ │e├──┐ - │ └┬┘ └┬┘ │ │ └┬┘ └┬┘ │ - ┌┴┐ 2 ┌─┐ 4 ┌┴┐ │ 2 ┌─┐ 4 │ - │d│ └──┤b├──┘ │f│ ───► │ └──┤b├──┘ │ - └─┘ └┬┘ └─┘ 3 └┬┘ 5 - 1 │ 1 │ - ┌┴┐ │ ┌┴┐ │ - │a│ └──────┤m├──────┘ - └─┘ └─┘ - """ - dag = retworkx.PyGraph() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - node_c = dag.add_node("c") - node_d = dag.add_node("d") - node_e = dag.add_node("e") - node_f = dag.add_node("f") - - dag.add_edge(node_a, node_b, 1) - dag.add_edge(node_b, node_c, 2) - dag.add_edge(node_c, node_d, 3) - dag.add_edge(node_b, node_e, 4) - dag.add_edge(node_e, node_f, 5) - - node_m = dag.contract_nodes([node_a, node_d, node_f], "m") - - self.assertEqual([node_b, node_c, node_e, node_m], list(dag.node_indexes())) - self.assertEqual( - { - UndirectedEdge((node_b, node_c)), - UndirectedEdge((node_c, node_m)), - UndirectedEdge((node_e, node_m)), - UndirectedEdge((node_b, node_e)), - UndirectedEdge((node_b, node_m)), - }, - set(UndirectedEdge(e) for e in dag.edge_list()), - ) - - def test_replace_node_no_neighbors(self): - dag = retworkx.PyGraph() - node_a = dag.add_node("a") - node_m = dag.contract_nodes([node_a], "m") - self.assertEqual([node_m], dag.node_indexes()) - self.assertEqual(set(), set(dag.edge_list())) - - def test_keep_edges_multigraph(self): - """ - ┌─┐ ┌─┐ - ┌─┤a├─┐ ┌─┤a├─┐ - │ └─┘ │ │ └─┘ │ - 1 2 ──► 1 2 - ┌┴┐ ┌┴┐ │ ┌─┐ │ - │b│ │c│ └─┤m├─┘ - └─┘ └─┘ └─┘ - """ - dag = retworkx.PyGraph() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - node_c = dag.add_node("c") - - dag.add_edge(node_a, node_b, 1) - dag.add_edge(node_c, node_a, 2) - - node_m = dag.contract_nodes([node_b, node_c], "m") - self.assertEqual([node_a, node_m], dag.node_indexes()) - - # Note that target is *always* the new node (m). - self.assertEqual( - { - UndirectedEdge((node_a, node_m, 1)), - UndirectedEdge((node_a, node_m, 2)), - }, - set(UndirectedEdge(e) for e in dag.weighted_edge_list()), - ) - - -class TestContractNodesSimpleGraph(unittest.TestCase): - def setUp(self): - super().setUp() - self.dag = retworkx.PyGraph(multigraph=False) - self.node_a = self.dag.add_node("a") - self.node_b = self.dag.add_node("b") - self.node_c = self.dag.add_node("c") - self.node_d = self.dag.add_node("d") - self.node_e = self.dag.add_node("e") - - self.dag.add_edge(self.node_a, self.node_b, 1) - self.dag.add_edge(self.node_a, self.node_c, 2) - self.dag.add_edge(self.node_a, self.node_d, 3) - self.dag.add_edge(self.node_b, self.node_e, 4) - self.dag.add_edge(self.node_c, self.node_e, 5) - self.dag.add_edge(self.node_d, self.node_e, 6) - - def test_collapse_parallel_edges_no_combo_fn(self): - """ - Parallel edges are collapsed arbitrarily when weight_combo_fn is None. - ┌─┐ ┌─┐ - │a│ │a│ - ┌──┴┬┴──┐ └┬┘ - 1 2 3 1 or 2 or 3 - ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ - │b│ │c│ │d│ ──► │m│ - └┬┘ └┬┘ └┬┘ └┬┘ - 4 5 6 4 or 5 or 6 - └──┬┴┬──┘ ┌┴┐ - │e│ │e│ - └─┘ └─┘ - """ - self.dag.contract_nodes([self.node_b, self.node_c, self.node_d], "m") - - self.assertEqual(set(self.dag.nodes()), {"a", "e", "m"}) - self.assertEqual(len(self.dag.edges()), 2) - - # Should have one incoming edge, one outgoing - self.assertTrue(any(e in self.dag.edges() for e in {1, 2, 3})) - self.assertTrue(any(e in self.dag.edges() for e in {4, 5, 6})) - - def test_collapse_parallel_edges(self): - """ - Parallel edges are collapsed using weight_combo_fn. - ┌─┐ ┌─┐ - │a│ │a│ - ┌──┴┬┴──┐ └┬┘ - 1 2 3 6 - ┌┴┐ ┌┴┐ ┌┴┐ ┌┴┐ - │b│ │c│ │d│ ──► │m│ - └┬┘ └┬┘ └┬┘ └┬┘ - 4 5 6 15 - └──┬┴┬──┘ ┌┴┐ - │e│ │e│ - └─┘ └─┘ - """ - self.dag.contract_nodes( - [self.node_b, self.node_c, self.node_d], - "m", - weight_combo_fn=lambda w1, w2: w1 + w2, - ) - - self.assertEqual(set(self.dag.nodes()), {"a", "e", "m"}) - self.assertEqual(len(self.dag.edges()), 2) - - # Should have one incoming edge, one outgoing - self.assertEqual(set(self.dag.edges()), {6, 15}) - - def test_replace_all_nodes(self): - self.dag.contract_nodes(self.dag.node_indexes(), "m") - self.assertEqual(set(self.dag.nodes()), {"m"}) - self.assertFalse(self.dag.edges()) diff --git a/tests/retworkx_backwards_compat/graph/test_copy.py b/tests/retworkx_backwards_compat/graph/test_copy.py deleted file mode 100644 index 1a9aa9741d..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_copy.py +++ /dev/null @@ -1,55 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCopy(unittest.TestCase): - def test_copy_returns_graph(self): - graph_a = retworkx.PyGraph() - node_a = graph_a.add_node("a_1") - node_b = graph_a.add_node("a_2") - graph_a.add_edge(node_a, node_b, "edge_1") - node_c = graph_a.add_node("a_3") - graph_a.add_edge(node_b, node_c, "edge_2") - graph_b = graph_a.copy() - self.assertIsInstance(graph_b, retworkx.PyGraph) - - def test_copy_with_holes_returns_graph(self): - graph_a = retworkx.PyGraph() - node_a = graph_a.add_node("a_1") - node_b = graph_a.add_node("a_2") - graph_a.add_edge(node_a, node_b, "edge_1") - node_c = graph_a.add_node("a_3") - graph_a.add_edge(node_b, node_c, "edge_2") - graph_a.remove_node(node_b) - graph_b = graph_a.copy() - self.assertIsInstance(graph_b, retworkx.PyGraph) - self.assertEqual([node_a, node_c], graph_b.node_indexes()) - - def test_copy_empty(self): - graph = retworkx.PyGraph() - empty_copy = graph.copy() - self.assertEqual(len(empty_copy), 0) - - def test_copy_shared_ref(self): - graph_a = retworkx.PyGraph() - node_a = graph_a.add_node({"a": 1}) - node_b = graph_a.add_node({"b": 2}) - graph_a.add_edge(node_a, node_b, {"edge": 1}) - graph_b = graph_a.copy() - graph_a[0]["a"] = 42 - graph_b.get_edge_data(0, 1)["edge"] = 162 - self.assertEqual(graph_b[0]["a"], 42) - self.assertEqual(graph_a.get_edge_data(0, 1), {"edge": 162}) diff --git a/tests/retworkx_backwards_compat/graph/test_core_number.py b/tests/retworkx_backwards_compat/graph/test_core_number.py deleted file mode 100644 index 0ed4907b06..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_core_number.py +++ /dev/null @@ -1,96 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCoreNumber(unittest.TestCase): - def setUp(self): - # This is the example graph in Figure 1 from Batagelj and - # Zaversnik's paper titled An O(m) Algorithm for Cores - # Decomposition of Networks, 2003, - # http://arXiv.org/abs/cs/0310049. With nodes labeled as - # shown, the 3-core is given by nodes 0-7, the 2-core by nodes - # 8-15, the 1-core by nodes 16-19 and node 20 is in the - # 0-core. - self.example_edges = [ - (0, 2), - (0, 3), - (0, 5), - (1, 4), - (1, 6), - (1, 7), - (2, 3), - (3, 5), - (2, 5), - (5, 6), - (4, 6), - (4, 7), - (6, 7), - (5, 8), - (6, 8), - (6, 9), - (8, 9), - (0, 10), - (1, 10), - (1, 11), - (10, 11), - (12, 13), - (13, 15), - (14, 15), - (12, 14), - (8, 19), - (11, 16), - (11, 17), - (12, 18), - ] - - example_core = {} - for i in range(8): - example_core[i] = 3 - for i in range(8, 16): - example_core[i] = 2 - for i in range(16, 20): - example_core[i] = 1 - example_core[20] = 0 - self.example_core = example_core - - def test_undirected_empty(self): - graph = retworkx.PyGraph() - res = retworkx.core_number(graph) - self.assertIsInstance(res, dict) - self.assertEqual(res, {}) - - def test_undirected_all_0(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - res = retworkx.core_number(graph) - self.assertIsInstance(res, dict) - self.assertEqual(res, {0: 0, 1: 0, 2: 0, 3: 0}) - - def test_undirected_all_3(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from_no_data([(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]) - res = retworkx.core_number(graph) - self.assertIsInstance(res, dict) - self.assertEqual(res, {0: 3, 1: 3, 2: 3, 3: 3}) - - def test_undirected_paper_example(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(21))) - graph.add_edges_from_no_data(self.example_edges) - res = retworkx.core_number(graph) - self.assertIsInstance(res, dict) - self.assertEqual(res, self.example_core) diff --git a/tests/retworkx_backwards_compat/graph/test_cycle_basis.py b/tests/retworkx_backwards_compat/graph/test_cycle_basis.py deleted file mode 100644 index 13719bb2fb..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_cycle_basis.py +++ /dev/null @@ -1,69 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestCycleBasis(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.graph.add_nodes_from(list(range(10))) - self.graph.add_edges_from_no_data( - [ - (0, 1), - (0, 3), - (0, 5), - (0, 8), - (1, 2), - (1, 6), - (2, 3), - (3, 4), - (4, 5), - (6, 7), - (7, 8), - (8, 9), - ] - ) - - def test_cycle_basis(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(6))) - graph.add_edges_from_no_data([(0, 1), (0, 3), (0, 5), (1, 2), (2, 3), (3, 4), (4, 5)]) - res = sorted(sorted(c) for c in retworkx.cycle_basis(graph, 0)) - self.assertEqual([[0, 1, 2, 3], [0, 3, 4, 5]], res) - - def test_cycle_basis_multiple_roots_same_cycles(self): - res = sorted(sorted(x) for x in retworkx.cycle_basis(self.graph, 0)) - self.assertEqual(res, [[0, 1, 2, 3], [0, 1, 6, 7, 8], [0, 3, 4, 5]]) - res = sorted(sorted(x) for x in retworkx.cycle_basis(self.graph, 1)) - self.assertEqual(res, [[0, 1, 2, 3], [0, 1, 6, 7, 8], [0, 3, 4, 5]]) - res = sorted(sorted(x) for x in retworkx.cycle_basis(self.graph, 9)) - self.assertEqual(res, [[0, 1, 2, 3], [0, 1, 6, 7, 8], [0, 3, 4, 5]]) - - def test_cycle_basis_disconnected_graphs(self): - self.graph.add_nodes_from(["A", "B", "C"]) - self.graph.add_edges_from_no_data([(10, 11), (10, 12), (11, 12)]) - cycles = retworkx.cycle_basis(self.graph, 9) - res = sorted(sorted(x) for x in cycles[:-1]) + [sorted(cycles[-1])] - self.assertEqual(res, [[0, 1, 2, 3], [0, 1, 6, 7, 8], [0, 3, 4, 5], [10, 11, 12]]) - - def test_invalid_types(self): - digraph = retworkx.PyDiGraph() - with self.assertRaises(TypeError): - retworkx.cycle_basis(digraph) - - def test_self_loop(self): - self.graph.add_edge(1, 1, None) - res = sorted(sorted(c) for c in retworkx.cycle_basis(self.graph, 0)) - self.assertEqual([[0, 1, 2, 3], [0, 1, 6, 7, 8], [0, 3, 4, 5], [1]], res) diff --git a/tests/retworkx_backwards_compat/graph/test_deepcopy.py b/tests/retworkx_backwards_compat/graph/test_deepcopy.py deleted file mode 100644 index fcd87b1c62..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_deepcopy.py +++ /dev/null @@ -1,50 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import unittest - -import retworkx - - -class TestDeepcopy(unittest.TestCase): - def test_deepcopy_returns_graph(self): - dag_a = retworkx.PyGraph() - node_a = dag_a.add_node("a_1") - node_b = dag_a.add_node("a_2") - dag_a.add_edge(node_a, node_b, "edge_1") - node_c = dag_a.add_node("a_3") - dag_a.add_edge(node_b, node_c, "edge_2") - dag_b = copy.deepcopy(dag_a) - self.assertIsInstance(dag_b, retworkx.PyGraph) - - def test_deepcopy_with_holes_returns_graph(self): - dag_a = retworkx.PyGraph() - node_a = dag_a.add_node("a_1") - node_b = dag_a.add_node("a_2") - dag_a.add_edge(node_a, node_b, "edge_1") - node_c = dag_a.add_node("a_3") - dag_a.add_edge(node_b, node_c, "edge_2") - dag_a.remove_node(node_b) - dag_b = copy.deepcopy(dag_a) - self.assertIsInstance(dag_b, retworkx.PyGraph) - self.assertEqual([node_a, node_c], dag_b.node_indexes()) - - def test_deepcopy_empty(self): - dag = retworkx.PyGraph() - empty_copy = copy.deepcopy(dag) - self.assertEqual(len(empty_copy), 0) - - def test_deepcopy_attrs(self): - graph = retworkx.PyGraph(attrs="abc") - graph_copy = copy.deepcopy(graph) - self.assertEqual(graph.attrs, graph_copy.attrs) diff --git a/tests/retworkx_backwards_compat/graph/test_dfs_edges.py b/tests/retworkx_backwards_compat/graph/test_dfs_edges.py deleted file mode 100644 index 3903e45eef..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_dfs_edges.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDfsEdges(unittest.TestCase): - def test_graph_dfs_edges(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)]) - edges = retworkx.graph_dfs_edges(graph, 0) - expected = [(0, 1), (1, 2), (2, 4), (4, 3)] - self.assertEqual(expected, edges) - - def test_graph_disconnected_dfs_edges(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list([(0, 1), (2, 3)]) - edges = retworkx.graph_dfs_edges(graph) - expected = [(0, 1), (2, 3)] - self.assertEqual(expected, edges) diff --git a/tests/retworkx_backwards_compat/graph/test_dfs_search.py b/tests/retworkx_backwards_compat/graph/test_dfs_search.py deleted file mode 100644 index 0b03349a54..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_dfs_search.py +++ /dev/null @@ -1,106 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDfsSearch(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.graph.extend_from_edge_list( - [ - (0, 1), - (0, 2), - (1, 3), - (2, 1), - (2, 5), - (2, 6), - (5, 3), - (4, 7), - ] - ) - - def test_graph_dfs_tree_edges(self): - class TreeEdgesRecorder(retworkx.visit.DFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.graph_dfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 2), (2, 6), (2, 5), (5, 3), (3, 1)]) - - def test_graph_dfs_tree_edges_no_starting_point(self): - class TreeEdgesRecorder(retworkx.visit.DFSVisitor): - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - self.edges.append((edge[0], edge[1])) - - vis = TreeEdgesRecorder() - retworkx.graph_dfs_search(self.graph, None, vis) - self.assertEqual(vis.edges, [(0, 2), (2, 6), (2, 5), (5, 3), (3, 1), (4, 7)]) - - def test_graph_dfs_tree_edges_restricted(self): - class TreeEdgesRecorderRestricted(retworkx.visit.DFSVisitor): - - prohibited = [(0, 2), (1, 2)] - - def __init__(self): - self.edges = [] - - def tree_edge(self, edge): - edge = (edge[0], edge[1]) - if edge in self.prohibited: - raise retworkx.visit.PruneSearch - self.edges.append(edge) - - vis = TreeEdgesRecorderRestricted() - retworkx.graph_dfs_search(self.graph, [0], vis) - self.assertEqual(vis.edges, [(0, 1), (1, 3), (3, 5), (5, 2), (2, 6)]) - - def test_graph_dfs_goal_search(self): - class GoalSearch(retworkx.visit.DFSVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - - def tree_edge(self, edge): - u, v, _ = edge - self.parents[v] = u - - if v == self.goal: - raise retworkx.visit.StopSearch - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - try: - retworkx.graph_dfs_search(self.graph, [0], vis) - except retworkx.visit.StopSearch: - pass - self.assertEqual(vis.reconstruct_path(), [0, 2, 5, 3]) diff --git a/tests/retworkx_backwards_compat/graph/test_dijkstra.py b/tests/retworkx_backwards_compat/graph/test_dijkstra.py deleted file mode 100644 index 68b9f98eee..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_dijkstra.py +++ /dev/null @@ -1,238 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDijkstraGraph(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - self.d = self.graph.add_node("D") - self.e = self.graph.add_node("E") - self.f = self.graph.add_node("F") - self.graph.add_edge(self.a, self.b, 7) - self.graph.add_edge(self.c, self.a, 9) - self.graph.add_edge(self.a, self.d, 14) - self.graph.add_edge(self.b, self.c, 10) - self.graph.add_edge(self.d, self.c, 2) - self.graph.add_edge(self.d, self.e, 9) - self.graph.add_edge(self.b, self.f, 15) - self.graph.add_edge(self.c, self.f, 11) - self.graph.add_edge(self.e, self.f, 6) - - def test_dijkstra(self): - path = retworkx.graph_dijkstra_shortest_path_lengths( - self.graph, self.a, lambda x: float(x), self.e - ) - expected = {4: 20.0} - self.assertEqual(expected, path) - - def test_dijkstra_path(self): - path = retworkx.graph_dijkstra_shortest_paths( - self.graph, self.a, weight_fn=lambda x: float(x), target=self.e - ) - # a -> d -> e = 23 - # a -> c -> d -> e = 20 - expected = {4: [self.a, self.c, self.d, self.e]} - self.assertEqual(expected, path) - - def test_dijkstra_with_no_goal_set(self): - path = retworkx.graph_dijkstra_shortest_path_lengths(self.graph, self.a, lambda x: 1) - expected = {1: 1.0, 2: 1.0, 3: 1.0, 4: 2.0, 5: 2.0} - self.assertEqual(expected, path) - - def test_dijkstra_length_with_no_path(self): - g = retworkx.PyGraph() - a = g.add_node("A") - b = g.add_node("B") - path_lenghts = retworkx.graph_dijkstra_shortest_path_lengths( - g, a, edge_cost_fn=float, goal=b - ) - expected = {} - self.assertEqual(expected, path_lenghts) - - def test_dijkstra_path_with_no_goal_set(self): - path = retworkx.graph_dijkstra_shortest_paths(self.graph, self.a) - expected = { - 1: [0, 1], - 2: [0, 2], - 3: [0, 3], - 4: [0, 3, 4], - 5: [0, 1, 5], - } - self.assertEqual(expected, path) - - def test_dijkstra_with_no_path(self): - g = retworkx.PyGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.graph_dijkstra_shortest_path_lengths(g, a, lambda x: float(x)) - expected = {} - self.assertEqual(expected, path) - - def test_dijkstra_path_with_no_path(self): - g = retworkx.PyGraph() - a = g.add_node("A") - g.add_node("B") - path = retworkx.graph_dijkstra_shortest_paths(g, a, weight_fn=lambda x: float(x)) - expected = {} - self.assertEqual(expected, path) - - def test_dijkstra_with_disconnected_nodes(self): - g = retworkx.PyGraph() - a = g.add_node("A") - b = g.add_node("B") - g.add_edge(a, b, 1.2) - g.add_node("C") - d = g.add_node("D") - g.add_edge(b, d, 2.4) - path = retworkx.graph_dijkstra_shortest_path_lengths(g, a, lambda x: round(x, 1)) - # Computers never work: - expected = {1: 1.2, 3: 3.5999999999999996} - self.assertEqual(expected, path) - - def test_dijkstra_graph_with_digraph_input(self): - g = retworkx.PyDAG() - g.add_node(0) - with self.assertRaises(TypeError): - retworkx.graph_dijkstra_shortest_path_lengths(g, 0, lambda x: x) - - def test_dijkstra_all_pair_path_lengths(self): - lengths = retworkx.graph_all_pairs_dijkstra_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 9.0, 3: 11.0, 4: 20.0, 5: 20.0}, - 1: {0: 7.0, 2: 10.0, 3: 12.0, 4: 21.0, 5: 15.0}, - 2: {0: 9.0, 1: 10.0, 3: 2.0, 4: 11.0, 5: 11.0}, - 3: {0: 11.0, 1: 12.0, 2: 2.0, 4: 9.0, 5: 13.0}, - 4: {0: 20.0, 1: 21.0, 2: 11.0, 3: 9.0, 5: 6.0}, - 5: {0: 20.0, 1: 15.0, 2: 11.0, 3: 13.0, 4: 6.0}, - } - self.assertEqual(expected, lengths) - - def test_dijkstra_all_pair_paths(self): - paths = retworkx.graph_all_pairs_dijkstra_shortest_paths(self.graph, float) - expected = { - 0: { - 1: [0, 1], - 2: [0, 2], - 3: [0, 2, 3], - 4: [0, 2, 3, 4], - 5: [0, 2, 5], - }, - 1: {0: [1, 0], 2: [1, 2], 3: [1, 2, 3], 4: [1, 2, 3, 4], 5: [1, 5]}, - 2: {0: [2, 0], 1: [2, 1], 3: [2, 3], 4: [2, 3, 4], 5: [2, 5]}, - 3: {0: [3, 2, 0], 1: [3, 2, 1], 2: [3, 2], 4: [3, 4], 5: [3, 2, 5]}, - 4: { - 0: [4, 3, 2, 0], - 1: [4, 5, 1], - 2: [4, 3, 2], - 3: [4, 3], - 5: [4, 5], - }, - 5: {0: [5, 2, 0], 1: [5, 1], 2: [5, 2], 3: [5, 2, 3], 4: [5, 4]}, - } - self.assertEqual(expected, paths) - - def test_dijkstra_all_pair_path_lengths_with_node_removal(self): - self.graph.remove_node(3) - lengths = retworkx.graph_all_pairs_dijkstra_path_lengths(self.graph, float) - expected = { - 0: {1: 7.0, 2: 9.0, 4: 26.0, 5: 20.0}, - 1: {0: 7.0, 2: 10.0, 4: 21.0, 5: 15.0}, - 2: {0: 9.0, 1: 10.0, 4: 17.0, 5: 11.0}, - 4: {0: 26.0, 1: 21.0, 2: 17.0, 5: 6.0}, - 5: {0: 20.0, 1: 15.0, 2: 11.0, 4: 6.0}, - } - self.assertEqual(expected, lengths) - - def test_dijkstra_all_pair_paths_with_node_removal(self): - self.graph.remove_node(3) - paths = retworkx.graph_all_pairs_dijkstra_shortest_paths(self.graph, float) - expected = { - 0: {1: [0, 1], 2: [0, 2], 4: [0, 2, 5, 4], 5: [0, 2, 5]}, - 1: {0: [1, 0], 2: [1, 2], 4: [1, 5, 4], 5: [1, 5]}, - 2: {0: [2, 0], 1: [2, 1], 4: [2, 5, 4], 5: [2, 5]}, - 4: {0: [4, 5, 2, 0], 1: [4, 5, 1], 2: [4, 5, 2], 5: [4, 5]}, - 5: {0: [5, 2, 0], 1: [5, 1], 2: [5, 2], 4: [5, 4]}, - } - self.assertEqual(expected, paths) - - def test_dijkstra_all_pair_path_lengths_empty_graph(self): - graph = retworkx.PyGraph() - self.assertEqual({}, retworkx.graph_all_pairs_dijkstra_path_lengths(graph, float)) - - def test_dijkstra_all_pair_shortest_paths_empty_graph(self): - graph = retworkx.PyGraph() - self.assertEqual({}, retworkx.graph_all_pairs_dijkstra_shortest_paths(graph, float)) - - def test_dijkstra_all_pair_path_lengths_graph_no_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.graph_all_pairs_dijkstra_path_lengths(graph, float), - ) - - def test_dijkstra_all_pair_shortest_paths_no_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.graph_all_pairs_dijkstra_shortest_paths(graph, float), - ) - - def dijkstra_with_invalid_weights(self): - graph = retworkx.generators.path_graph(2) - for invalid_weight in [float("nan"), -1]: - for as_undirected in [False, True]: - with self.subTest(invalid_weight=invalid_weight, as_undirected=as_undirected): - with self.assertRaises(ValueError): - retworkx.graph_dijkstra_shortest_paths( - graph, - source=0, - weight_fn=lambda _: invalid_weight, - as_undirected=as_undirected, - ) - - def dijkstra_lengths_with_invalid_weights(self): - graph = retworkx.generators.path_graph(2) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.graph_dijkstra_shortest_path_lengths( - graph, node=0, edge_cost_fn=lambda _: invalid_weight - ) - - def all_pairs_dijkstra_with_invalid_weights(self): - graph = retworkx.generators.path_graph(2) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.graph_all_pairs_dijkstra_shortest_paths( - graph, edge_cost_fn=lambda _: invalid_weight - ) - - def all_pairs_dijkstra_lenghts_with_invalid_weights(self): - graph = retworkx.generators.path_graph(2) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.graph_all_pairs_dijkstra_path_lengths( - graph, edge_cost_fn=lambda _: invalid_weight - ) diff --git a/tests/retworkx_backwards_compat/graph/test_dijkstra_search.py b/tests/retworkx_backwards_compat/graph/test_dijkstra_search.py deleted file mode 100644 index aea0dc6d75..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_dijkstra_search.py +++ /dev/null @@ -1,189 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestDijkstraSearch(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.graph.extend_from_weighted_edge_list( - [ - (0, 1, 1), - (0, 2, 2), - (1, 3, 10), - (2, 1, 1), - (2, 5, 1), - (2, 6, 1), - (5, 3, 1), - (4, 7, 1), - ] - ) - - def test_graph_dijkstra_tree_edges(self): - class DijkstraTreeEdgesRecorder(retworkx.visit.DijkstraVisitor): - def __init__(self): - self.edges = [] - self.parents = dict() - - def discover_vertex(self, v, _): - u = self.parents.get(v, None) - if u is not None: - self.edges.append((u, v)) - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - vis = DijkstraTreeEdgesRecorder() - retworkx.graph_dijkstra_search(self.graph, [0], float, vis) - self.assertEqual(vis.edges, [(0, 1), (0, 2), (2, 6), (2, 5), (5, 3)]) - - def test_graph_dijkstra_tree_edges_no_starting_point(self): - class DijkstraTreeEdgesRecorder(retworkx.visit.DijkstraVisitor): - def __init__(self): - self.edges = [] - self.parents = dict() - - def discover_vertex(self, v, _): - u = self.parents.get(v, None) - if u is not None: - self.edges.append((u, v)) - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - vis = DijkstraTreeEdgesRecorder() - retworkx.graph_dijkstra_search(self.graph, None, float, vis) - self.assertEqual(vis.edges, [(0, 1), (0, 2), (2, 6), (2, 5), (5, 3), (4, 7)]) - - def test_graph_dijkstra_goal_search_with_stop_search_exception(self): - class GoalSearch(retworkx.visit.DijkstraVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - self.opt_goal_cost = None - - def discover_vertex(self, v, score): - if v == self.goal: - self.opt_goal_cost = score - raise retworkx.visit.StopSearch - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - retworkx.graph_dijkstra_search(self.graph, [0], float, vis) - self.assertEqual(vis.reconstruct_path(), [0, 2, 5, 3]) - self.assertEqual(vis.opt_goal_cost, 4.0) - - def test_graph_dijkstra_goal_search_with_custom_exception(self): - class StopIfGoalFound(Exception): - pass - - class GoalSearch(retworkx.visit.DijkstraVisitor): - - goal = 3 - - def __init__(self): - self.parents = {} - self.opt_goal_cost = None - - def discover_vertex(self, v, score): - if v == self.goal: - self.opt_goal_cost = score - raise StopIfGoalFound - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - try: - retworkx.graph_dijkstra_search(self.graph, [0], float, vis) - except StopIfGoalFound: - pass - self.assertEqual(vis.reconstruct_path(), [0, 2, 5, 3]) - self.assertEqual(vis.opt_goal_cost, 4.0) - - def test_graph_dijkstra_goal_search_with_prohibited_edges(self): - class GoalSearch(retworkx.visit.DijkstraVisitor): - - goal = 3 - prohibited = [(5, 3)] - - def __init__(self): - self.parents = {} - self.opt_goal_cost = None - - def discover_vertex(self, v, score): - if v == self.goal: - self.opt_goal_cost = score - raise retworkx.visit.StopSearch - - def examine_edge(self, edge): - u, v, _ = edge - if (u, v) in self.prohibited: - raise retworkx.visit.PruneSearch - - def edge_relaxed(self, edge): - u, v, _ = edge - self.parents[v] = u - - def reconstruct_path(self): - v = self.goal - path = [v] - while v in self.parents: - v = self.parents[v] - path.append(v) - - path.reverse() - return path - - vis = GoalSearch() - retworkx.graph_dijkstra_search(self.graph, [0], float, vis) - self.assertEqual(vis.reconstruct_path(), [0, 1, 3]) - self.assertEqual(vis.opt_goal_cost, 11.0) - - def test_graph_prune_edge_not_relaxed(self): - class PruneEdgeNotRelaxed(retworkx.visit.DijkstraVisitor): - def edge_not_relaxed(self, _): - raise retworkx.visit.PruneSearch - - vis = PruneEdgeNotRelaxed() - retworkx.graph_dijkstra_search(self.graph, [0], float, vis) diff --git a/tests/retworkx_backwards_compat/graph/test_dist_matrix.py b/tests/retworkx_backwards_compat/graph/test_dist_matrix.py deleted file mode 100644 index 1663125751..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_dist_matrix.py +++ /dev/null @@ -1,102 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import numpy as np - -import retworkx - - -class TestDistanceMatrix(unittest.TestCase): - def test_graph_distance_matrix(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.graph_distance_matrix(graph) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected)) - - def test_graph_distance_matrix_parallel(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.graph_distance_matrix(graph, parallel_threshold=5) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected)) - - def test_graph_distance_matrix_non_zero_null(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - graph.add_node(7) - dist = retworkx.graph_distance_matrix(graph, null_value=np.nan) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, np.nan], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0, np.nan], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0, np.nan], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0, np.nan], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0, np.nan], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0, np.nan], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0, np.nan], - [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 0.0], - ] - ) - self.assertTrue(np.array_equal(dist, expected, equal_nan=True)) - - def test_graph_distance_matrix_parallel_non_zero_null(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - graph.add_node(7) - dist = retworkx.graph_distance_matrix(graph, parallel_threshold=5, null_value=np.nan) - expected = np.array( - [ - [0.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, np.nan], - [1.0, 0.0, 1.0, 2.0, 3.0, 3.0, 2.0, np.nan], - [2.0, 1.0, 0.0, 1.0, 2.0, 3.0, 3.0, np.nan], - [3.0, 2.0, 1.0, 0.0, 1.0, 2.0, 3.0, np.nan], - [3.0, 3.0, 2.0, 1.0, 0.0, 1.0, 2.0, np.nan], - [2.0, 3.0, 3.0, 2.0, 1.0, 0.0, 1.0, np.nan], - [1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 0.0, np.nan], - [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 0.0], - ], - ) - self.assertTrue(np.array_equal(dist, expected, equal_nan=True)) - - def test_graph_distance_matrix_node_hole(self): - graph = retworkx.generators.path_graph(4) - graph.remove_node(0) - dist = retworkx.graph_distance_matrix(graph) - expected = np.array([[0.0, 1.0, 2.0], [1.0, 0.0, 1.0], [2.0, 1.0, 0.0]]) - self.assertTrue(np.array_equal(dist, expected)) diff --git a/tests/retworkx_backwards_compat/graph/test_dot.py b/tests/retworkx_backwards_compat/graph/test_dot.py deleted file mode 100644 index fafbbcd87e..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_dot.py +++ /dev/null @@ -1,130 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import tempfile -import unittest - -import retworkx - - -class TestDot(unittest.TestCase): - def setUp(self): - fd, self.path = tempfile.mkstemp() - os.close(fd) - os.remove(self.path) - - def test_graph_to_dot(self): - graph = retworkx.PyGraph() - graph.add_node( - { - "color": "black", - "fillcolor": "green", - "label": "a", - "style": "filled", - } - ) - graph.add_node( - { - "color": "black", - "fillcolor": "red", - "label": "a", - "style": "filled", - } - ) - graph.add_edge(0, 1, dict(label="1", name="1")) - expected = ( - 'graph {\n0 [color=black, fillcolor=green, label="a", style=filled' - '];\n1 [color=black, fillcolor=red, label="a", style=filled];' - '\n0 -- 1 [label="1", name=1];\n}\n' - ) - res = graph.to_dot(lambda node: node, lambda edge: edge) - self.assertEqual(expected, res) - - def test_digraph_to_dot(self): - graph = retworkx.PyDiGraph() - graph.add_node( - { - "color": "black", - "fillcolor": "green", - "label": "a", - "style": "filled", - } - ) - graph.add_node( - { - "color": "black", - "fillcolor": "red", - "label": "a", - "style": "filled", - } - ) - graph.add_edge(0, 1, dict(label="1", name="1")) - expected = ( - 'digraph {\n0 [color=black, fillcolor=green, label="a", ' - 'style=filled];\n1 [color=black, fillcolor=red, label="a", ' - 'style=filled];\n0 -> 1 [label="1", name=1];\n}\n' - ) - res = graph.to_dot(lambda node: node, lambda edge: edge) - self.assertEqual(expected, res) - - def test_graph_to_dot_to_file(self): - graph = retworkx.PyGraph() - graph.add_node( - { - "color": "black", - "fillcolor": "green", - "label": "a", - "style": "filled", - } - ) - graph.add_node( - { - "color": "black", - "fillcolor": "red", - "label": "a", - "style": "filled", - } - ) - graph.add_edge(0, 1, dict(label="1", name="1")) - expected = ( - 'graph {\n0 [color=black, fillcolor=green, label="a", ' - 'style=filled];\n1 [color=black, fillcolor=red, label="a", ' - 'style=filled];\n0 -- 1 [label="1", name=1];\n}\n' - ) - res = graph.to_dot(lambda node: node, lambda edge: edge, filename=self.path) - self.addCleanup(os.remove, self.path) - self.assertIsNone(res) - with open(self.path, "r") as fd: - res = fd.read() - self.assertEqual(expected, res) - - def test_graph_empty_dicts(self): - graph = retworkx.undirected_gnp_random_graph(3, 0.9, seed=42) - dot_str = graph.to_dot(lambda _: {}, lambda _: {}) - self.assertEqual( - "graph {\n0 ;\n1 ;\n2 ;\n1 -- 0 ;\n2 -- 0 ;\n" "2 -- 1 ;\n}\n", - dot_str, - ) - - def test_graph_graph_attrs(self): - graph = retworkx.undirected_gnp_random_graph(3, 0.9, seed=42) - dot_str = graph.to_dot(lambda _: {}, lambda _: {}, {"bgcolor": "red"}) - self.assertEqual( - "graph {\nbgcolor=red ;\n0 ;\n1 ;\n2 ;\n1 -- 0 ;\n" "2 -- 0 ;\n2 -- 1 ;\n}\n", - dot_str, - ) - - def test_graph_no_args(self): - graph = retworkx.undirected_gnp_random_graph(3, 0.95, seed=24) - dot_str = graph.to_dot() - self.assertEqual("graph {\n0 ;\n1 ;\n2 ;\n2 -- 0 ;\n2 -- 1 ;\n}\n", dot_str) diff --git a/tests/retworkx_backwards_compat/graph/test_edgelist.py b/tests/retworkx_backwards_compat/graph/test_edgelist.py deleted file mode 100644 index c6092a1733..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_edgelist.py +++ /dev/null @@ -1,209 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import tempfile -import unittest - -import retworkx - - -class TestEdgeList(unittest.TestCase): - def test_empty_edge_list_graph(self): - with tempfile.NamedTemporaryFile() as fd: - graph = retworkx.PyGraph.read_edge_list(fd.name) - self.assertEqual(graph.nodes(), []) - - def test_invalid_path_graph(self): - path = os.path.join(tempfile.gettempdir(), "fake_file_name.txt") - with self.assertRaises(FileNotFoundError): - retworkx.PyGraph.read_edge_list(path) - - def test_simple_example_graph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1\n") - fd.write("1 2\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list(fd.name) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertTrue(graph.has_edge(1, 0)) - self.assertTrue(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_blank_line_graph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1\n") - fd.write("\n") - fd.write("1 2\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list(fd.name) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertTrue(graph.has_edge(1, 0)) - self.assertTrue(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_comment_graph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1\n") - fd.write("1 2 # test comments\n") - fd.write("#2 3\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list(fd.name, comment="#") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertTrue(graph.has_edge(1, 0)) - self.assertTrue(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_comment_leading_space_graph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1\n") - fd.write("1 2 # test comments\n") - fd.write(" #2 3\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list(fd.name, comment="#") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertTrue(graph.has_edge(1, 0)) - self.assertTrue(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - - def test_weight_graph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0 1 0\n") - fd.write("1 2 1# test comments\n") - fd.write("#2 3\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list(fd.name, comment="#") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertTrue(graph.has_edge(1, 0)) - self.assertTrue(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1"]) - - def test_delim_graph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("0,1,0\n") - fd.write("1,2,1# test comments\n") - fd.write("#2,3\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list(fd.name, comment="#", deliminator=",") - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertTrue(graph.has_edge(1, 0)) - self.assertTrue(graph.has_edge(2, 1)) - self.assertFalse(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1"]) - - def test_labels_graph(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("a|b|0// test a comment\n") - fd.write("b|c|1\n") - fd.write("//c|d\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list( - fd.name, comment="//", deliminator="|", labels=True - ) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertFalse(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1"]) - - def test_labels_graph_target_existing(self): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write("a|b|0// test a comment\n") - fd.write("b|c|1\n") - fd.write("a|c\n") - fd.flush() - graph = retworkx.PyGraph.read_edge_list( - fd.name, comment="//", deliminator="|", labels=True - ) - self.assertEqual(graph.node_indexes(), [0, 1, 2]) - self.assertTrue(graph.has_edge(0, 1)) - self.assertTrue(graph.has_edge(1, 2)) - self.assertTrue(graph.has_edge(0, 2)) - self.assertEqual(graph.edges(), ["0", "1", None]) - - def test_write_edge_list_empty_digraph(self): - path = os.path.join(tempfile.gettempdir(), "empty.txt") - graph = retworkx.PyGraph() - graph.write_edge_list(path) - self.addCleanup(os.remove, path) - with open(path, "rt") as edge_file: - self.assertEqual("", edge_file.read()) - - def test_write_edge_list_round_trip(self): - path = os.path.join(tempfile.gettempdir(), "round_trip.txt") - graph = retworkx.generators.star_graph(5) - count = iter(range(5)) - - def weight_fn(edge): - return str(next(count)) - - graph.write_edge_list(path, weight_fn=weight_fn) - self.addCleanup(os.remove, path) - new_graph = retworkx.PyGraph.read_edge_list(path) - expected = [ - (0, 1, "0"), - (0, 2, "1"), - (0, 3, "2"), - (0, 4, "3"), - ] - self.assertEqual(expected, new_graph.weighted_edge_list()) - - def test_custom_delim(self): - path = os.path.join(tempfile.gettempdir(), "custom_delim.txt") - graph = retworkx.generators.path_graph(5) - graph.write_edge_list(path, deliminator=",") - self.addCleanup(os.remove, path) - expected = """0,1 -1,2 -2,3 -3,4 -""" - with open(path, "rt") as edge_file: - self.assertEqual(edge_file.read(), expected) - - def test_invalid_return_type_weight_fn(self): - path = os.path.join(tempfile.gettempdir(), "fail.txt") - graph = retworkx.undirected_gnm_random_graph(5, 4) - self.addCleanup(cleanup_file, path) - with self.assertRaises(TypeError): - graph.write_edge_list(path, weight_fn=lambda _: 4.5) - - def test_weight_fn_raises(self): - path = os.path.join(tempfile.gettempdir(), "fail.txt") - graph = retworkx.undirected_gnm_random_graph(5, 4) - - def weight_fn(edge): - raise KeyError - - self.addCleanup(cleanup_file, path) - with self.assertRaises(KeyError): - graph.write_edge_list(path, weight_fn=weight_fn) - - -def cleanup_file(path): - try: - os.remove(path) - except Exception: - pass diff --git a/tests/retworkx_backwards_compat/graph/test_edges.py b/tests/retworkx_backwards_compat/graph/test_edges.py deleted file mode 100644 index bcb7fd252a..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_edges.py +++ /dev/null @@ -1,819 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestEdges(unittest.TestCase): - def test_get_edge_data(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - res = graph.get_edge_data(node_a, node_b) - self.assertEqual("Edgy", res) - - def test_get_all_edge_data(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - graph.add_edge(node_a, node_b, "b") - res = graph.get_all_edge_data(node_a, node_b) - self.assertIn("b", res) - self.assertIn("Edgy", res) - - def test_no_edge(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.get_edge_data, node_a, node_b) - - def test_num_edges(self): - graph = retworkx.PyGraph() - graph.add_node(1) - graph.add_node(42) - graph.add_node(146) - graph.add_edges_from_no_data([(0, 1), (1, 2)]) - self.assertEqual(2, graph.num_edges()) - - def test_num_edges_no_edges(self): - graph = retworkx.PyGraph() - graph.add_node(1) - graph.add_node(42) - self.assertEqual(0, graph.num_edges()) - - def test_update_edge(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "not edgy") - graph.update_edge(node_a, node_b, "Edgy") - self.assertEqual([(0, 1, "Edgy")], graph.weighted_edge_list()) - - def test_update_edge_no_edge(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.update_edge, node_a, node_b, None) - - def test_update_edge_by_index(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - edge_index = graph.add_edge(node_a, node_b, "not edgy") - graph.update_edge_by_index(edge_index, "Edgy") - self.assertEqual([(0, 1, "Edgy")], graph.weighted_edge_list()) - - def test_update_edge_invalid_index(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - self.assertRaises(IndexError, graph.update_edge_by_index, 0, None) - - def test_update_edge_parallel_edges(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "not edgy") - edge_index = graph.add_edge(node_a, node_b, "not edgy") - graph.update_edge_by_index(edge_index, "Edgy") - self.assertEqual( - [(0, 1, "not edgy"), (0, 1, "Edgy")], - list(graph.weighted_edge_list()), - ) - - def test_no_edge_get_all_edge_data(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.get_all_edge_data, node_a, node_b) - - def test_has_edge(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, {}) - self.assertTrue(graph.has_edge(node_a, node_b)) - self.assertTrue(graph.has_edge(node_b, node_a)) - - def test_has_edge_no_edge(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertFalse(graph.has_edge(node_a, node_b)) - - def test_edges(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Super edgy") - self.assertEqual(["Edgy", "Super edgy"], graph.edges()) - - def test_edges_empty(self): - graph = retworkx.PyGraph() - graph.add_node("a") - self.assertEqual([], graph.edges()) - - def test_edge_indices(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Super edgy") - self.assertEqual([0, 1], graph.edge_indices()) - - def test_get_edge_indices_empty(self): - graph = retworkx.PyGraph() - graph.add_node("a") - self.assertEqual([], graph.edge_indices()) - - def test_add_duplicates(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("a") - graph.add_edge(node_a, node_b, "a") - graph.add_edge(node_a, node_b, "b") - self.assertEqual(["a", "b"], graph.edges()) - - def test_remove_no_edge(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.remove_edge, node_a, node_b) - - def test_remove_edge_single(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.remove_edge(node_a, node_b) - self.assertEqual([], graph.edges()) - - def test_remove_multiple(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.add_edge(node_a, node_b, "super_edgy") - graph.remove_edge_from_index(0) - self.assertEqual(["super_edgy"], graph.edges()) - - def test_remove_edge_from_index(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_remove_edge_no_edge(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_remove_edges_from(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - node_c = graph.add_node("c") - graph.add_edge(node_a, node_b, "edgy") - graph.add_edge(node_a, node_c, "super_edgy") - graph.remove_edges_from([(node_a, node_b), (node_a, node_c)]) - self.assertEqual([], graph.edges()) - - def test_remove_edges_from_invalid(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - node_c = graph.add_node("c") - graph.add_edge(node_a, node_b, "edgy") - graph.add_edge(node_a, node_c, "super_edgy") - with self.assertRaises(retworkx.NoEdgeBetweenNodes): - graph.remove_edges_from([(node_b, node_c), (node_a, node_c)]) - - def test_degree(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Super edgy") - self.assertEqual(2, graph.degree(node_b)) - - def test_degree_with_self_loops(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list([(0, 0), (0, 1), (0, 0)]) - self.assertEqual(5, graph.degree(0)) - - def test_add_edge_from(self): - graph = retworkx.PyGraph() - nodes = list(range(4)) - graph.add_nodes_from(nodes) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - res = graph.add_edges_from(edge_list) - self.assertEqual(len(res), 5) - self.assertEqual(["a", "b", "c", "d", "e"], graph.edges()) - self.assertEqual(3, graph.degree(0)) - self.assertEqual(2, graph.degree(1)) - self.assertEqual(3, graph.degree(2)) - self.assertEqual(2, graph.degree(3)) - - def test_add_edge_from_empty(self): - graph = retworkx.PyGraph() - res = graph.add_edges_from([]) - self.assertEqual([], res) - - def test_add_edge_from_no_data(self): - graph = retworkx.PyGraph() - nodes = list(range(4)) - graph.add_nodes_from(nodes) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - res = graph.add_edges_from_no_data(edge_list) - self.assertEqual(len(res), 5) - self.assertEqual([None, None, None, None, None], graph.edges()) - self.assertEqual(3, graph.degree(0)) - self.assertEqual(2, graph.degree(1)) - self.assertEqual(3, graph.degree(2)) - self.assertEqual(2, graph.degree(3)) - - def test_add_edge_from_empty_no_data(self): - graph = retworkx.PyGraph() - res = graph.add_edges_from_no_data([]) - self.assertEqual([], res) - - def test_extend_from_weighted_edge_list_empty(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list([]) - self.assertEqual(0, len(graph)) - - def test_extend_from_weighted_edge_list_nodes_exist(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["a", "b", "c", "d", "e"], graph.edges()) - - def test_extend_from_weighted_edge_list_edges_exist(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - (0, 1, "not_a"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["a", "b", "c", "d", "e", "not_a"], graph.edges()) - - def test_edge_list(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.add_edges_from(edge_list) - self.assertEqual([(x[0], x[1]) for x in edge_list], graph.edge_list()) - - def test_edge_list_empty(self): - graph = retworkx.PyGraph() - self.assertEqual([], graph.edge_list()) - - def test_weighted_edge_list(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.add_edges_from(edge_list) - self.assertEqual(edge_list, graph.weighted_edge_list()) - - def test_weighted_edge_list_empty(self): - graph = retworkx.PyGraph() - self.assertEqual([], graph.weighted_edge_list()) - - def test_extend_from_edge_list(self): - graph = retworkx.PyGraph() - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 5, graph.edges()) - self.assertEqual(3, graph.degree(0)) - self.assertEqual(2, graph.degree(1)) - self.assertEqual(3, graph.degree(2)) - self.assertEqual(2, graph.degree(3)) - - def test_extend_from_edge_list_empty(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list([]) - self.assertEqual(0, len(graph)) - - def test_extend_from_edge_list_nodes_exist(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 5, graph.edges()) - self.assertEqual(3, graph.degree(0)) - self.assertEqual(2, graph.degree(1)) - self.assertEqual(3, graph.degree(2)) - self.assertEqual(2, graph.degree(3)) - - def test_extend_from_edge_list_existing_edge(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3), (0, 1)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 6, graph.edges()) - - def test_extend_from_weighted_edge_list(self): - graph = retworkx.PyGraph() - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - - def test_add_edges_from_parallel_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from([0, 1]) - res = graph.add_edges_from([(0, 1, False), (1, 0, True)]) - self.assertEqual([0, 1], res) - self.assertEqual([False, True], graph.edges()) - - def test_add_edges_from_no_data_parallel_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from([0, 1]) - res = graph.add_edges_from_no_data([(0, 1), (1, 0)]) - self.assertEqual([0, 1], res) - self.assertEqual([None, None], graph.edges()) - - def test_multigraph_attr(self): - graph = retworkx.PyGraph() - self.assertTrue(graph.multigraph) - - def test_has_parallel_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from([0, 1]) - graph.add_edge(0, 1, None) - graph.add_edge(1, 0, 0) - self.assertTrue(graph.has_parallel_edges()) - - def test_has_parallel_edges_no_parallel_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from([0, 1]) - graph.add_edge(0, 1, None) - self.assertFalse(graph.has_parallel_edges()) - - def test_has_parallel_edges_empty(self): - graph = retworkx.PyGraph() - self.assertFalse(graph.has_parallel_edges()) - - def test_edge_index_map(self): - graph = retworkx.PyGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_node("c") - node_d = graph.add_node("d") - graph.add_edge(node_a, node_c, "edge a") - graph.add_edge(node_b, node_d, "edge_b") - graph.add_edge(node_c, node_d, "edge c") - self.assertEqual( - { - 0: (node_a, node_c, "edge a"), - 1: (node_b, node_d, "edge_b"), - 2: (node_c, node_d, "edge c"), - }, - graph.edge_index_map(), - ) - - def test_incident_edges(self): - graph = retworkx.PyGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_node("c") - node_d = graph.add_node("d") - graph.add_edge(node_a, node_c, "edge a") - graph.add_edge(node_b, node_d, "edge_b") - graph.add_edge(node_c, node_d, "edge c") - res = graph.incident_edges(node_d) - self.assertEqual({1, 2}, set(res)) - - def test_incident_edges_invalid_node(self): - graph = retworkx.PyGraph() - res = graph.incident_edges(42) - self.assertEqual([], res) - - def test_incident_edge_index_map(self): - graph = retworkx.PyGraph() - node_a = graph.add_node(0) - node_b = graph.add_node(1) - node_c = graph.add_node("c") - node_d = graph.add_node("d") - graph.add_edge(node_a, node_c, "edge a") - graph.add_edge(node_b, node_d, "edge_b") - graph.add_edge(node_c, node_d, "edge c") - res = graph.incident_edge_index_map(node_d) - self.assertEqual({2: (3, 2, "edge c"), 1: (3, 1, "edge_b")}, res) - - def test_incident_edge_index_map_invalid_node(self): - graph = retworkx.PyGraph() - res = graph.incident_edge_index_map(42) - self.assertEqual({}, res) - - def test_single_neighbor_out_edges(self): - g = retworkx.PyGraph() - node_a = g.add_node("a") - node_b = g.add_node("b") - g.add_edge(node_a, node_b, {"a": 1}) - node_c = g.add_node("c") - g.add_edge(node_a, node_c, {"a": 2}) - res = g.out_edges(node_a) - self.assertEqual([(node_a, node_c, {"a": 2}), (node_a, node_b, {"a": 1})], res) - - def test_neighbor_surrounded_in_out_edges(self): - g = retworkx.PyGraph() - node_a = g.add_node("a") - node_b = g.add_node("b") - node_c = g.add_node("c") - g.add_edge(node_a, node_b, {"a": 1}) - g.add_edge(node_b, node_c, {"a": 2}) - res = g.out_edges(node_b) - self.assertEqual([(node_b, node_c, {"a": 2}), (node_b, node_a, {"a": 1})], res) - res = g.in_edges(node_b) - self.assertEqual([(node_c, node_b, {"a": 2}), (node_a, node_b, {"a": 1})], res) - - def test_edge_index_map_empty(self): - graph = retworkx.PyGraph() - self.assertEqual({}, graph.edge_index_map()) - - def test_get_edge_data_by_index(self): - graph = retworkx.PyGraph() - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - res = graph.get_edge_data_by_index(2) - self.assertEqual("c", res) - - def test_get_edge_data_by_index_invalid_index(self): - graph = retworkx.PyGraph() - with self.assertRaisesRegex( - IndexError, "Provided edge index 2 is not present in the graph" - ): - graph.get_edge_data_by_index(2) - - def test_get_edge_endpoints_by_index(self): - graph = retworkx.PyGraph() - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - res = graph.get_edge_endpoints_by_index(2) - self.assertEqual((0, 2), res) - - def test_get_edge_endpoints_by_index_invalid_index(self): - graph = retworkx.PyGraph() - with self.assertRaisesRegex( - IndexError, "Provided edge index 2 is not present in the graph" - ): - graph.get_edge_endpoints_by_index(2) - - -class TestEdgesMultigraphFalse(unittest.TestCase): - def test_multigraph_attr(self): - graph = retworkx.PyGraph(multigraph=False) - self.assertFalse(graph.multigraph) - - def test_has_parallel_edges(self): - graph = retworkx.PyGraph(multigraph=False) - graph.add_nodes_from([0, 1]) - graph.add_edge(0, 1, None) - graph.add_edge(1, 0, 0) - self.assertFalse(graph.has_parallel_edges()) - - def test_parallel_edges_not_in_edge_list(self): - graph = retworkx.PyGraph(multigraph=False) - edge_list = [ - (8, 6), - (6, 5), - (6, 5), - (4, 5), - (5, 4), - (4, 5), - (3, 4), - (4, 3), - (3, 4), - (2, 3), - (0, 2), - (2, 0), - (0, 2), - (2, 3), - ] - graph.extend_from_edge_list(edge_list) - graph_edge_list = graph.edge_list() - expected_edges = [(6, 8), (5, 6), (4, 5), (3, 4), (2, 3), (0, 2)] - self.assertEqual(len(graph_edge_list), len(expected_edges)) - for edge in expected_edges: - if edge not in graph_edge_list and (edge[1], edge[0]) not in graph_edge_list: - self.fail(f"{edge} not found in graph edge list {graph_edge_list}") - - def test_get_edge_data(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - res = graph.get_edge_data(node_a, node_b) - self.assertEqual("Edgy", res) - - def test_get_all_edge_data(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - graph.add_edge(node_a, node_b, "b") - res = graph.get_all_edge_data(node_a, node_b) - self.assertIn("b", res) - self.assertNotIn("Edgy", res) - - def test_no_edge(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.get_edge_data, node_a, node_b) - - def test_no_edge_get_all_edge_data(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.get_all_edge_data, node_a, node_b) - - def test_has_edge(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, {}) - self.assertTrue(graph.has_edge(node_a, node_b)) - self.assertTrue(graph.has_edge(node_b, node_a)) - - def test_has_edge_no_edge(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertFalse(graph.has_edge(node_a, node_b)) - - def test_edges(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Super edgy") - self.assertEqual(["Edgy", "Super edgy"], graph.edges()) - - def test_edges_empty(self): - graph = retworkx.PyGraph(False) - graph.add_node("a") - self.assertEqual([], graph.edges()) - - def test_add_duplicates(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("a") - graph.add_edge(node_a, node_b, "a") - graph.add_edge(node_a, node_b, "b") - self.assertEqual(["b"], graph.edges()) - - def test_remove_no_edge(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - self.assertRaises(retworkx.NoEdgeBetweenNodes, graph.remove_edge, node_a, node_b) - - def test_remove_edge_single(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.remove_edge(node_a, node_b) - self.assertEqual([], graph.edges()) - - def test_remove_multiple(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.add_edge(node_a, node_b, "super_edgy") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_remove_edge_from_index(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "edgy") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_remove_edge_no_edge(self): - graph = retworkx.PyGraph(False) - graph.add_node("a") - graph.remove_edge_from_index(0) - self.assertEqual([], graph.edges()) - - def test_degree(self): - graph = retworkx.PyGraph(False) - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Super edgy") - self.assertEqual(2, graph.degree(node_b)) - - def test_add_edge_from(self): - graph = retworkx.PyGraph(False) - nodes = list(range(4)) - graph.add_nodes_from(nodes) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - res = graph.add_edges_from(edge_list) - self.assertEqual(len(res), 5) - self.assertEqual(["a", "b", "c", "d", "e"], graph.edges()) - self.assertEqual(3, graph.degree(0)) - self.assertEqual(2, graph.degree(1)) - self.assertEqual(3, graph.degree(2)) - self.assertEqual(2, graph.degree(3)) - - def test_add_edge_from_empty(self): - graph = retworkx.PyGraph(False) - res = graph.add_edges_from([]) - self.assertEqual([], res) - - def test_add_edge_from_no_data(self): - graph = retworkx.PyGraph(False) - nodes = list(range(4)) - graph.add_nodes_from(nodes) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - res = graph.add_edges_from_no_data(edge_list) - self.assertEqual(len(res), 5) - self.assertEqual([None, None, None, None, None], graph.edges()) - self.assertEqual(3, graph.degree(0)) - self.assertEqual(2, graph.degree(1)) - self.assertEqual(3, graph.degree(2)) - self.assertEqual(2, graph.degree(3)) - - def test_add_edge_from_empty_no_data(self): - graph = retworkx.PyGraph(False) - res = graph.add_edges_from_no_data([]) - self.assertEqual([], res) - - def test_add_edges_from_parallel_edges(self): - graph = retworkx.PyGraph(False) - graph.add_nodes_from([0, 1]) - res = graph.add_edges_from([(0, 1, False), (1, 0, True)]) - self.assertEqual([0, 0], res) - self.assertEqual([True], graph.edges()) - - def test_add_edges_from_no_data_parallel_edges(self): - graph = retworkx.PyGraph(False) - graph.add_nodes_from([0, 1]) - res = graph.add_edges_from_no_data([(0, 1), (1, 0)]) - self.assertEqual([0, 0], res) - self.assertEqual([None], graph.edges()) - - def test_extend_from_weighted_edge_list_empty(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list([]) - self.assertEqual(0, len(graph)) - - def test_extend_from_weighted_edge_list_nodes_exist(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["a", "b", "c", "d", "e"], graph.edges()) - - def test_extend_from_weighted_edge_list_edges_exist(self): - graph = retworkx.PyGraph(False) - graph.add_nodes_from(list(range(4))) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - (0, 1, "not_a"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["not_a", "b", "c", "d", "e"], graph.edges()) - - def test_extend_from_edge_list(self): - graph = retworkx.PyGraph(False) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 5, graph.edges()) - - def test_extend_from_edge_list_empty(self): - graph = retworkx.PyGraph(False) - graph.extend_from_edge_list([]) - self.assertEqual(0, len(graph)) - - def test_extend_from_edge_list_nodes_exist(self): - graph = retworkx.PyGraph(False) - graph.add_nodes_from(list(range(4))) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 5, graph.edges()) - self.assertEqual(3, graph.degree(0)) - self.assertEqual(2, graph.degree(1)) - self.assertEqual(3, graph.degree(2)) - self.assertEqual(2, graph.degree(3)) - - def test_extend_from_edge_list_existing_edge(self): - graph = retworkx.PyGraph(False) - graph.add_nodes_from(list(range(4))) - edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3), (0, 1)] - graph.extend_from_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual([None] * 5, graph.edges()) - - def test_extend_from_weighted_edge_list(self): - graph = retworkx.PyGraph(False) - edge_list = [ - (0, 1, "a"), - (1, 2, "b"), - (0, 2, "c"), - (2, 3, "d"), - (0, 3, "e"), - ] - graph.extend_from_weighted_edge_list(edge_list) - self.assertEqual(len(graph), 4) - self.assertEqual(["a", "b", "c", "d", "e"], graph.edges()) diff --git a/tests/retworkx_backwards_compat/graph/test_floyd_warshall.py b/tests/retworkx_backwards_compat/graph/test_floyd_warshall.py deleted file mode 100644 index a7fc4452e6..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_floyd_warshall.py +++ /dev/null @@ -1,201 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import numpy - -import retworkx - - -class TestFloydWarshall(unittest.TestCase): - parallel_threshold = 300 - - def test_vs_dijkstra_all_pairs(self): - graph = retworkx.PyGraph() - a = graph.add_node("A") - b = graph.add_node("B") - c = graph.add_node("C") - d = graph.add_node("D") - e = graph.add_node("E") - f = graph.add_node("F") - edge_list = [ - (a, b, 7), - (c, a, 9), - (a, d, 14), - (b, c, 10), - (d, c, 2), - (d, e, 9), - (b, f, 15), - (c, f, 11), - (e, f, 6), - ] - graph.add_edges_from(edge_list) - - dijkstra_lengths = retworkx.graph_all_pairs_dijkstra_path_lengths(graph, float) - - expected = {k: {**v, k: 0.0} for k, v in dijkstra_lengths.items()} - - result = retworkx.graph_floyd_warshall( - graph, float, parallel_threshold=self.parallel_threshold - ) - - self.assertEqual(result, expected) - - def test_vs_dijkstra_all_pairs_with_node_removal(self): - graph = retworkx.PyGraph() - a = graph.add_node("A") - b = graph.add_node("B") - c = graph.add_node("C") - d = graph.add_node("D") - e = graph.add_node("E") - f = graph.add_node("F") - edge_list = [ - (a, b, 7), - (c, a, 9), - (a, d, 14), - (b, c, 10), - (d, c, 2), - (d, e, 9), - (b, f, 15), - (c, f, 11), - (e, f, 6), - ] - graph.add_edges_from(edge_list) - graph.remove_node(d) - - dijkstra_lengths = retworkx.graph_all_pairs_dijkstra_path_lengths(graph, float) - - expected = {k: {**v, k: 0.0} for k, v in dijkstra_lengths.items()} - - result = retworkx.graph_floyd_warshall( - graph, float, parallel_threshold=self.parallel_threshold - ) - - self.assertEqual(result, expected) - - def test_floyd_warshall_empty_graph(self): - graph = retworkx.PyGraph() - self.assertEqual({}, retworkx.graph_floyd_warshall(graph, float)) - - def test_floyd_warshall_graph_no_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(1000))) - expected = {x: {} for x in range(1000)} - self.assertEqual( - expected, - retworkx.graph_floyd_warshall(graph, float), - ) - - def test_floyd_warshall_numpy_three_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(6))) - weights = [2, 12, 1, 5, 1] - graph.add_edges_from([(i, i + 1, weights[i]) for i in range(5)]) - graph.add_edge(5, 0, 10) - dist = retworkx.graph_floyd_warshall_numpy( - graph, lambda x: x, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 15) - self.assertEqual(dist[3, 0], 15) - - def test_weighted_numpy_two_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(8))) - graph.add_edges_from( - [ - (0, 1, 2), - (1, 2, 2), - (2, 3, 1), - (3, 4, 1), - (4, 5, 1), - (5, 6, 1), - (6, 7, 1), - (7, 0, 1), - ] - ) - dist = retworkx.graph_floyd_warshall_numpy( - graph, lambda x: x, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 2], 4) - self.assertEqual(dist[2, 0], 4) - - def test_weighted_numpy_negative_cycle(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.add_edges_from( - [ - (0, 1, 1), - (1, 2, -1), - (2, 3, -1), - (3, 0, -1), - ] - ) - dist = retworkx.graph_floyd_warshall_numpy( - graph, lambda x: x, parallel_threshold=self.parallel_threshold - ) - self.assertTrue(numpy.all(numpy.diag(dist) < 0)) - - def test_floyd_warshall_numpy_cycle(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - dist = retworkx.graph_floyd_warshall_numpy( - graph, lambda x: 1, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 3) - self.assertEqual(dist[0, 4], 3) - - def test_numpy_no_edges(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - dist = retworkx.graph_floyd_warshall_numpy( - graph, lambda x: x, parallel_threshold=self.parallel_threshold - ) - expected = numpy.full((4, 4), numpy.inf) - numpy.fill_diagonal(expected, 0) - self.assertTrue(numpy.array_equal(dist, expected)) - - def test_floyd_warshall_numpy_graph_cycle_with_removals(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(8))) - graph.remove_node(0) - graph.add_edges_from_no_data([(1, 2), (1, 7), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]) - dist = retworkx.graph_floyd_warshall_numpy( - graph, lambda x: 1, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 3) - self.assertEqual(dist[0, 4], 3) - - def test_floyd_warshall_numpy_graph_cycle_no_weight_fn(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(8))) - graph.remove_node(0) - graph.add_edges_from_no_data([(1, 2), (1, 7), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]) - dist = retworkx.graph_floyd_warshall_numpy(graph) - self.assertEqual(dist[0, 3], 3) - self.assertEqual(dist[0, 4], 3) - - def test_floyd_warshall_numpy_graph_cycle_default_weight(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(8))) - graph.remove_node(0) - graph.add_edges_from_no_data([(1, 2), (1, 7), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]) - dist = retworkx.graph_floyd_warshall_numpy( - graph, default_weight=2, parallel_threshold=self.parallel_threshold - ) - self.assertEqual(dist[0, 3], 6) - self.assertEqual(dist[0, 4], 6) - - -class TestParallelFloydWarshall(TestFloydWarshall): - parallel_threshold = 0 diff --git a/tests/retworkx_backwards_compat/graph/test_graph_attrs.py b/tests/retworkx_backwards_compat/graph/test_graph_attrs.py deleted file mode 100644 index d91ab16660..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_graph_attrs.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestAttributes(unittest.TestCase): - def test_no_attrs(self): - graph = retworkx.PyGraph() - self.assertIsNone(graph.attrs) - - def test_attrs_set_at_init(self): - graph = retworkx.PyGraph(attrs=dict(foo="bar")) - self.assertEqual({"foo": "bar"}, graph.attrs) - - def test_attrs_set_at_init_override(self): - graph = retworkx.PyGraph(attrs=dict(foo="bar")) - self.assertEqual({"foo": "bar"}, graph.attrs) - graph.attrs = "ABC" - self.assertEqual("ABC", graph.attrs) diff --git a/tests/retworkx_backwards_compat/graph/test_isomorphic.py b/tests/retworkx_backwards_compat/graph/test_isomorphic.py deleted file mode 100644 index e034b67511..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_isomorphic.py +++ /dev/null @@ -1,313 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestIsomorphic(unittest.TestCase): - def test_empty_isomorphic_identical(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_isomorphic(g_a, g_b, id_order=id_order)) - - def test_empty_isomorphic(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_isomorphic(g_a, g_b, id_order=id_order)) - - def test_empty_isomorphic_compare_nodes(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic(g_a, g_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_isomorphic_identical(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_isomorphic(g_a, g_b, id_order=id_order)) - - def test_isomorphic_mismatch_node_data(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - nodes = g_b.add_nodes_from(["b_1", "b_2", "b_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "b_1"), (nodes[1], nodes[2], "b_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_isomorphic(g_a, g_b, id_order=id_order)) - - def test_isomorphic_compare_nodes_mismatch_node_data(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - nodes = g_b.add_nodes_from(["b_1", "b_2", "b_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "b_1"), (nodes[1], nodes[2], "b_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse( - retworkx.is_isomorphic(g_a, g_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_is_isomorphic_nodes_compare_raises(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - nodes = g_b.add_nodes_from(["b_1", "b_2", "b_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "b_1"), (nodes[1], nodes[2], "b_2")]) - - def compare_nodes(a, b): - raise TypeError("Failure") - - self.assertRaises(TypeError, retworkx.is_isomorphic, (g_a, g_b, compare_nodes)) - - def test_isomorphic_compare_nodes_identical(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic(g_a, g_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_isomorphic_compare_edges_identical(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic( - g_a, - g_b, - edge_matcher=lambda x, y: x == y, - id_order=id_order, - ) - ) - - def test_isomorphic_removed_nodes_in_second_graph(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - nodes = g_b.add_nodes_from(["a_0", "a_2", "a_1", "a_3"]) - g_b.add_edges_from( - [ - (nodes[0], nodes[1], "e_01"), - (nodes[0], nodes[3], "e_03"), - (nodes[2], nodes[1], "a_1"), - (nodes[1], nodes[3], "a_2"), - ] - ) - g_b.remove_node(nodes[0]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_isomorphic(g_a, g_b, lambda x, y: x == y, id_order=id_order) - ) - - def test_isomorphic_node_count_not_equal(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1")]) - - nodes = g_b.add_nodes_from(["a_0", "a_1"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1")]) - g_b.remove_node(nodes[0]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse(retworkx.is_isomorphic(g_a, g_b, id_order=id_order)) - - def test_same_degrees_non_isomorphic(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4", "b_1", "b_2", "b_3", "b_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[2], nodes[3], "a_3"), - (nodes[3], nodes[0], "a_4"), - (nodes[4], nodes[5], "b_1"), - (nodes[5], nodes[6], "b_2"), - (nodes[6], nodes[7], "b_3"), - (nodes[7], nodes[4], "b_4"), - (nodes[0], nodes[4], "e_1"), - (nodes[1], nodes[5], "e_2"), - ] - ) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3", "a_4", "b_1", "b_2", "b_3", "b_4"]) - g_b.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[2], nodes[3], "a_3"), - (nodes[3], nodes[0], "a_4"), - (nodes[4], nodes[5], "b_1"), - (nodes[5], nodes[6], "b_2"), - (nodes[6], nodes[7], "b_3"), - (nodes[7], nodes[4], "b_4"), - (nodes[0], nodes[4], "e_1"), - (nodes[2], nodes[6], "e_2"), - ] - ) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse(retworkx.is_isomorphic(g_a, g_b, id_order=id_order)) - - def test_graph_isomorphic_self_loop(self): - graph = retworkx.PyGraph() - graph.add_nodes_from([0, 1]) - graph.add_edges_from_no_data([(0, 0), (0, 1)]) - self.assertTrue(retworkx.is_isomorphic(graph, graph)) - - def test_graph_isomorphic_petersen(self): - """Based on 'The isomorphism classes of the generalized Petersen graphs' - by Steimle and Staton: https://doi.org/10.1016/j.disc.2007.12.074 - - For 2 <= k <= n- 2 with gcd(n, k) = 1, - G(n, k) is isomorphic to G(n, l) if and only if: - k ≡ -l (mod n) or kl ≡ ±1 (mod n) - """ - n = 23 - upper_bound_k = (n - 1) // 2 - for k in range(1, upper_bound_k + 1): - for t in range(k, upper_bound_k + 1): - with self.subTest(k=k, t=t): - self.assertEqual( - retworkx.is_isomorphic( - retworkx.generators.generalized_petersen_graph(n, k), - retworkx.generators.generalized_petersen_graph(n, t), - ), - (k == t) or (k == n - t) or (k * t % n == 1) or (k * t % n == n - 1), - ) - - def test_isomorphic_parallel_edges(self): - first = retworkx.PyGraph() - first.extend_from_edge_list([(0, 1), (0, 1), (1, 2), (2, 3)]) - second = retworkx.PyGraph() - second.extend_from_edge_list([(0, 1), (1, 2), (1, 2), (2, 3)]) - self.assertFalse(retworkx.is_isomorphic(first, second)) - - def test_isomorphic_parallel_edges_with_edge_matcher(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list([(0, 1, "a"), (0, 1, "b"), (1, 2, "c")]) - self.assertTrue(retworkx.is_isomorphic(graph, graph, edge_matcher=lambda x, y: x == y)) - - def test_graph_isomorphic_insufficient_call_limit(self): - graph = retworkx.generators.path_graph(5) - self.assertFalse(retworkx.is_isomorphic(graph, graph, call_limit=2)) - - def test_graph_vf2_mapping_identical(self): - graph = retworkx.generators.grid_graph(2, 2) - second_graph = retworkx.generators.grid_graph(2, 2) - mapping = retworkx.graph_vf2_mapping(graph, second_graph) - self.assertEqual(next(mapping), {0: 0, 1: 1, 2: 2, 3: 3}) - - def test_graph_vf2_mapping_identical_removals(self): - graph = retworkx.generators.path_graph(2) - second_graph = retworkx.generators.path_graph(4) - second_graph.remove_nodes_from([1, 2]) - second_graph.add_edge(0, 3, None) - mapping = retworkx.graph_vf2_mapping(graph, second_graph) - self.assertEqual({0: 0, 1: 3}, next(mapping)) - - def test_graph_vf2_mapping_identical_removals_first(self): - second_graph = retworkx.generators.path_graph(2) - graph = retworkx.generators.path_graph(4) - graph.remove_nodes_from([1, 2]) - graph.add_edge(0, 3, None) - mapping = retworkx.graph_vf2_mapping( - graph, - second_graph, - ) - self.assertEqual({0: 0, 3: 1}, next(mapping)) - - def test_graph_vf2_mapping_identical_vf2pp(self): - graph = retworkx.generators.grid_graph(2, 2) - second_graph = retworkx.generators.grid_graph(2, 2) - mapping = retworkx.graph_vf2_mapping(graph, second_graph, id_order=False) - self.assertEqual(next(mapping), {0: 0, 1: 1, 2: 2, 3: 3}) - - def test_graph_vf2_mapping_identical_removals_vf2pp(self): - graph = retworkx.generators.path_graph(2) - second_graph = retworkx.generators.path_graph(4) - second_graph.remove_nodes_from([1, 2]) - second_graph.add_edge(0, 3, None) - mapping = retworkx.graph_vf2_mapping(graph, second_graph, id_order=False) - self.assertEqual({0: 0, 1: 3}, next(mapping)) - - def test_graph_vf2_mapping_identical_removals_first_vf2pp(self): - second_graph = retworkx.generators.path_graph(2) - graph = retworkx.generators.path_graph(4) - graph.remove_nodes_from([1, 2]) - graph.add_edge(0, 3, None) - mapping = retworkx.graph_vf2_mapping(graph, second_graph, id_order=False) - self.assertEqual({0: 0, 3: 1}, next(mapping)) - - def test_graph_vf2_number_of_valid_mappings(self): - graph = retworkx.generators.mesh_graph(3) - mapping = retworkx.graph_vf2_mapping(graph, graph, id_order=True) - total = 0 - for _ in mapping: - total += 1 - self.assertEqual(total, 6) - - def test_empty_graph_vf2_mapping(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - mapping = retworkx.graph_vf2_mapping(g_a, g_b, id_order=id_order, subgraph=False) - self.assertEqual({}, next(mapping)) diff --git a/tests/retworkx_backwards_compat/graph/test_k_shortest_path.py b/tests/retworkx_backwards_compat/graph/test_k_shortest_path.py deleted file mode 100644 index 8c01b64978..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_k_shortest_path.py +++ /dev/null @@ -1,75 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestKShortestpath(unittest.TestCase): - def test_graph_k_shortest_path_lengths(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(8))) - graph.add_edges_from_no_data( - [ - (0, 1), - (1, 2), - (2, 3), - (3, 0), - (4, 5), - (1, 4), - (5, 6), - (6, 7), - (7, 5), - ] - ) - res = retworkx.graph_k_shortest_path_lengths(graph, 1, 2, lambda _: 1) - expected = {0: 3, 1: 2, 2: 3, 3: 2, 4: 3, 5: 4, 6: 4, 7: 4} - self.assertEqual(res, expected) - - def test_k_graph_shortest_path_with_goal(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(7))) - graph.add_edges_from_no_data([(0, 1), (0, 6), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]) - res = retworkx.graph_k_shortest_path_lengths(graph, 0, 2, lambda _: 1, 3) - self.assertEqual({3: 4}, res) - - def test_k_graph_shortest_path_with_goal_node_hole(self): - graph = retworkx.generators.path_graph(4) - graph.remove_node(0) - res = retworkx.graph_k_shortest_path_lengths( - graph, start=1, k=1, edge_cost=lambda _: 1, goal=3 - ) - self.assertEqual({3: 2}, res) - - def test_graph_k_shortest_path_with_invalid_weight(self): - graph = retworkx.generators.path_graph(4) - for invalid_weight in [float("nan"), -1]: - with self.subTest(invalid_weight=invalid_weight): - with self.assertRaises(ValueError): - retworkx.graph_k_shortest_path_lengths( - graph, - start=1, - k=1, - edge_cost=lambda _: invalid_weight, - goal=3, - ) - - def test_k_shortest_path_with_no_path(self): - g = retworkx.PyGraph() - a = g.add_node("A") - b = g.add_node("B") - path_lenghts = retworkx.graph_k_shortest_path_lengths( - g, start=a, k=1, edge_cost=float, goal=b - ) - expected = {} - self.assertEqual(expected, path_lenghts) diff --git a/tests/retworkx_backwards_compat/graph/test_layout.py b/tests/retworkx_backwards_compat/graph/test_layout.py deleted file mode 100644 index 38e56737df..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_layout.py +++ /dev/null @@ -1,477 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class LayoutTest(unittest.TestCase): - thres = 1e-6 - - def assertLayoutEquiv(self, exp, res): - for k in exp: - ev = exp[k] - rv = res[k] - if abs(ev[0] - rv[0]) > self.thres or abs(ev[1] - rv[1]) > self.thres: - self.fail( - "The position for node %s, %s, differs from the expected " - "position, %s by more than the allowed threshold of %s" - % (k, rv, ev, self.thres) - ) - - -class TestRandomLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.path_graph(10) - - def test_random_layout(self): - res = retworkx.graph_random_layout(self.graph, seed=42) - expected = { - 0: (0.2265125179283135, 0.23910669031859955), - 4: (0.8025885957751138, 0.37085692752109345), - 5: (0.23635127852185123, 0.9286365888207462), - 1: (0.760833410686741, 0.5278396573581516), - 3: (0.1879083014236631, 0.524657662927804), - 2: (0.9704763177409157, 0.37546268141451944), - 6: (0.462700947802672, 0.44025745918644743), - 7: (0.3125895420208278, 0.0893209773065271), - 8: (0.5567725240957387, 0.21079648777222115), - 9: (0.7586719404939911, 0.43090704138697045), - } - self.assertEqual(expected, res) - - def test_random_layout_center(self): - res = retworkx.graph_random_layout(self.graph, center=(0.5, 0.5), seed=42) - expected = { - 1: [1.260833410686741, 1.0278396573581516], - 5: [0.7363512785218512, 1.4286365888207462], - 7: [0.8125895420208278, 0.5893209773065271], - 4: [1.3025885957751138, 0.8708569275210934], - 8: [1.0567725240957389, 0.7107964877722212], - 9: [1.2586719404939912, 0.9309070413869704], - 0: [0.7265125179283135, 0.7391066903185995], - 2: [1.4704763177409157, 0.8754626814145194], - 6: [0.962700947802672, 0.9402574591864474], - 3: [0.6879083014236631, 1.0246576629278041], - } - self.assertEqual(expected, res) - - def test_random_layout_no_seed(self): - res = retworkx.graph_random_layout(self.graph) - # Random output, just assert structurally correct - self.assertIsInstance(res, retworkx.Pos2DMapping) - self.assertEqual(len(res), 10) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - -class TestBipartiteLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.path_graph(10) - - def test_bipartite_layout_empty(self): - res = retworkx.bipartite_layout(retworkx.PyGraph(), set()) - self.assertEqual({}, res) - - def test_bipartite_layout_hole(self): - g = retworkx.generators.path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.bipartite_layout(g, set()) - expected = { - 0: (0.0, -1.0), - 2: (0.0, -0.3333333333333333), - 3: (0.0, 0.3333333333333333), - 4: (0.0, 1.0), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout(self): - res = retworkx.bipartite_layout(self.graph, {0, 1, 2, 3, 4}) - expected = { - 0: (-1.0, -0.75), - 1: (-1.0, -0.375), - 2: (-1.0, 0.0), - 3: (-1.0, 0.375), - 4: (-1.0, 0.75), - 5: (1.0, -0.75), - 6: (1.0, -0.375), - 7: (1.0, 0.0), - 8: (1.0, 0.375), - 9: (1.0, 0.75), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_horizontal(self): - res = retworkx.bipartite_layout(self.graph, {0, 1, 2, 3}, horizontal=True) - expected = { - 0: (1.0, -0.9), - 1: (0.3333333333333333, -0.9), - 2: (-0.333333333333333, -0.9), - 3: (-1.0, -0.9), - 4: (1.0, 0.6), - 5: (0.6, 0.6), - 6: (0.2, 0.6), - 7: (-0.2, 0.6), - 8: (-0.6, 0.6), - 9: (-1.0, 0.6), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_scale(self): - res = retworkx.bipartite_layout(self.graph, {0, 1, 2}, scale=2) - expected = { - 0: (-2.0, -1.0714285714285714), - 1: (-2.0, 2.3790493384824785e-17), - 2: (-2.0, 1.0714285714285714), - 3: (0.8571428571428571, -1.0714285714285714), - 4: (0.8571428571428571, -0.7142857142857143), - 5: (0.8571428571428571, -0.35714285714285715), - 6: (0.8571428571428571, 2.3790493384824785e-17), - 7: (0.8571428571428571, 0.35714285714285704), - 8: (0.8571428571428571, 0.7142857142857141), - 9: (0.8571428571428571, 1.0714285714285714), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_center(self): - res = retworkx.bipartite_layout(self.graph, {4, 5, 6}, center=(0.5, 0.5)) - expected = { - 4: (-0.5, -0.0357142857142857), - 5: (-0.5, 0.5), - 6: (-0.5, 1.0357142857142856), - 0: (0.9285714285714286, -0.0357142857142857), - 1: (0.9285714285714286, 0.14285714285714285), - 2: (0.9285714285714286, 0.3214285714285714), - 3: (0.9285714285714286, 0.5), - 7: (0.9285714285714286, 0.6785714285714285), - 8: (0.9285714285714286, 0.857142857142857), - 9: (0.9285714285714286, 1.0357142857142856), - } - self.assertLayoutEquiv(expected, res) - - def test_bipartite_layout_ratio(self): - res = retworkx.bipartite_layout(self.graph, {2, 4, 8}, aspect_ratio=4) - expected = { - 8: [-1.0, 0.17857142857142858], - 2: [-1.0, -0.17857142857142858], - 4: [-1.0, 0], - 0: [0.42857142857142855, -0.17857142857142858], - 1: [0.42857142857142855, -0.11904761904761907], - 3: [0.42857142857142855, -0.05952380952380952], - 5: [0.42857142857142855, 0], - 6: [0.42857142857142855, 0.05952380952380952], - 7: [0.42857142857142855, 0.11904761904761903], - 9: [0.42857142857142855, 0.17857142857142858], - } - self.assertLayoutEquiv(expected, res) - - -class TestCircularLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.path_graph(10) - - def test_circular_layout_empty(self): - res = retworkx.circular_layout(retworkx.PyGraph()) - self.assertEqual({}, res) - - def test_circular_layout_one_node(self): - res = retworkx.circular_layout(retworkx.generators.path_graph(1)) - self.assertEqual({0: (0.0, 0.0)}, res) - - def test_circular_layout_hole(self): - g = retworkx.generators.path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.circular_layout(g) - expected = { - 0: (0.999999986090933, 2.1855693665697608e-08), - 2: (-3.576476059301554e-08, 1.0), - 3: (-0.9999999701976796, -6.556708099709282e-08), - 4: (1.987150711625619e-08, -0.9999999562886126), - } - self.assertLayoutEquiv(expected, res) - - def test_circular_layout(self): - res = retworkx.circular_layout(self.graph) - expected = { - 0: (1.0, 2.662367085193061e-08), - 1: (0.8090170042900712, 0.5877852653564984), - 2: (0.3090169789580973, 0.9510565581329226), - 3: (-0.3090170206813483, 0.9510564985282783), - 4: (-0.8090170460133221, 0.5877852057518542), - 5: (-0.9999999821186069, -6.079910493992474e-08), - 6: (-0.8090169268040337, -0.5877853313184453), - 7: (-0.3090170802859925, -0.9510564452809367), - 8: (0.3090171279697079, -0.9510564452809367), - 9: (0.809016944685427, -0.587785271713801), - } - self.assertLayoutEquiv(expected, res) - - def test_circular_layout_scale(self): - res = retworkx.circular_layout(self.graph, scale=2) - expected = { - 0: (2.0, 5.324734170386122e-08), - 1: (1.6180340085801423, 1.1755705307129969), - 2: (0.6180339579161946, 1.9021131162658451), - 3: (-0.6180340413626966, 1.9021129970565567), - 4: (-1.6180340920266443, 1.1755704115037084), - 5: (-1.9999999642372137, -1.2159820987984948e-07), - 6: (-1.6180338536080674, -1.1755706626368907), - 7: (-0.618034160571985, -1.9021128905618734), - 8: (0.6180342559394159, -1.9021128905618734), - 9: (1.618033889370854, -1.175570543427602), - } - self.assertLayoutEquiv(expected, res) - - def test_circular_layout_center(self): - res = retworkx.circular_layout(self.graph, center=(0.5, 0.5)) - expected = { - 0: (1.5, 0.5000000266236708), - 1: (1.3090170042900713, 1.0877852653564983), - 2: (0.8090169789580973, 1.4510565581329224), - 3: (0.1909829793186517, 1.4510564985282783), - 4: (-0.30901704601332214, 1.0877852057518542), - 5: (-0.49999998211860686, 0.4999999392008951), - 6: (-0.3090169268040337, -0.08778533131844535), - 7: (0.1909829197140075, -0.4510564452809367), - 8: (0.8090171279697079, -0.4510564452809367), - 9: (1.309016944685427, -0.08778527171380102), - } - self.assertLayoutEquiv(expected, res) - - -class TestShellLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.path_graph(10) - - def test_shell_layout_empty(self): - res = retworkx.circular_layout(retworkx.PyGraph()) - self.assertEqual({}, res) - - def test_shell_layout_one_node(self): - res = retworkx.shell_layout(retworkx.generators.path_graph(1)) - self.assertEqual({0: (0.0, 0.0)}, res) - - def test_shell_layout_hole(self): - g = retworkx.generators.path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.shell_layout(g) - expected = { - 0: (-1.0, -8.742277657347586e-08), - 2: (1.1924880638503055e-08, -1.0), - 3: (1.0, 1.7484555314695172e-07), - 4: (-3.3776623808989825e-07, 1.0), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_hole_two_shells(self): - g = retworkx.generators.path_graph(5) - g.remove_nodes_from([2]) - res = retworkx.shell_layout(g, [[0, 1], [3, 4]]) - expected = { - 0: (-2.1855694143368964e-08, 0.5), - 1: (5.962440319251527e-09, -0.5), - 3: (-1.0, -8.742277657347586e-08), - 4: (1.0, 1.7484555314695172e-07), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout(self): - res = retworkx.shell_layout(self.graph) - expected = { - 0: (-1.0, -8.742277657347586e-08), - 1: (-0.8090169429779053, -0.5877853631973267), - 2: (-0.3090170919895172, -0.9510564804077148), - 3: (0.3090171217918396, -0.9510564804077148), - 4: (0.8090172410011292, -0.5877849459648132), - 5: (1.0, 1.7484555314695172e-07), - 6: (0.80901700258255, 0.5877852439880371), - 7: (0.30901679396629333, 0.9510565996170044), - 8: (-0.30901744961738586, 0.9510563611984253), - 9: (-0.8090168833732605, 0.5877854228019714), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_nlist(self): - res = retworkx.shell_layout(self.graph, nlist=[[0, 2], [1, 3], [4, 9], [8, 7], [6, 5]]) - expected = { - 0: (0.16180340945720673, 0.11755704879760742), - 2: (-0.16180339455604553, -0.11755707114934921), - 1: (0.12360679358243942, 0.3804226219654083), - 3: (-0.123606838285923, -0.38042259216308594), - 4: (-0.18541023135185242, 0.5706338882446289), - 9: (0.185410276055336, -0.5706338882446289), - 8: (-0.6472136378288269, 0.4702281653881073), - 7: (0.6472138166427612, -0.4702279567718506), - 6: (-1.0, -8.742277657347586e-08), - 5: (1.0, 1.7484555314695172e-07), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_rotate(self): - res = retworkx.shell_layout( - self.graph, nlist=[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]], rotate=0.5 - ) - expected = { - 0: (0.21939563751220703, 0.11985638737678528), - 1: (-0.21349650621414185, 0.13007399439811707), - 2: (-0.005899117328226566, -0.24993039667606354), - 3: (0.27015113830566406, 0.4207354784011841), - 4: (-0.4994432032108307, 0.023589985445141792), - 5: (0.229292094707489, -0.4443254768848419), - 6: (0.05305289849638939, 0.7481212615966797), - 7: (-0.6744184494018555, -0.3281154930591583), - 8: (0.6213656067848206, -0.420005738735199), - 9: (-0.416146844625473, 0.9092974066734314), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_scale(self): - res = retworkx.shell_layout(self.graph, nlist=[[0, 1, 2, 3, 4], [9, 8, 7, 6, 5]], scale=2) - expected = { - 0: (-4.371138828673793e-08, 1.0), - 1: (-0.9510565996170044, 0.30901679396629333), - 2: (-0.5877850651741028, -0.8090171217918396), - 3: (0.5877854824066162, -0.8090168237686157), - 4: (0.9510564208030701, 0.30901727080345154), - 9: (-2.0, -1.7484555314695172e-07), - 8: (-0.6180341839790344, -1.9021129608154297), - 7: (1.6180344820022583, -1.1755698919296265), - 6: (1.6180340051651, 1.1755704879760742), - 5: (-0.6180348992347717, 1.9021127223968506), - } - self.assertLayoutEquiv(expected, res) - - def test_shell_layout_center(self): - res = retworkx.shell_layout( - self.graph, - nlist=[[0, 1, 2, 3, 4], [9, 8, 7, 6, 5]], - center=(0.5, 0.5), - ) - expected = { - 0: (0.49999997814430586, 1.0), - 1: (0.024471700191497803, 0.6545083969831467), - 2: (0.2061074674129486, 0.0954914391040802), - 3: (0.7938927412033081, 0.09549158811569214), - 4: (0.975528210401535, 0.6545086354017258), - 9: (-0.5, 0.4999999125772234), - 8: (0.1909829080104828, -0.45105648040771484), - 7: (1.3090172410011292, -0.08778494596481323), - 6: (1.30901700258255, 1.087785243988037), - 5: (0.19098255038261414, 1.4510563611984253), - } - self.assertLayoutEquiv(expected, res) - - -class TestSpiralLayout(LayoutTest): - def setUp(self): - self.graph = retworkx.generators.path_graph(10) - - def test_spiral_layout_empty(self): - res = retworkx.spiral_layout(retworkx.PyGraph()) - self.assertEqual({}, res) - - def test_spiral_layout_one_node(self): - res = retworkx.spiral_layout(retworkx.generators.path_graph(1)) - self.assertEqual({0: (0.0, 0.0)}, res) - - def test_spiral_layout_hole(self): - g = retworkx.generators.path_graph(5) - g.remove_nodes_from([1]) - res = retworkx.spiral_layout(g) - expected = { - 0: (-0.6415327868391166, -0.6855508729419231), - 2: (-0.03307913182988828, -0.463447951079834), - 3: (0.34927952438480797, 0.1489988240217569), - 4: (0.32533239428419697, 1.0), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout(self): - res = retworkx.spiral_layout(self.graph) - expected = { - 0: (0.3083011152777303, -0.36841870322845377), - 1: (0.4448595378922136, -0.3185709877650719), - 2: (0.5306742824266687, -0.18111636841212878), - 3: (0.5252997033017661, 0.009878257518578544), - 4: (0.40713492048969163, 0.20460820654918466), - 5: (0.17874125121181098, 0.3468009691240852), - 6: (-0.1320415949011884, 0.3844997574641717), - 7: (-0.4754889029311045, 0.28057288841663486), - 8: (-0.7874803127675889, 0.021164283410983312), - 9: (-0.9999999999999999, -0.3794183030779839), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_scale(self): - res = retworkx.spiral_layout(self.graph, scale=2) - expected = { - 0: (0.6166022305554606, -0.7368374064569075), - 1: (0.8897190757844272, -0.6371419755301438), - 2: (1.0613485648533374, -0.36223273682425755), - 3: (1.0505994066035322, 0.01975651503715709), - 4: (0.8142698409793833, 0.4092164130983693), - 5: (0.35748250242362195, 0.6936019382481704), - 6: (-0.2640831898023768, 0.7689995149283434), - 7: (-0.950977805862209, 0.5611457768332697), - 8: (-1.5749606255351778, 0.042328566821966625), - 9: (-1.9999999999999998, -0.7588366061559678), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_center(self): - res = retworkx.spiral_layout(self.graph, center=(1, 1)) - expected = { - 0: (1.3083011152777302, 0.6315812967715462), - 1: (1.4448595378922136, 0.681429012234928), - 2: (1.5306742824266686, 0.8188836315878713), - 3: (1.5252997033017661, 1.0098782575185785), - 4: (1.4071349204896917, 1.2046082065491848), - 5: (1.178741251211811, 1.3468009691240852), - 6: (0.8679584050988116, 1.3844997574641718), - 7: (0.5245110970688955, 1.2805728884166347), - 8: (0.2125196872324111, 1.0211642834109833), - 9: (1.1102230246251565e-16, 0.6205816969220161), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_resolution(self): - res = retworkx.spiral_layout(self.graph, resolution=0.6) - expected = { - 0: (0.14170895375949058, 0.22421978768273812), - 1: (0.2657196183870804, 0.30906004798138936), - 2: (0.2506009612140119, 0.5043065412934762), - 3: (0.039294315670400995, 0.6631957258449066), - 4: (-0.3014789232909145, 0.6301862160709318), - 5: (-0.602046830323471, 0.3302396035952633), - 6: (-0.66674476042188, -0.17472522299849289), - 7: (-0.3739394496041176, -0.6924895145748617), - 8: (0.2468861146093996, -0.9732085843739783), - 9: (1.0, -0.8207846005213728), - } - self.assertLayoutEquiv(expected, res) - - def test_spiral_layout_equidistant(self): - res = retworkx.spiral_layout(self.graph, equidistant=True) - expected = { - 0: (-0.13161882865656718, -0.7449342807652114), - 1: (0.7160560542246066, -0.6335352483233974), - 2: (0.6864868274284994, -0.34165899654603915), - 3: (0.5679822628330004, -0.07281296883784087), - 4: (0.375237081214659, 0.14941210155952697), - 5: (0.12730720268992277, 0.30830226777240866), - 6: (-0.15470865936858091, 0.3939608192236113), - 7: (-0.4495426197217269, 0.4027809258196645), - 8: (-0.7371993206438128, 0.33662707199446507), - 9: (-1.0, 0.2018583081028111), - } - self.assertLayoutEquiv(expected, res) diff --git a/tests/retworkx_backwards_compat/graph/test_matching.py b/tests/retworkx_backwards_compat/graph/test_matching.py deleted file mode 100644 index 820a6a38a3..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_matching.py +++ /dev/null @@ -1,56 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestMatching(unittest.TestCase): - def test_valid(self): - graph = retworkx.generators.path_graph(4) - matching = {(0, 1), (2, 3)} - self.assertTrue(retworkx.is_maximal_matching(graph, matching)) - - def test_not_matching(self): - graph = retworkx.generators.path_graph(4) - matching = {(0, 1), (1, 2), (2, 3)} - self.assertFalse(retworkx.is_maximal_matching(graph, matching)) - - def test_not_maximal(self): - graph = retworkx.generators.path_graph(4) - matching = {(0, 1)} - self.assertFalse(retworkx.is_maximal_matching(graph, matching)) - - def test_is_matching_empty(self): - graph = retworkx.generators.path_graph(4) - matching = set() - self.assertTrue(retworkx.is_matching(graph, matching)) - - def test_is_matching_single_edge(self): - graph = retworkx.generators.path_graph(4) - matching = {(1, 2)} - self.assertTrue(retworkx.is_matching(graph, matching)) - - def test_is_matching_valid(self): - graph = retworkx.generators.path_graph(4) - matching = {(0, 1), (2, 3)} - self.assertTrue(retworkx.is_matching(graph, matching)) - - def test_is_matching_invalid(self): - graph = retworkx.generators.path_graph(4) - matching = {(0, 1), (1, 2), (2, 3)} - self.assertFalse(retworkx.is_matching(graph, matching)) - - def test_is_matching_invalid_edge(self): - graph = retworkx.generators.path_graph(4) - matching = {(0, 3), (1, 2)} - self.assertFalse(retworkx.is_matching(graph, matching)) diff --git a/tests/retworkx_backwards_compat/graph/test_max_weight_matching.py b/tests/retworkx_backwards_compat/graph/test_max_weight_matching.py deleted file mode 100644 index 091626da30..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_max_weight_matching.py +++ /dev/null @@ -1,569 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# These tests are adapated from the networkx test cases: -# https://github.com/networkx/networkx/blob/3351206a3ce5b3a39bb2fc451e93ef545b96c95b/networkx/algorithms/tests/test_matching.py - -import random -import unittest - -import networkx - -import retworkx - - -def match_dict_to_set(match): - return {(u, v) for (u, v) in set(map(frozenset, match.items()))} - - -class TestMaxWeightMatching(unittest.TestCase): - def compare_match_sets(self, rx_match, expected_match): - for (u, v) in rx_match: - if (u, v) not in expected_match and (v, u) not in expected_match: - self.fail( - "Element %s and it's reverse %s not found in " - "expected output.\nretworkx output: %s\nexpected " - "output: %s" % ((u, v), (v, u), rx_match, expected_match) - ) - - def compare_rx_nx_sets(self, rx_graph, rx_matches, nx_matches, seed, nx_graph): - def get_rx_weight(edge): - weight = rx_graph.get_edge_data(*edge) - if weight is None: - return 1 - return weight - - def get_nx_weight(edge): - weight = nx_graph.get_edge_data(*edge) - if not weight: - return 1 - return weight["weight"] - - not_match = False - for (u, v) in rx_matches: - if (u, v) not in nx_matches: - if (v, u) not in nx_matches: - print( - "seed %s failed. Element %s and it's " - "reverse %s not found in networkx output.\nretworkx" - " output: %s\nnetworkx output: %s\nedge list: %s\n" - "falling back to checking for a valid solution" - % ( - seed, - (u, v), - (v, u), - rx_matches, - nx_matches, - list(rx_graph.weighted_edge_list()), - ) - ) - not_match = True - break - if not_match: - self.assertTrue( - retworkx.is_matching(rx_graph, rx_matches), - "%s is not a valid matching" % rx_matches, - ) - self.assertTrue( - retworkx.is_maximal_matching(rx_graph, rx_matches), - "%s is not a maximal matching" % rx_matches, - ) - self.assertEqual( - sum(map(get_rx_weight, rx_matches)), - sum(map(get_nx_weight, nx_matches)), - ) - - def test_empty_graph(self): - graph = retworkx.PyGraph() - self.assertEqual(retworkx.max_weight_matching(graph), set()) - - def test_single_edge(self): - graph = retworkx.PyGraph() - graph.add_nodes_from([0, 1]) - graph.add_edges_from([(0, 1, 1)]) - self.compare_match_sets( - retworkx.max_weight_matching(graph, verify_optimum=True), - { - (0, 1), - }, - ) - - def test_single_edge_no_verification(self): - graph = retworkx.PyGraph() - graph.add_nodes_from([0, 1]) - graph.add_edges_from([(0, 1, 1)]) - self.compare_match_sets( - retworkx.max_weight_matching(graph, verify_optimum=False), - { - (0, 1), - }, - ) - - def test_single_self_edge(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list([(0, 0, 100)]) - self.assertEqual(retworkx.max_weight_matching(graph), set()) - - def test_small_graph(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list([(1, 2, 10), (2, 3, 11)]) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - { - (2, 3), - }, - ) - - def test_path_graph(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list([(1, 2, 5), (2, 3, 11), (3, 4, 5)]) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - { - (2, 3), - }, - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, True, weight_fn=lambda x: x, verify_optimum=True), - {(1, 2), (3, 4)}, - ) - - def test_negative_weights(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 2), - (1, 3, -2), - (2, 3, 1), - (2, 4, -1), - (3, 4, -6), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - { - (1, 2), - }, - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, True, weight_fn=lambda x: x, verify_optimum=True), - {(1, 3), (2, 4)}, - ) - - def test_s_blossom(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (0, 1, 8), - (0, 2, 9), - (1, 2, 10), - (2, 3, 7), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(0, 1), (2, 3)}, - ) - graph.extend_from_weighted_edge_list([(0, 5, 5), (3, 4, 6)]) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(0, 5), (1, 2), (3, 4)}, - ) - - def test_s_t_blossom(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 9), - (1, 3, 8), - (2, 3, 10), - (1, 4, 5), - (4, 5, 4), - (1, 6, 3), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 6), (2, 3), (4, 5)}, - ) - graph.remove_edge(1, 6) - graph.remove_edge(4, 5) - graph.extend_from_weighted_edge_list([(4, 5, 3), (1, 6, 4)]) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 6), (2, 3), (4, 5)}, - ) - graph.remove_edge(1, 6) - graph.add_edge(3, 6, 4) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 2), (3, 6), (4, 5)}, - ) - - def test_s_t_blossom_with_removed_nodes(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 9), - (1, 3, 8), - (2, 3, 10), - (1, 4, 5), - (4, 5, 4), - (1, 6, 3), - ] - ) - node_id = graph.add_node(None) - graph.remove_node(5) - graph.add_edge(4, node_id, 4) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 6), (2, 3), (4, 7)}, - ) - graph.remove_edge(1, 6) - graph.remove_edge(4, 7) - graph.extend_from_weighted_edge_list([(4, node_id, 3), (1, 6, 4)]) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 6), (2, 3), (4, 7)}, - ) - graph.remove_edge(1, 6) - graph.add_edge(3, 6, 4) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 2), (3, 6), (4, 7)}, - ) - - def test_nested_s_blossom(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 9), - (1, 3, 9), - (2, 3, 10), - (2, 4, 8), - (3, 5, 8), - (4, 5, 10), - (5, 6, 6), - ] - ) - expected = {(1, 3), (2, 4), (5, 6)} - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - expected, - ) - - def test_nested_s_blossom_relabel(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 10), - (1, 7, 10), - (2, 3, 12), - (3, 4, 20), - (3, 5, 20), - (4, 5, 25), - (5, 6, 10), - (6, 7, 10), - (7, 8, 8), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 2), (3, 4), (5, 6), (7, 8)}, - ) - - def test_nested_s_blossom_expand(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 8), - (1, 3, 8), - (2, 3, 10), - (2, 4, 12), - (3, 5, 12), - (4, 5, 14), - (4, 6, 12), - (5, 7, 12), - (6, 7, 14), - (7, 8, 12), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 2), (3, 5), (4, 6), (7, 8)}, - ) - - def test_s_blossom_relabel_expand(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 23), - (1, 5, 22), - (1, 6, 15), - (2, 3, 25), - (3, 4, 22), - (4, 5, 25), - (4, 8, 14), - (5, 7, 13), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - {(1, 6), (2, 3), (4, 8), (5, 7)}, - ) - - def test_nested_s_blossom_relabel_expand(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 19), - (1, 3, 20), - (1, 8, 8), - (2, 3, 25), - (2, 4, 18), - (3, 5, 18), - (4, 5, 13), - (4, 7, 7), - (5, 6, 7), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - match_dict_to_set({1: 8, 2: 3, 3: 2, 4: 7, 5: 6, 6: 5, 7: 4, 8: 1}), - ) - - def test_blossom_relabel_multiple_paths(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 45), - (1, 5, 45), - (2, 3, 50), - (3, 4, 45), - (4, 5, 50), - (1, 6, 30), - (3, 9, 35), - (4, 8, 35), - (5, 7, 26), - (9, 10, 5), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - match_dict_to_set({1: 6, 2: 3, 3: 2, 4: 8, 5: 7, 6: 1, 7: 5, 8: 4, 9: 10, 10: 9}), - ) - - def test_blossom_relabel_multiple_path_alternate(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 45), - (1, 5, 45), - (2, 3, 50), - (3, 4, 45), - (4, 5, 50), - (1, 6, 30), - (3, 9, 35), - (4, 8, 26), - (5, 7, 40), - (9, 10, 5), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - match_dict_to_set({1: 6, 2: 3, 3: 2, 4: 8, 5: 7, 6: 1, 7: 5, 8: 4, 9: 10, 10: 9}), - ) - - def test_blossom_relabel_multiple_paths_least_slack(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 45), - (1, 5, 45), - (2, 3, 50), - (3, 4, 45), - (4, 5, 50), - (1, 6, 30), - (3, 9, 35), - (4, 8, 28), - (5, 7, 26), - (9, 10, 5), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - match_dict_to_set({1: 6, 2: 3, 3: 2, 4: 8, 5: 7, 6: 1, 7: 5, 8: 4, 9: 10, 10: 9}), - ) - - def test_nested_blossom_expand_recursively(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 40), - (1, 3, 40), - (2, 3, 60), - (2, 4, 55), - (3, 5, 55), - (4, 5, 50), - (1, 8, 15), - (5, 7, 30), - (7, 6, 10), - (8, 10, 10), - (4, 9, 30), - ] - ) - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - match_dict_to_set({1: 2, 2: 1, 3: 5, 4: 9, 5: 3, 6: 7, 7: 6, 8: 10, 9: 4, 10: 8}), - ) - - def test_nested_blossom_augmented(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (1, 2, 45), - (1, 7, 45), - (2, 3, 50), - (3, 4, 45), - (4, 5, 95), - (4, 6, 94), - (5, 6, 94), - (6, 7, 50), - (1, 8, 30), - (3, 11, 35), - (5, 9, 36), - (7, 10, 26), - (11, 12, 5), - ] - ) - expected = { - 1: 8, - 2: 3, - 3: 2, - 4: 6, - 5: 9, - 6: 4, - 7: 10, - 8: 1, - 9: 5, - 10: 7, - 11: 12, - 12: 11, - } - self.compare_match_sets( - retworkx.max_weight_matching(graph, weight_fn=lambda x: x, verify_optimum=True), - match_dict_to_set(expected), - ) - - def test_gnp_random_against_networkx(self): - for i in range(1024): - with self.subTest(i=i): - rx_graph = retworkx.undirected_gnp_random_graph(10, 0.75, seed=42 + i) - nx_graph = networkx.Graph(list(rx_graph.edge_list())) - nx_matches = networkx.max_weight_matching(nx_graph) - rx_matches = retworkx.max_weight_matching(rx_graph, verify_optimum=True) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42 + i, nx_graph) - - def test_gnp_random_against_networkx_with_weight(self): - for i in range(1024): - with self.subTest(i=i): - random.seed(i) - rx_graph = retworkx.undirected_gnp_random_graph(10, 0.75, seed=42 + i) - for edge in rx_graph.edge_list(): - rx_graph.update_edge(*edge, random.randint(0, 5000)) - nx_graph = networkx.Graph( - [(x[0], x[1], {"weight": x[2]}) for x in rx_graph.weighted_edge_list()] - ) - nx_matches = networkx.max_weight_matching(nx_graph) - rx_matches = retworkx.max_weight_matching( - rx_graph, weight_fn=lambda x: x, verify_optimum=True - ) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42 + i, nx_graph) - - def test_gnp_random_against_networkx_with_negative_weight(self): - for i in range(1024): - with self.subTest(i=i): - random.seed(i) - rx_graph = retworkx.undirected_gnp_random_graph(10, 0.75, seed=42 + i) - for edge in rx_graph.edge_list(): - rx_graph.update_edge(*edge, random.randint(-5000, 5000)) - nx_graph = networkx.Graph( - [(x[0], x[1], {"weight": x[2]}) for x in rx_graph.weighted_edge_list()] - ) - nx_matches = networkx.max_weight_matching(nx_graph) - rx_matches = retworkx.max_weight_matching( - rx_graph, weight_fn=lambda x: x, verify_optimum=True - ) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42 + i, nx_graph) - - def test_gnp_random_against_networkx_max_cardinality(self): - rx_graph = retworkx.undirected_gnp_random_graph(10, 0.78, seed=428) - nx_graph = networkx.Graph(list(rx_graph.edge_list())) - nx_matches = networkx.max_weight_matching(nx_graph, maxcardinality=True) - rx_matches = retworkx.max_weight_matching( - rx_graph, max_cardinality=True, verify_optimum=True - ) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 428, nx_graph) - - def test_gnp_random_against_networkx_with_weight_max_cardinality(self): - for i in range(1024): - with self.subTest(i=i): - random.seed(i) - rx_graph = retworkx.undirected_gnp_random_graph(10, 0.75, seed=42 + i) - for edge in rx_graph.edge_list(): - rx_graph.update_edge(*edge, random.randint(0, 5000)) - nx_graph = networkx.Graph( - [(x[0], x[1], {"weight": x[2]}) for x in rx_graph.weighted_edge_list()] - ) - nx_matches = networkx.max_weight_matching(nx_graph, maxcardinality=True) - rx_matches = retworkx.max_weight_matching( - rx_graph, - weight_fn=lambda x: x, - max_cardinality=True, - verify_optimum=True, - ) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42 + i, nx_graph) - - def test_gnp_random__networkx_with_negative_weight_max_cardinality(self): - for i in range(1024): - with self.subTest(i=i): - random.seed(i) - rx_graph = retworkx.undirected_gnp_random_graph(10, 0.75, seed=42 + i) - for edge in rx_graph.edge_list(): - rx_graph.update_edge(*edge, random.randint(-5000, 5000)) - nx_graph = networkx.Graph( - [(x[0], x[1], {"weight": x[2]}) for x in rx_graph.weighted_edge_list()] - ) - nx_matches = networkx.max_weight_matching(nx_graph, maxcardinality=True) - rx_matches = retworkx.max_weight_matching( - rx_graph, - weight_fn=lambda x: x, - max_cardinality=True, - verify_optimum=True, - ) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42 + i, nx_graph) - - def test_gnm_random_against_networkx(self): - rx_graph = retworkx.undirected_gnm_random_graph(10, 13, seed=42) - nx_graph = networkx.Graph(list(rx_graph.edge_list())) - nx_matches = networkx.max_weight_matching(nx_graph) - rx_matches = retworkx.max_weight_matching(rx_graph, verify_optimum=True) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42, nx_graph) - - def test_gnm_random_against_networkx_max_cardinality(self): - rx_graph = retworkx.undirected_gnm_random_graph(10, 12, seed=42) - nx_graph = networkx.Graph(list(rx_graph.edge_list())) - nx_matches = networkx.max_weight_matching(nx_graph, maxcardinality=True) - rx_matches = retworkx.max_weight_matching( - rx_graph, max_cardinality=True, verify_optimum=True - ) - self.compare_rx_nx_sets(rx_graph, rx_matches, nx_matches, 42, nx_graph) diff --git a/tests/retworkx_backwards_compat/graph/test_mst.py b/tests/retworkx_backwards_compat/graph/test_mst.py deleted file mode 100644 index 895d2328b2..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_mst.py +++ /dev/null @@ -1,122 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestMinimumSpanningTree(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.a = self.graph.add_node("A") - self.b = self.graph.add_node("B") - self.c = self.graph.add_node("C") - self.d = self.graph.add_node("D") - self.e = self.graph.add_node("E") - self.f = self.graph.add_node("F") - - edge_list = [ - (self.a, self.b, 3), - (self.a, self.d, 2), - (self.b, self.c, 4), - (self.c, self.d, 1), - (self.a, self.f, 1), - (self.b, self.f, 6), - (self.d, self.e, 5), - (self.c, self.e, 7), - ] - self.graph.add_edges_from(edge_list) - - self.expected_edges = [ - (self.a, self.b, 3), - (self.a, self.d, 2), - (self.c, self.d, 1), - (self.a, self.f, 1), - (self.d, self.e, 5), - ] - - def assertEqualEdgeList(self, expected, actual): - self.assertEqual(len(expected), len(actual)) - for edge in actual: - self.assertTrue(edge in expected) - - def test_edges(self): - mst_edges = retworkx.minimum_spanning_edges(self.graph, weight_fn=lambda x: x) - self.assertEqual(len(self.graph.nodes()) - 1, len(mst_edges)) - for edge in mst_edges: - self.assertTrue(edge in self.expected_edges) - - def test_tree(self): - mst_graph = retworkx.minimum_spanning_tree(self.graph, weight_fn=lambda x: x) - self.assertEqual(self.graph.nodes(), mst_graph.nodes()) - self.assertEqual(len(self.graph.nodes()) - 1, len(mst_graph.edge_list())) - self.assertEqualEdgeList(self.expected_edges, mst_graph.weighted_edge_list()) - - def test_forest(self): - s = self.graph.add_node("S") - t = self.graph.add_node("T") - u = self.graph.add_node("U") - self.graph.add_edges_from([(s, t, 10), (t, u, 9), (s, u, 8)]) - forest_expected_edges = self.expected_edges + [(s, u, 8), (t, u, 9)] - - msf_graph = retworkx.minimum_spanning_tree(self.graph, weight_fn=lambda x: x) - self.assertEqual(self.graph.nodes(), msf_graph.nodes()) - self.assertEqual(len(self.graph.nodes()) - 2, len(msf_graph.edge_list())) - self.assertEqualEdgeList(forest_expected_edges, msf_graph.weighted_edge_list()) - - def test_isolated(self): - s = self.graph.add_node("S") - - msf_graph = retworkx.minimum_spanning_tree(self.graph, weight_fn=lambda x: x) - self.assertEqual("S", msf_graph.nodes()[s]) - self.assertEqual(self.graph.nodes(), msf_graph.nodes()) - self.assertEqual(len(self.graph.nodes()) - 2, len(msf_graph.edge_list())) - self.assertEqualEdgeList(self.expected_edges, msf_graph.weighted_edge_list()) - - def test_multigraph(self): - mutligraph = retworkx.PyGraph(multigraph=True) - mutligraph.extend_from_weighted_edge_list( - [(0, 1, 1), (0, 2, 3), (1, 2, 2), (0, 0, -10), (1, 2, 1)] - ) - - mst_graph = retworkx.minimum_spanning_tree(mutligraph, weight_fn=lambda x: x) - self.assertEqualEdgeList([(0, 1, 1), (1, 2, 1)], mst_graph.weighted_edge_list()) - - def test_default_weight(self): - weightless_graph = retworkx.PyGraph() - weightless_graph.extend_from_edge_list( - [(0, 1), (0, 2), (0, 3), (0, 4), (1, 5), (2, 6), (3, 7), (4, 8)] - ) # MST of the graph is itself - - mst_graph_default_weight = retworkx.minimum_spanning_tree(weightless_graph) - mst_graph_weight_2 = retworkx.minimum_spanning_tree(weightless_graph, default_weight=2.0) - - self.assertTrue( - retworkx.is_isomorphic( - weightless_graph, - mst_graph_default_weight, - ) - ) - self.assertTrue( - retworkx.is_isomorphic( - weightless_graph, - mst_graph_weight_2, - ) - ) - - def test_nan_weight(self): - invalid_graph = retworkx.PyGraph() - invalid_graph.extend_from_weighted_edge_list([(0, 1, 0.5), (0, 2, float("nan"))]) - - with self.assertRaises(ValueError): - retworkx.minimum_spanning_tree(invalid_graph, lambda x: x) diff --git a/tests/retworkx_backwards_compat/graph/test_neighbors.py b/tests/retworkx_backwards_compat/graph/test_neighbors.py deleted file mode 100644 index 25ec06258c..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_neighbors.py +++ /dev/null @@ -1,43 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestNeighbors(unittest.TestCase): - def test_single_neighbor(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, {"a": 1}) - node_c = graph.add_node("c") - graph.add_edge(node_a, node_c, {"a": 2}) - res = graph.neighbors(node_a) - self.assertCountEqual([node_c, node_b], res) - - def test_unique_neighbors_on_graphs(self): - dag = retworkx.PyGraph() - node_a = dag.add_node("a") - node_b = dag.add_node("b") - node_c = dag.add_node("c") - dag.add_edge(node_a, node_b, ["edge a->b"]) - dag.add_edge(node_a, node_b, ["edge a->b bis"]) - dag.add_edge(node_a, node_c, ["edge a->c"]) - res = dag.neighbors(node_a) - self.assertCountEqual([node_c, node_b], res) - - def test_no_neighbor(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - self.assertEqual([], graph.neighbors(node_a)) diff --git a/tests/retworkx_backwards_compat/graph/test_nodes.py b/tests/retworkx_backwards_compat/graph/test_nodes.py deleted file mode 100644 index c9bfe053e9..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_nodes.py +++ /dev/null @@ -1,181 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestNodes(unittest.TestCase): - def test_nodes(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - res = graph.nodes() - self.assertEqual(["a", "b"], res) - self.assertEqual([0, 1], graph.node_indexes()) - - def test_node_indices(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - self.assertEqual([0, 1], graph.node_indices()) - - def test_no_nodes(self): - graph = retworkx.PyGraph() - self.assertEqual([], graph.nodes()) - self.assertEqual([], graph.node_indexes()) - self.assertEqual([], graph.node_indices()) - - def test_remove_node(self): - graph = retworkx.PyGraph() - graph.add_node("a") - node_b = graph.add_node("b") - graph.add_node("c") - graph.remove_node(node_b) - res = graph.nodes() - self.assertEqual(["a", "c"], res) - self.assertEqual([0, 2], graph.node_indexes()) - - def test_remove_node_invalid_index(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.remove_node(76) - res = graph.nodes() - self.assertEqual(["a", "b", "c"], res) - self.assertEqual([0, 1, 2], graph.node_indexes()) - - def test_remove_nodes_from(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Edgy_mk2") - graph.remove_nodes_from([node_b, node_c]) - res = graph.nodes() - self.assertEqual(["a"], res) - self.assertEqual([0], graph.node_indexes()) - - def test_remove_nodes_from_with_invalid_index(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Edgy_mk2") - graph.remove_nodes_from([node_b, node_c, 76]) - res = graph.nodes() - self.assertEqual(["a"], res) - self.assertEqual([0], graph.node_indexes()) - - def test_get_node_data(self): - graph = retworkx.PyGraph() - graph.add_node("a") - node_b = graph.add_node("b") - self.assertEqual("b", graph.get_node_data(node_b)) - - def test_get_node_data_bad_index(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - self.assertRaises(IndexError, graph.get_node_data, 42) - - def test_pygraph_length(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "An_edge") - self.assertEqual(2, len(graph)) - - def test_pygraph_num_nodes(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "An_edge") - self.assertEqual(2, graph.num_nodes()) - - def test_pygraph_length_empty(self): - graph = retworkx.PyGraph() - self.assertEqual(0, len(graph)) - - def test_pygraph_num_nodes_empty(self): - graph = retworkx.PyGraph() - self.assertEqual(0, graph.num_nodes()) - - def test_add_nodes_from(self): - graph = retworkx.PyGraph() - nodes = list(range(100)) - res = graph.add_nodes_from(nodes) - self.assertEqual(len(res), 100) - self.assertEqual(res, nodes) - - def test_add_node_from_empty(self): - graph = retworkx.PyGraph() - res = graph.add_nodes_from([]) - self.assertEqual(len(res), 0) - - def test_get_node_data_getitem(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - self.assertEqual("b", graph[node_b]) - - def test_get_node_data_getitem_bad_index(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - with self.assertRaises(IndexError): - graph[42] - - def test_set_node_data_setitem(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - graph[node_b] = "Oh so cool" - self.assertEqual("Oh so cool", graph[node_b]) - - def test_set_node_data_setitem_bad_index(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - with self.assertRaises(IndexError): - graph[42] = "Oh so cool" - - def test_remove_node_delitem(self): - graph = retworkx.PyGraph() - node_a = graph.add_node("a") - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, "Edgy") - node_c = graph.add_node("c") - graph.add_edge(node_b, node_c, "Edgy_mk2") - del graph[node_b] - res = graph.nodes() - self.assertEqual(["a", "c"], res) - self.assertEqual([0, 2], graph.node_indexes()) - - def test_remove_node_delitem_invalid_index(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - with self.assertRaises(IndexError): - del graph[76] - res = graph.nodes() - self.assertEqual(["a", "b", "c"], res) - self.assertEqual([0, 1, 2], graph.node_indexes()) diff --git a/tests/retworkx_backwards_compat/graph/test_num_shortest_path.py b/tests/retworkx_backwards_compat/graph/test_num_shortest_path.py deleted file mode 100644 index c1182eb8f3..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_num_shortest_path.py +++ /dev/null @@ -1,138 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestNumShortestpath(unittest.TestCase): - def test_num_shortest_path_unweighted(self): - graph = retworkx.PyGraph() - node_a = graph.add_node(0) - node_b = graph.add_node("end") - for i in range(3): - node = graph.add_node(i) - graph.add_edge(node_a, node, None) - graph.add_edge(node, node_b, None) - res = retworkx.graph_num_shortest_paths_unweighted(graph, node_a) - expected = {2: 1, 4: 1, 3: 1, 1: 3} - self.assertEqual(expected, res) - - def test_parallel_paths(self): - graph = retworkx.PyGraph() - graph.extend_from_edge_list( - [ - (0, 1), - (1, 2), - (2, 3), - (0, 4), - (4, 5), - (5, 3), - ] - ) - res = retworkx.num_shortest_paths_unweighted(graph, 0) - expected = { - 1: 1, - 2: 1, - 3: 2, - 4: 1, - 5: 1, - } - self.assertEqual(expected, res) - - def test_grid_graph(self): - """Test num shortest paths for a 5x5 grid graph - 0 - 1 - 2 - 3 - 4 - | | | | | - 5 - 6 - 7 - 8 - 9 - | | | | | - 10- 11- 12- 13- 14 - | | | | | - 15- 16- 17- 18- 19 - | | | | | - 20- 21- 22- 23- 24 - """ - graph = retworkx.generators.grid_graph(5, 5) - res = retworkx.num_shortest_paths_unweighted(graph, 0) - expected = { - 1: 1, - 2: 1, - 3: 1, - 4: 1, - 5: 1, - 6: 2, - 7: 3, - 8: 4, - 9: 5, - 10: 1, - 11: 3, - 12: 6, - 13: 10, - 14: 15, - 15: 1, - 16: 4, - 17: 10, - 18: 20, - 19: 35, - 20: 1, - 21: 5, - 22: 15, - 23: 35, - 24: 70, - } - self.assertEqual(expected, res) - - def test_node_with_no_path(self): - graph = retworkx.generators.path_graph(5) - graph.extend_from_edge_list([(6, 7), (7, 8), (8, 9), (9, 10), (10, 11)]) - expected = {1: 1, 2: 1, 3: 1, 4: 1} - res = retworkx.num_shortest_paths_unweighted(graph, 0) - self.assertEqual(expected, res) - res = retworkx.num_shortest_paths_unweighted(graph, 6) - expected = {7: 1, 8: 1, 9: 1, 10: 1, 11: 1} - self.assertEqual(expected, res) - - def test_node_indices_with_holes(self): - graph = retworkx.generators.path_graph(5) - graph.extend_from_edge_list([(6, 7), (7, 8), (8, 9), (9, 10), (10, 11)]) - graph.add_edge(4, 6, None) - graph.remove_node(5) - expected = { - 1: 1, - 2: 1, - 3: 1, - 4: 1, - 6: 1, - 7: 1, - 8: 1, - 9: 1, - 10: 1, - 11: 1, - } - res = retworkx.num_shortest_paths_unweighted(graph, 0) - self.assertEqual(expected, res) - - def test_no_edges(self): - graph = retworkx.PyGraph() - graph.add_node(0) - graph.add_node(1) - res = retworkx.num_shortest_paths_unweighted(graph, 0) - self.assertEqual({}, res) - - def test_invalid_source_index(self): - graph = retworkx.PyGraph() - graph.add_node(0) - graph.add_node(1) - graph.add_edge(0, 1, None) - with self.assertRaises(IndexError): - retworkx.num_shortest_paths_unweighted(graph, 4) diff --git a/tests/retworkx_backwards_compat/graph/test_spring_layout.py b/tests/retworkx_backwards_compat/graph/test_spring_layout.py deleted file mode 100644 index 48a51fe38a..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_spring_layout.py +++ /dev/null @@ -1,73 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestSpringLayout(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - node_a = self.graph.add_node(1) - node_b = self.graph.add_node(2) - self.graph.add_edge(node_a, node_b, 1) - node_c = self.graph.add_node(3) - self.graph.add_edge(node_a, node_c, 2) - - def test_empty_graph(self): - graph = retworkx.PyGraph() - res = retworkx.spring_layout(graph) - self.assertEqual({}, res) - - def test_simple_graph(self): - res = retworkx.spring_layout(self.graph, seed=42) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_simple_graph_with_edge_weights(self): - res = retworkx.spring_layout(self.graph, weight_fn=lambda e: e) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_simple_graph_center(self): - res = retworkx.spring_layout(self.graph, center=[0.5, 0.5]) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_simple_graph_fixed(self): - pos = {0: [0.1, 0.1]} - res = retworkx.spring_layout(self.graph, pos=pos, fixed={0}) - self.assertEqual(res[0], pos[0]) - - def test_simple_graph_fixed_not_pos(self): - with self.assertRaises(ValueError): - retworkx.spring_layout(self.graph, fixed={0}) - - def test_simple_graph_linear_cooling(self): - res = retworkx.spring_layout(self.graph, adaptive_cooling=False) - self.assertEqual(len(res), 3) - self.assertEqual(len(res[0]), 2) - self.assertIsInstance(res[0][0], float) - - def test_graph_with_removed_nodes(self): - graph = retworkx.PyGraph() - nodes = graph.add_nodes_from([0, 1, 2]) - graph.remove_node(nodes[1]) - res = retworkx.spring_layout(graph) - self.assertEqual(len(res), 2) - self.assertTrue(nodes[0] in res) - self.assertTrue(nodes[2] in res) - self.assertFalse(nodes[1] in res) diff --git a/tests/retworkx_backwards_compat/graph/test_steiner_tree.py b/tests/retworkx_backwards_compat/graph/test_steiner_tree.py deleted file mode 100644 index 703caf4993..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_steiner_tree.py +++ /dev/null @@ -1,188 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import pprint -import unittest - -import retworkx - - -class TestSteinerTree(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph(multigraph=False) - self.graph.add_node(None) - self.graph.extend_from_weighted_edge_list( - [ - (1, 2, 10), - (2, 3, 10), - (3, 4, 10), - (4, 5, 10), - (5, 6, 10), - (2, 7, 1), - (7, 5, 1), - ] - ) - self.graph.remove_node(0) - - def test_metric_closure(self): - closure_graph = retworkx.metric_closure(self.graph, weight_fn=float) - expected_edges = [ - (1, 2, (10.0, [1, 2])), - (1, 3, (20.0, [1, 2, 3])), - (1, 4, (22.0, [1, 2, 7, 5, 4])), - (1, 5, (12.0, [1, 2, 7, 5])), - (1, 6, (22.0, [1, 2, 7, 5, 6])), - (1, 7, (11.0, [1, 2, 7])), - (2, 3, (10.0, [2, 3])), - (2, 4, (12.0, [2, 7, 5, 4])), - (2, 5, (2.0, [2, 7, 5])), - (2, 6, (12, [2, 7, 5, 6])), - (2, 7, (1.0, [2, 7])), - (3, 4, (10.0, [3, 4])), - (3, 5, (12.0, [3, 2, 7, 5])), - (3, 6, (22.0, [3, 2, 7, 5, 6])), - (3, 7, (11.0, [3, 2, 7])), - (4, 5, (10.0, [4, 5])), - (4, 6, (20.0, [4, 5, 6])), - (4, 7, (11.0, [4, 5, 7])), - (5, 6, (10.0, [5, 6])), - (5, 7, (1.0, [5, 7])), - (6, 7, (11.0, [6, 5, 7])), - ] - edges = list(closure_graph.weighted_edge_list()) - for edge in expected_edges: - found = False - if edge in edges: - found = True - if not found: - - if ( - edge[1], - edge[0], - (edge[2][0], list(reversed(edge[2][1]))), - ) in edges: - found = True - if not found: - self.fail( - f"edge: {edge} nor it's reverse not found in metric " - f"closure output:\n{pprint.pformat(edges)}" - ) - - def test_not_connected_metric_closure(self): - self.graph.add_node(None) - with self.assertRaises(ValueError): - retworkx.metric_closure(self.graph, weight_fn=float) - - def test_partially_connected_metric_closure(self): - graph = retworkx.PyGraph() - graph.add_node(None) - graph.extend_from_weighted_edge_list( - [ - (1, 2, 10), - (2, 3, 10), - (3, 4, 10), - (4, 5, 10), - (5, 6, 10), - (2, 7, 1), - (7, 5, 1), - ] - ) - graph.extend_from_weighted_edge_list( - [ - (0, 8, 20), - (0, 9, 20), - (0, 10, 20), - (8, 10, 10), - (9, 10, 5), - ] - ) - with self.assertRaises(ValueError): - retworkx.metric_closure(graph, weight_fn=float) - - def test_metric_closure_empty_graph(self): - graph = retworkx.PyGraph() - closure = retworkx.metric_closure(graph, weight_fn=float) - self.assertEqual([], closure.weighted_edge_list()) - - def test_steiner_graph(self): - steiner_tree = retworkx.steiner_tree(self.graph, [1, 2, 3, 4, 5], weight_fn=float) - expected_steiner_tree = [ - (1, 2, 10), - (2, 3, 10), - (2, 7, 1), - (3, 4, 10), - (7, 5, 1), - ] - steiner_tree_edge_list = steiner_tree.weighted_edge_list() - for edge in expected_steiner_tree: - self.assertIn(edge, steiner_tree_edge_list) - - def test_steiner_graph_multigraph(self): - edge_list = [ - (1, 2, 1), - (2, 3, 999), - (2, 3, 1), - (3, 4, 1), - (3, 5, 1), - ] - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list(edge_list) - graph.remove_node(0) - terminal_nodes = [2, 4, 5] - tree = retworkx.steiner_tree(graph, terminal_nodes, weight_fn=float) - expected_edges = [ - (2, 3, 1), - (3, 4, 1), - (3, 5, 1), - ] - steiner_tree_edge_list = tree.weighted_edge_list() - for edge in expected_edges: - self.assertIn(edge, steiner_tree_edge_list) - - def test_not_connected_steiner_tree(self): - self.graph.add_node(None) - with self.assertRaises(ValueError): - retworkx.steiner_tree(self.graph, [1, 2, 8], weight_fn=float) - - def test_steiner_tree_empty_graph(self): - graph = retworkx.PyGraph() - tree = retworkx.steiner_tree(graph, [], weight_fn=float) - self.assertEqual([], tree.weighted_edge_list()) - - def test_equal_distance_graph(self): - n = 3 - graph = retworkx.PyGraph() - graph.add_nodes_from(range(n + 5)) - graph.add_edges_from( - [ - (n, n + 1, 0.5), - (n, n + 2, 0.5), - (n + 1, n + 2, 0.5), - (n, n + 3, 0.5), - (n + 1, n + 4, 0.5), - ] - ) - graph.add_edges_from([(i, n + 2, 2) for i in range(n)]) - terminals = list(range(5)) + [n + 3, n + 4] - tree = retworkx.steiner_tree(graph, terminals, weight_fn=float) - # Assert no cycle - self.assertEqual(retworkx.cycle_basis(tree), []) - expected_edges = [ - (3, 4, 0.5), - (4, 5, 0.5), - (3, 6, 0.5), - (4, 7, 0.5), - (0, 5, 2), - (1, 5, 2), - (2, 5, 2), - ] - self.assertEqual(tree.weighted_edge_list(), expected_edges) diff --git a/tests/retworkx_backwards_compat/graph/test_subgraph.py b/tests/retworkx_backwards_compat/graph/test_subgraph.py deleted file mode 100644 index 2f02596409..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_subgraph.py +++ /dev/null @@ -1,150 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestSubgraph(unittest.TestCase): - def test_subgraph(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([1, 3]) - self.assertEqual([(0, 1, 4)], subgraph.weighted_edge_list()) - self.assertEqual(["b", "d"], subgraph.nodes()) - - def test_subgraph_empty_list(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([]) - self.assertEqual([], subgraph.weighted_edge_list()) - self.assertEqual(0, len(subgraph)) - - def test_subgraph_invalid_entry(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([42]) - self.assertEqual([], subgraph.weighted_edge_list()) - self.assertEqual(0, len(subgraph)) - - def test_subgraph_pass_by_reference(self): - graph = retworkx.PyGraph() - graph.add_node({"a": 0}) - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([0, 1, 3]) - self.assertEqual([(0, 1, 1), (0, 2, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - self.assertEqual([{"a": 0}, "b", "d"], subgraph.nodes()) - graph[0]["a"] = 4 - self.assertEqual(subgraph[0]["a"], 4) - - def test_subgraph_replace_weight_no_reference(self): - graph = retworkx.PyGraph() - graph.add_node({"a": 0}) - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([0, 1, 3]) - self.assertEqual([(0, 1, 1), (0, 2, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - self.assertEqual([{"a": 0}, "b", "d"], subgraph.nodes()) - graph[0] = 4 - self.assertEqual(subgraph[0]["a"], 0) - - def test_edge_subgraph(self): - graph = retworkx.PyGraph() - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.edge_subgraph([(0, 1), (1, 3)]) - self.assertEqual(["a", "b", "d"], subgraph.nodes()) - self.assertEqual([(0, 1, 1), (1, 3, 4)], subgraph.weighted_edge_list()) - - def test_edge_subgraph_parallel_edge(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.extend_from_weighted_edge_list( - [ - (0, 1, 2), - (0, 1, 3), - (0, 2, 2), - (1, 2, 4), - (0, 3, 5), - (2, 3, 6), - ] - ) - subgraph = graph.edge_subgraph([(0, 1), (1, 2)]) - self.assertEqual([0, 1, 2], subgraph.nodes()) - self.assertEqual([(0, 1, 2), (0, 1, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - - def test_edge_subgraph_empty_list(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.extend_from_weighted_edge_list( - [ - (0, 1, 2), - (0, 1, 3), - (0, 2, 2), - (1, 2, 4), - (0, 3, 5), - (2, 3, 6), - ] - ) - subgraph = graph.edge_subgraph([]) - self.assertEqual([], subgraph.nodes()) - - def test_edge_subgraph_non_edge(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(4))) - graph.extend_from_weighted_edge_list( - [ - (0, 1, 2), - (0, 1, 3), - (0, 2, 2), - (1, 2, 4), - (0, 3, 5), - (2, 3, 6), - ] - ) - # 1->3 isn't an edge in graph - subgraph = graph.edge_subgraph([(0, 1), (1, 2), (1, 3)]) - self.assertEqual([0, 1, 2], subgraph.nodes()) - self.assertEqual([(0, 1, 2), (0, 1, 3), (1, 2, 4)], subgraph.weighted_edge_list()) - - def test_preserve_attrs(self): - graph = retworkx.PyGraph(attrs="My attribute") - graph.add_node("a") - graph.add_node("b") - graph.add_node("c") - graph.add_node("d") - graph.add_edges_from([(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 3, 4)]) - subgraph = graph.subgraph([1, 3], preserve_attrs=True) - self.assertEqual([(0, 1, 4)], subgraph.weighted_edge_list()) - self.assertEqual(["b", "d"], subgraph.nodes()) - self.assertEqual(graph.attrs, subgraph.attrs) diff --git a/tests/retworkx_backwards_compat/graph/test_subgraph_isomorphic.py b/tests/retworkx_backwards_compat/graph/test_subgraph_isomorphic.py deleted file mode 100644 index 3fa842443c..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_subgraph_isomorphic.py +++ /dev/null @@ -1,296 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestSubgraphIsomorphic(unittest.TestCase): - def test_empty_subgraph_isomorphic_identical(self): - g_a = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_a, id_order=id_order)) - - def test_empty_subgraph_isomorphic(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order)) - - def test_empty_subgraph_isomorphic_compare_nodes(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_subgraph_isomorphic( - g_a, g_b, lambda x, y: x == y, id_order=id_order - ) - ) - - def test_subgraph_isomorphic_identical(self): - g_a = retworkx.PyGraph() - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_a, id_order=id_order)) - - def test_subgraph_isomorphic_mismatch_node_data(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["b_1", "b_2", "b_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "b_1"), (nodes[1], nodes[2], "b_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order)) - - def test_subgraph_isomorphic_compare_nodes_mismatch_node_data(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["b_1", "b_2", "b_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "b_1"), (nodes[1], nodes[2], "b_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse( - retworkx.is_subgraph_isomorphic( - g_a, g_b, lambda x, y: x == y, id_order=id_order - ) - ) - - def test_subgraph_isomorphic_compare_nodes_identical(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_subgraph_isomorphic( - g_a, g_b, lambda x, y: x == y, id_order=id_order - ) - ) - - def test_is_subgraph_isomorphic_nodes_compare_raises(self): - g_a = retworkx.PyGraph() - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - - def compare_nodes(a, b): - raise TypeError("Failure") - - self.assertRaises( - TypeError, - retworkx.is_subgraph_isomorphic, - (g_a, g_a, compare_nodes), - ) - - def test_subgraph_isomorphic_compare_edges_identical(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3", "a_4"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[0], nodes[3], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertTrue( - retworkx.is_subgraph_isomorphic( - g_a, - g_b, - edge_matcher=lambda x, y: x == y, - id_order=id_order, - ) - ) - - def test_subgraph_isomorphic_node_count_not_ge(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2"]) - g_a.add_edges_from([(nodes[0], nodes[1], "a_1")]) - - nodes = g_b.add_nodes_from(["a_0", "a_1", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order): - self.assertFalse(retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order)) - - def test_non_induced_subgraph_isomorphic(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - - nodes = g_a.add_nodes_from(["a_1", "a_2", "a_3"]) - g_a.add_edges_from( - [ - (nodes[0], nodes[1], "a_1"), - (nodes[1], nodes[2], "a_2"), - (nodes[2], nodes[0], "a_3"), - ] - ) - - nodes = g_b.add_nodes_from(["a_1", "a_2", "a_3"]) - g_b.add_edges_from([(nodes[0], nodes[1], "a_1"), (nodes[1], nodes[2], "a_2")]) - for id_order in [False, True]: - with self.subTest(id_order=id_order, induced=True): - self.assertFalse( - retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order, induced=True) - ) - with self.subTest(id_order=id_order, induced=False): - self.assertTrue( - retworkx.is_subgraph_isomorphic(g_a, g_b, id_order=id_order, induced=False) - ) - - def test_subgraph_isomorphic_edge_matcher(self): - first = retworkx.PyGraph() - first.extend_from_weighted_edge_list([(0, 1, "a"), (1, 2, "b"), (2, 0, "c")]) - second = retworkx.PyGraph() - second.extend_from_weighted_edge_list([(0, 1, "a"), (1, 2, "b")]) - - self.assertTrue( - retworkx.is_subgraph_isomorphic( - first, second, induced=False, edge_matcher=lambda x, y: x == y - ) - ) - - def test_subgraph_isomorphic_mismatch_edge_data_parallel_edges(self): - first = retworkx.PyGraph() - first.extend_from_weighted_edge_list([(0, 1, "a"), (0, 1, "f"), (1, 2, "b"), (2, 0, "c")]) - second = retworkx.PyGraph() - second.extend_from_weighted_edge_list([(0, 1, "a"), (0, 1, "a"), (1, 2, "b")]) - - self.assertFalse( - retworkx.is_subgraph_isomorphic( - first, second, id_order=True, edge_matcher=lambda x, y: x == y - ) - ) - - def test_subgraph_isomorphic_parallel_edges(self): - first = retworkx.PyGraph() - first.extend_from_edge_list([(0, 1), (1, 2), (2, 3)]) - second = retworkx.PyGraph() - second.extend_from_edge_list([(0, 1), (0, 1)]) - self.assertFalse(retworkx.is_subgraph_isomorphic(first, second, induced=True)) - self.assertFalse(retworkx.is_subgraph_isomorphic(first, second, induced=False)) - - def test_non_induced_grid_subgraph_isomorphic(self): - g_a = retworkx.generators.grid_graph(2, 2) - g_b = retworkx.PyGraph() - g_b.add_nodes_from([0, 1, 2, 3]) - g_b.add_edges_from_no_data([(0, 1), (2, 3)]) - - self.assertFalse(retworkx.is_subgraph_isomorphic(g_a, g_b, induced=True)) - - self.assertTrue(retworkx.is_subgraph_isomorphic(g_a, g_b, induced=False)) - - def test_non_induced_subgraph_isomorphic_parallel_edges(self): - first = retworkx.PyGraph() - first.extend_from_edge_list([(0, 1), (0, 1), (1, 2), (1, 2)]) - second = retworkx.PyGraph() - second.extend_from_edge_list([(0, 1), (1, 2), (1, 2)]) - self.assertFalse(retworkx.is_subgraph_isomorphic(first, second, induced=True)) - self.assertTrue(retworkx.is_subgraph_isomorphic(first, second, induced=False)) - - def test_subgraph_vf2_mapping(self): - graph = retworkx.generators.grid_graph(10, 10) - second_graph = retworkx.generators.grid_graph(2, 2) - mapping = retworkx.graph_vf2_mapping(graph, second_graph, subgraph=True) - self.assertEqual(next(mapping), {0: 0, 1: 1, 10: 2, 11: 3}) - - def test_subgraph_vf2_all_mappings(self): - graph = retworkx.generators.path_graph(3) - second_graph = retworkx.generators.path_graph(2) - mapping = retworkx.graph_vf2_mapping(graph, second_graph, subgraph=True, id_order=True) - self.assertEqual(next(mapping), {0: 0, 1: 1}) - self.assertEqual(next(mapping), {0: 1, 1: 0}) - self.assertEqual(next(mapping), {2: 1, 1: 0}) - self.assertEqual(next(mapping), {1: 1, 2: 0}) - - def test_subgraph_vf2_mapping_vf2pp(self): - graph = retworkx.generators.grid_graph(3, 3) - second_graph = retworkx.generators.grid_graph(2, 2) - mapping = retworkx.graph_vf2_mapping(graph, second_graph, subgraph=True, id_order=False) - self.assertEqual(next(mapping), {4: 0, 3: 2, 0: 3, 1: 1}) - - def test_vf2pp_remapping(self): - temp = retworkx.generators.grid_graph(3, 3) - - graph = retworkx.PyGraph() - dummy = graph.add_node(0) - - graph.compose(temp, dict()) - graph.remove_node(dummy) - - second_graph = retworkx.generators.grid_graph(2, 2) - mapping = retworkx.graph_vf2_mapping(graph, second_graph, subgraph=True, id_order=False) - self.assertEqual(next(mapping), {5: 0, 4: 2, 1: 3, 2: 1}) - - def test_empty_subgraph_vf2_mapping(self): - g_a = retworkx.PyGraph() - g_b = retworkx.PyGraph() - for id_order in [False, True]: - with self.subTest(id_order=id_order): - mapping = retworkx.graph_vf2_mapping(g_a, g_b, id_order=id_order, subgraph=True) - self.assertEqual({}, next(mapping)) - - def test_subgraph_vf2_mapping_out_size(self): - first = retworkx.PyGraph() - first.add_nodes_from([0, 1, 2, 3]) - first.add_edges_from_no_data([(0, 1), (0, 2), (1, 2), (2, 3)]) - second = retworkx.PyGraph() - second.add_nodes_from([0, 1, 2, 3]) - second.add_edges_from_no_data([(0, 1), (0, 2), (1, 3)]) - mapping = retworkx.graph_vf2_mapping( - first, second, subgraph=True, id_order=True, induced=False - ) - self.assertEqual(next(mapping), {0: 0, 1: 2, 2: 1, 3: 3}) diff --git a/tests/retworkx_backwards_compat/graph/test_tensor_product.py b/tests/retworkx_backwards_compat/graph/test_tensor_product.py deleted file mode 100644 index 9d282b0bbc..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_tensor_product.py +++ /dev/null @@ -1,112 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestTensorProduct(unittest.TestCase): - def test_null_tensor_null(self): - graph_1 = retworkx.PyGraph() - graph_2 = retworkx.PyGraph() - - graph_product, _ = retworkx.graph_tensor_product(graph_1, graph_2) - self.assertEqual(graph_product.num_nodes(), 0) - self.assertEqual(graph_product.num_edges(), 0) - - def test_path_2_tensor_path_2(self): - graph_1 = retworkx.generators.path_graph(2) - graph_2 = retworkx.generators.path_graph(2) - - graph_product, node_map = retworkx.graph_tensor_product(graph_1, graph_2) - - expected_node_map = {(0, 0): 0, (0, 1): 1, (1, 0): 2, (1, 1): 3} - self.assertEqual(node_map, expected_node_map) - - expected_edges = [(0, 3), (1, 2)] - self.assertEqual(graph_product.num_nodes(), 4) - self.assertEqual(graph_product.num_edges(), 2) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_path_2_tensor_path_3(self): - graph_1 = retworkx.generators.path_graph(2) - graph_2 = retworkx.generators.path_graph(3) - - graph_product, node_map = retworkx.graph_tensor_product(graph_1, graph_2) - expected_node_map = {(0, 1): 1, (1, 0): 3, (0, 0): 0, (1, 2): 5, (0, 2): 2, (1, 1): 4} - self.assertEqual(dict(node_map), expected_node_map) - - expected_edges = [(0, 4), (1, 5), (1, 3), (2, 4)] - self.assertEqual(graph_product.num_nodes(), 6) - self.assertEqual(graph_product.num_edges(), 4) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_node_weights_tensor(self): - graph_1 = retworkx.PyGraph() - graph_1.add_node("a_1") - graph_2 = retworkx.PyGraph() - graph_2.add_node(0) - - graph_product, _ = retworkx.graph_tensor_product(graph_1, graph_2) - self.assertEqual([("a_1", 0)], graph_product.nodes()) - - def test_edge_weights_tensor(self): - graph_1 = retworkx.PyGraph() - graph_1.add_nodes_from([0, 1]) - graph_1.add_edge(0, 1, "w_1") - - graph_2 = retworkx.PyGraph() - graph_2.add_nodes_from([0, 1]) - graph_2.add_edge(0, 1, "w_2") - - graph_product, _ = retworkx.graph_tensor_product(graph_1, graph_2) - self.assertEqual([("w_1", "w_2"), ("w_1", "w_2")], graph_product.edges()) - - def test_multi_graph_1(self): - graph_1 = retworkx.generators.path_graph(2) - graph_1.add_edge(0, 1, None) - graph_2 = retworkx.generators.path_graph(2) - - graph_product, _ = retworkx.graph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 3), (1, 2), (1, 2)] - self.assertEqual(graph_product.num_edges(), 4) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_multi_graph_2(self): - graph_1 = retworkx.generators.path_graph(2) - graph_1.add_edge(0, 0, None) - graph_2 = retworkx.generators.path_graph(2) - - graph_product, _ = retworkx.graph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 1), (1, 2)] - self.assertEqual(graph_product.num_edges(), 3) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_multi_graph_3(self): - graph_1 = retworkx.generators.path_graph(2) - graph_2 = retworkx.generators.path_graph(2) - graph_2.add_edge(0, 1, None) - - graph_product, _ = retworkx.graph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 3), (1, 2), (1, 2)] - self.assertEqual(graph_product.num_edges(), 4) - self.assertEqual(graph_product.edge_list(), expected_edges) - - def test_multi_graph_4(self): - graph_1 = retworkx.generators.path_graph(2) - graph_2 = retworkx.generators.path_graph(2) - graph_2.add_edge(0, 0, None) - - graph_product, _ = retworkx.graph_tensor_product(graph_1, graph_2) - expected_edges = [(0, 3), (0, 2), (1, 2)] - self.assertEqual(graph_product.num_edges(), 3) - self.assertEqual(graph_product.edge_list(), expected_edges) diff --git a/tests/retworkx_backwards_compat/graph/test_to_directed.py b/tests/retworkx_backwards_compat/graph/test_to_directed.py deleted file mode 100644 index 16b97b8661..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_to_directed.py +++ /dev/null @@ -1,79 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestToDirected(unittest.TestCase): - def test_to_undirected_empty_graph(self): - graph = retworkx.PyGraph() - digraph = graph.to_directed() - self.assertEqual(0, len(digraph)) - - def test_path_graph(self): - graph = retworkx.generators.path_graph(5) - digraph = graph.to_directed() - expected = [ - (0, 1, None), - (1, 0, None), - (1, 2, None), - (2, 1, None), - (2, 3, None), - (3, 2, None), - (3, 4, None), - (4, 3, None), - ] - self.assertEqual(digraph.weighted_edge_list(), expected) - - def test_parallel_edge_graph(self): - graph = retworkx.PyGraph() - graph.extend_from_weighted_edge_list( - [ - (0, 1, "A"), - (0, 1, "B"), - (0, 2, "C"), - (0, 3, "D"), - ] - ) - digraph = graph.to_directed() - expected = [ - (0, 1, "A"), - (1, 0, "A"), - (0, 1, "B"), - (1, 0, "B"), - (0, 2, "C"), - (2, 0, "C"), - (0, 3, "D"), - (3, 0, "D"), - ] - self.assertEqual(digraph.weighted_edge_list(), expected) - - def test_shared_ref(self): - graph = retworkx.PyGraph() - node_weight = {"a": 1} - node_a = graph.add_node(node_weight) - edge_weight = {"a": 1} - node_b = graph.add_node("b") - graph.add_edge(node_a, node_b, edge_weight) - digraph = graph.to_directed() - self.assertEqual(digraph[node_a], {"a": 1}) - self.assertEqual(graph[node_a], {"a": 1}) - node_weight["b"] = 2 - self.assertEqual(digraph[node_a], {"a": 1, "b": 2}) - self.assertEqual(graph[node_a], {"a": 1, "b": 2}) - self.assertEqual(digraph.get_edge_data(0, 1), {"a": 1}) - self.assertEqual(graph.get_edge_data(0, 1), {"a": 1}) - edge_weight["b"] = 2 - self.assertEqual(digraph.get_edge_data(0, 1), {"a": 1, "b": 2}) - self.assertEqual(graph.get_edge_data(0, 1), {"a": 1, "b": 2}) diff --git a/tests/retworkx_backwards_compat/graph/test_transitivity.py b/tests/retworkx_backwards_compat/graph/test_transitivity.py deleted file mode 100644 index 5d7d8fed8a..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_transitivity.py +++ /dev/null @@ -1,49 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import retworkx - - -class TestTransitivity(unittest.TestCase): - def test_transitivity(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(5))) - graph.add_edges_from_no_data([(0, 1), (0, 2), (0, 3), (0, 4), (1, 2)]) - res = retworkx.transitivity(graph) - self.assertEqual(res, 3 / 8) - - def test_transitivity_triangle(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(3))) - graph.add_edges_from_no_data([(0, 1), (0, 2), (1, 2)]) - res = retworkx.transitivity(graph) - self.assertEqual(res, 1.0) - - def test_transitivity_star(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(5))) - graph.add_edges_from_no_data([(0, 1), (0, 2), (0, 3), (0, 4)]) - res = retworkx.transitivity(graph) - self.assertEqual(res, 0.0) - - def test_transitivity_empty(self): - graph = retworkx.PyGraph() - res = retworkx.transitivity(graph) - self.assertEqual(res, 0.0) - - def test_transitivity_disconnected(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(3))) - res = retworkx.transitivity(graph) - self.assertEqual(res, 0.0) diff --git a/tests/retworkx_backwards_compat/graph/test_union.py b/tests/retworkx_backwards_compat/graph/test_union.py deleted file mode 100644 index 6ada9c331b..0000000000 --- a/tests/retworkx_backwards_compat/graph/test_union.py +++ /dev/null @@ -1,74 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - - -class TestUnion(unittest.TestCase): - def setUp(self): - self.graph = retworkx.PyGraph() - self.graph.add_nodes_from(["a_1", "a_2", "a_3"]) - self.graph.extend_from_weighted_edge_list([(0, 1, "e_1"), (1, 2, "e_2")]) - - def test_union_basic_merge_none(self): - final = retworkx.graph_union(self.graph, self.graph, merge_nodes=False, merge_edges=False) - self.assertTrue(len(final.nodes()) == 6) - self.assertTrue(len(final.edge_list()) == 4) - - def test_union_merge_all(self): - final = retworkx.graph_union(self.graph, self.graph, merge_nodes=True, merge_edges=True) - self.assertTrue(retworkx.is_isomorphic(final, self.graph)) - - def test_union_basic_merge_nodes_only(self): - final = retworkx.graph_union(self.graph, self.graph, merge_nodes=True, merge_edges=False) - self.assertTrue(len(final.edge_list()) == 4) - self.assertTrue(len(final.get_all_edge_data(0, 1)) == 2) - self.assertTrue(len(final.nodes()) == 3) - - def test_union_mismatch_edge_weight(self): - first = retworkx.PyGraph() - nodes = first.add_nodes_from([0, 1]) - first.add_edges_from([(nodes[0], nodes[1], "a")]) - - second = retworkx.PyGraph() - nodes = second.add_nodes_from([0, 1]) - second.add_edges_from([(nodes[0], nodes[1], "b")]) - - final = retworkx.graph_union(first, second, merge_nodes=True, merge_edges=True) - self.assertEqual(final.weighted_edge_list(), [(0, 1, "a"), (0, 1, "b")]) - - def test_union_node_hole(self): - first = retworkx.PyGraph() - nodes = first.add_nodes_from([0, 1]) - first.add_edges_from([(nodes[0], nodes[1], "a")]) - - second = retworkx.PyGraph() - dummy = second.add_node("dummy") - nodes = second.add_nodes_from([0, 1]) - second.add_edges_from([(nodes[0], nodes[1], "a")]) - second.remove_node(dummy) - - final = retworkx.graph_union(first, second, merge_nodes=True, merge_edges=True) - self.assertEqual(final.weighted_edge_list(), [(0, 1, "a")]) - - def test_union_edge_between_merged_and_unmerged_nodes(self): - first = retworkx.PyGraph() - nodes = first.add_nodes_from([0, 1]) - first.add_edges_from([(nodes[0], nodes[1], "a")]) - - second = retworkx.PyGraph() - nodes = second.add_nodes_from([0, 2]) - second.add_edges_from([(nodes[0], nodes[1], "b")]) - - final = retworkx.graph_union(first, second, merge_nodes=True, merge_edges=True) - self.assertEqual(final.weighted_edge_list(), [(0, 1, "a"), (0, 2, "b")]) diff --git a/tests/retworkx_backwards_compat/test_converters.py b/tests/retworkx_backwards_compat/test_converters.py deleted file mode 100644 index df753b72c8..0000000000 --- a/tests/retworkx_backwards_compat/test_converters.py +++ /dev/null @@ -1,117 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx -import networkx - - -class TestNetworkxConverter(unittest.TestCase): - def test_undirected_gnm_graph(self): - g = networkx.gnm_random_graph(10, 10, seed=42) - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_directed_gnm_graph(self): - g = networkx.gnm_random_graph(10, 10, seed=42, directed=True) - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyDiGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_empty_graph(self): - g = networkx.Graph() - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_empty_multigraph(self): - g = networkx.MultiGraph() - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_empty_directed_graph(self): - g = networkx.DiGraph() - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyDiGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_empty_directed_multigraph(self): - g = networkx.MultiDiGraph() - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyDiGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_cubical_graph(self): - g = networkx.cubical_graph(networkx.Graph) - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_cubical_multigraph(self): - g = networkx.cubical_graph(networkx.MultiGraph) - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_random_k_out_graph(self): - g = networkx.random_k_out_graph(100, 50, 3.14159, True, 42) - for keep_attributes in [True, False]: - with self.subTest(keep_attributes=keep_attributes): - out_graph = retworkx.networkx_converter(g, keep_attributes=keep_attributes) - self.assertIsInstance(out_graph, retworkx.PyDiGraph) - self.assertEqual(list(out_graph.node_indexes()), list(g.nodes)) - self.assertEqual(out_graph.weighted_edge_list(), list(g.edges(data=True))) - self.assertEqual(out_graph.multigraph, g.is_multigraph()) - - def test_networkx_graph_attributes_are_converted(self): - g = networkx.Graph() - for node in range(100): - g.add_node(str(node), test=True) - - out_graph = retworkx.networkx_converter(g, keep_attributes=True) - for node in out_graph.node_indexes(): - self.assertEqual(out_graph[node]["test"], True) - self.assertEqual(out_graph[node]["__networkx_node__"], str(node)) diff --git a/tests/retworkx_backwards_compat/test_custom_return_types.py b/tests/retworkx_backwards_compat/test_custom_return_types.py deleted file mode 100644 index a3bb14260d..0000000000 --- a/tests/retworkx_backwards_compat/test_custom_return_types.py +++ /dev/null @@ -1,1561 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import pickle -import unittest - -import retworkx -import numpy as np - - -class TestBFSSuccessorsComparisons(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - self.node_a = self.dag.add_node("a") - self.node_b = self.dag.add_child(self.node_a, "b", "Edgy") - - def test__eq__match(self): - self.assertTrue(retworkx.bfs_successors(self.dag, 0) == [("a", ["b"])]) - - def test__eq__not_match(self): - self.assertFalse(retworkx.bfs_successors(self.dag, 0) == [("b", ["c"])]) - - def test_eq_not_match_inner(self): - self.assertFalse(retworkx.bfs_successors(self.dag, 0) == [("a", ["c"])]) - - def test__eq__different_length(self): - self.assertFalse(retworkx.bfs_successors(self.dag, 0) == [("a", ["b"]), ("b", ["c"])]) - - def test__eq__invalid_type(self): - with self.assertRaises(TypeError): - retworkx.bfs_successors(self.dag, 0) == ["a"] - - def test__ne__match(self): - self.assertFalse(retworkx.bfs_successors(self.dag, 0) != [("a", ["b"])]) - - def test__ne__not_match(self): - self.assertTrue(retworkx.bfs_successors(self.dag, 0) != [("b", ["c"])]) - - def test_ne_not_match_inner(self): - self.assertTrue(retworkx.bfs_successors(self.dag, 0) != [("a", ["c"])]) - - def test__ne__different_length(self): - self.assertTrue(retworkx.bfs_successors(self.dag, 0) != [("a", ["b"]), ("b", ["c"])]) - - def test__ne__invalid_type(self): - with self.assertRaises(TypeError): - retworkx.bfs_successors(self.dag, 0) != ["a"] - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - retworkx.bfs_successors(self.dag, 0) > [("b", ["c"])] - - def test_deepcopy(self): - bfs = retworkx.bfs_successors(self.dag, 0) - bfs_copy = copy.deepcopy(bfs) - self.assertEqual(bfs, bfs_copy) - - def test_pickle(self): - bfs = retworkx.bfs_successors(self.dag, 0) - bfs_pickle = pickle.dumps(bfs) - bfs_copy = pickle.loads(bfs_pickle) - self.assertEqual(bfs, bfs_copy) - - def test_str(self): - res = retworkx.bfs_successors(self.dag, 0) - self.assertEqual("BFSSuccessors[(a, [b])]", str(res)) - - def test_hash(self): - res = retworkx.bfs_successors(self.dag, 0) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_hash_invalid_type(self): - self.dag.add_child(0, [1, 2, 3], "edgy") - res = retworkx.bfs_successors(self.dag, 0) - with self.assertRaises(TypeError): - hash(res) - - def test_slices(self): - self.dag.add_child(self.node_a, "c", "New edge") - self.dag.add_child(self.node_b, "d", "New edge to d") - successors = retworkx.bfs_successors(self.dag, 0) - slice_return = successors[0:3:2] - self.assertEqual([("a", ["c", "b"])], slice_return) - - -class TestNodeIndicesComparisons(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - - def test__eq__match(self): - self.assertTrue(self.dag.node_indexes() == [0, 1]) - - def test__eq__not_match(self): - self.assertFalse(self.dag.node_indexes() == [1, 2]) - - def test__eq__different_length(self): - self.assertFalse(self.dag.node_indexes() == [0, 1, 2, 3]) - - def test__eq__invalid_type(self): - with self.assertRaises(TypeError): - self.dag.node_indexes() == ["a", None] - - def test__ne__match(self): - self.assertFalse(self.dag.node_indexes() != [0, 1]) - - def test__ne__not_match(self): - self.assertTrue(self.dag.node_indexes() != [1, 2]) - - def test__ne__different_length(self): - self.assertTrue(self.dag.node_indexes() != [0, 1, 2, 3]) - - def test__ne__invalid_type(self): - with self.assertRaises(TypeError): - self.dag.node_indexes() != ["a", None] - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.dag.node_indexes() > [2, 1] - - def test_deepcopy(self): - nodes = self.dag.node_indexes() - nodes_copy = copy.deepcopy(nodes) - self.assertEqual(nodes, nodes_copy) - - def test_pickle(self): - nodes = self.dag.node_indexes() - nodes_pickle = pickle.dumps(nodes) - nodes_copy = pickle.loads(nodes_pickle) - self.assertEqual(nodes, nodes_copy) - - def test_str(self): - res = self.dag.node_indexes() - self.assertEqual("NodeIndices[0, 1]", str(res)) - - def test_hash(self): - res = self.dag.node_indexes() - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_slices(self): - self.dag.add_node("new") - self.dag.add_node("fun") - nodes = self.dag.node_indices() - slice_return = nodes[0:3:2] - self.assertEqual([0, 2], slice_return) - self.assertEqual(nodes[0:-1], [0, 1, 2]) - - def test_slices_negatives(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(range(5)) - indices = graph.node_indices() - slice_return = indices[-1:-3:-1] - self.assertEqual([4, 3], slice_return) - slice_return = indices[3:1:-2] - self.assertEqual([3], slice_return) - slice_return = indices[-3:-1] - self.assertEqual([2, 3], slice_return) - self.assertEqual([], indices[-1:-2]) - - def test_numpy_conversion(self): - res = self.dag.node_indexes() - np.testing.assert_array_equal(np.asarray(res, dtype=np.uintp), np.array([0, 1])) - - -class TestNodesCountMapping(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - - def test__eq__match(self): - self.assertTrue(retworkx.num_shortest_paths_unweighted(self.dag, 0) == {1: 1}) - - def test__eq__not_match_keys(self): - self.assertFalse(retworkx.num_shortest_paths_unweighted(self.dag, 0) == {2: 1}) - - def test__eq__not_match_values(self): - self.assertFalse(retworkx.num_shortest_paths_unweighted(self.dag, 0) == {1: 2}) - - def test__eq__different_length(self): - self.assertFalse(retworkx.num_shortest_paths_unweighted(self.dag, 0) == {1: 1, 2: 2}) - - def test_eq__same_type(self): - self.assertEqual( - retworkx.num_shortest_paths_unweighted(self.dag, 0), - retworkx.num_shortest_paths_unweighted(self.dag, 0), - ) - - def test__eq__invalid_type(self): - self.assertFalse(retworkx.num_shortest_paths_unweighted(self.dag, 0) == ["a", None]) - - def test__eq__invalid_inner_type(self): - self.assertFalse(retworkx.num_shortest_paths_unweighted(self.dag, 0) == {0: "a"}) - - def test__ne__match(self): - self.assertFalse(retworkx.num_shortest_paths_unweighted(self.dag, 0) != {1: 1}) - - def test__ne__not_match(self): - self.assertTrue(retworkx.num_shortest_paths_unweighted(self.dag, 0) != {2: 1}) - - def test__ne__not_match_values(self): - self.assertTrue(retworkx.num_shortest_paths_unweighted(self.dag, 0) != {1: 2}) - - def test__ne__different_length(self): - self.assertTrue(retworkx.num_shortest_paths_unweighted(self.dag, 0) != {1: 1, 2: 2}) - - def test__ne__invalid_type(self): - self.assertTrue(retworkx.num_shortest_paths_unweighted(self.dag, 0) != ["a", None]) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - retworkx.num_shortest_paths_unweighted(self.dag, 0) > {1: 1} - - def test_deepcopy(self): - paths = retworkx.num_shortest_paths_unweighted(self.dag, 0) - paths_copy = copy.deepcopy(paths) - self.assertEqual(paths, paths_copy) - - def test_pickle(self): - paths = retworkx.num_shortest_paths_unweighted(self.dag, 0) - paths_pickle = pickle.dumps(paths) - paths_copy = pickle.loads(paths_pickle) - self.assertEqual(paths, paths_copy) - - def test_str(self): - res = retworkx.num_shortest_paths_unweighted(self.dag, 0) - self.assertEqual("NodesCountMapping{1: 1}", str(res)) - - def test_hash(self): - res = retworkx.num_shortest_paths_unweighted(self.dag, 0) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = retworkx.num_shortest_paths_unweighted(self.dag, 0) - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = retworkx.num_shortest_paths_unweighted(self.dag, 0).keys() - self.assertEqual([1], list(keys)) - - def test_values(self): - values = retworkx.num_shortest_paths_unweighted(self.dag, 0).values() - self.assertEqual([1], list(values)) - - def test_items(self): - items = retworkx.num_shortest_paths_unweighted(self.dag, 0).items() - self.assertEqual([(1, 1)], list(items)) - - def test_iter(self): - mapping_iter = iter(retworkx.num_shortest_paths_unweighted(self.dag, 0)) - output = list(mapping_iter) - self.assertEqual(output, [1]) - - def test_contains(self): - res = retworkx.num_shortest_paths_unweighted(self.dag, 0) - self.assertIn(1, res) - - def test_not_contains(self): - res = retworkx.num_shortest_paths_unweighted(self.dag, 0) - self.assertNotIn(0, res) - - -class TestEdgeIndicesComparisons(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDiGraph() - node_a = self.dag.add_node("a") - node_b = self.dag.add_child(node_a, "b", "Edgy") - self.dag.add_child(node_b, "c", "Super Edgy") - - def test__eq__match(self): - self.assertTrue(self.dag.edge_indices() == [0, 1]) - - def test__eq__not_match(self): - self.assertFalse(self.dag.edge_indices() == [1, 2]) - - def test__eq__different_length(self): - self.assertFalse(self.dag.edge_indices() == [0, 1, 2, 3]) - - def test__eq__invalid_type(self): - with self.assertRaises(TypeError): - self.dag.edge_indices() == ["a", None] - - def test__ne__match(self): - self.assertFalse(self.dag.edge_indices() != [0, 1]) - - def test__ne__not_match(self): - self.assertTrue(self.dag.edge_indices() != [1, 2]) - - def test__ne__different_length(self): - self.assertTrue(self.dag.edge_indices() != [0, 1, 2, 3]) - - def test__ne__invalid_type(self): - with self.assertRaises(TypeError): - self.dag.edge_indices() != ["a", None] - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.dag.edge_indices() > [2, 1] - - def test_deepcopy(self): - edges = self.dag.edge_indices() - edges_copy = copy.deepcopy(edges) - self.assertEqual(edges, edges_copy) - - def test_pickle(self): - edges = self.dag.edge_indices() - edges_pickle = pickle.dumps(edges) - edges_copy = pickle.loads(edges_pickle) - self.assertEqual(edges, edges_copy) - - def test_str(self): - res = self.dag.edge_indices() - self.assertEqual("EdgeIndices[0, 1]", str(res)) - - def test_hash(self): - res = self.dag.edge_indices() - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_slices(self): - self.dag.add_edge(0, 1, None) - edges = self.dag.edge_indices() - slice_return = edges[0:-1] - self.assertEqual([0, 1], slice_return) - - -class TestEdgeListComparisons(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - - def test__eq__match(self): - self.assertTrue(self.dag.edge_list() == [(0, 1)]) - - def test__eq__not_match(self): - self.assertFalse(self.dag.edge_list() == [(1, 2)]) - - def test__eq__different_length(self): - self.assertFalse(self.dag.edge_list() == [(0, 1), (2, 3)]) - - def test__eq__invalid_type(self): - self.assertFalse(self.dag.edge_list() == ["a", None]) - - def test__ne__match(self): - self.assertFalse(self.dag.edge_list() != [(0, 1)]) - - def test__ne__not_match(self): - self.assertTrue(self.dag.edge_list() != [(1, 2)]) - - def test__ne__different_length(self): - self.assertTrue(self.dag.edge_list() != [(0, 1), (2, 3)]) - - def test__ne__invalid_type(self): - self.assertTrue(self.dag.edge_list() != ["a", None]) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.dag.edge_list() > [(2, 1)] - - def test_deepcopy(self): - edges = self.dag.edge_list() - edges_copy = copy.deepcopy(edges) - self.assertEqual(edges, edges_copy) - - def test_pickle(self): - edges = self.dag.edge_list() - edges_pickle = pickle.dumps(edges) - edges_copy = pickle.loads(edges_pickle) - self.assertEqual(edges, edges_copy) - - def test_str(self): - res = self.dag.edge_list() - self.assertEqual("EdgeList[(0, 1)]", str(res)) - - def test_hash(self): - res = self.dag.edge_list() - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_slice(self): - self.dag.add_edge(0, 1, None) - self.dag.add_edge(0, 1, None) - edges = self.dag.edge_list() - slice_return = edges[0:3:2] - self.assertEqual([(0, 1), (0, 1)], slice_return) - - @staticmethod - def test_numpy_conversion(): - g = retworkx.generators.directed_star_graph(5) - res = g.edge_list() - - np.testing.assert_array_equal( - np.asarray(res, dtype=np.uintp), np.array([[0, 1], [0, 2], [0, 3], [0, 4]]) - ) - - -class TestWeightedEdgeListComparisons(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - - def test__eq__match(self): - self.assertTrue(self.dag.weighted_edge_list() == [(0, 1, "Edgy")]) - - def test__eq__not_match(self): - self.assertFalse(self.dag.weighted_edge_list() == [(1, 2, None)]) - - def test__eq__different_length(self): - self.assertFalse(self.dag.weighted_edge_list() == [(0, 1, "Edgy"), (2, 3, "Not Edgy")]) - - def test__eq__invalid_type(self): - self.assertFalse(self.dag.weighted_edge_list() == ["a", None]) - - def test__ne__match(self): - self.assertFalse(self.dag.weighted_edge_list() != [(0, 1, "Edgy")]) - - def test__ne__not_match(self): - self.assertTrue(self.dag.weighted_edge_list() != [(1, 2, "Not Edgy")]) - - def test__ne__different_length(self): - self.assertTrue(self.dag.node_indexes() != [0, 1, 2, 3]) - - def test__ne__invalid_type(self): - self.assertTrue(self.dag.weighted_edge_list() != ["a", None]) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.dag.weighted_edge_list() > [(2, 1, "Not Edgy")] - - def test_deepcopy(self): - edges = self.dag.weighted_edge_list() - edges_copy = copy.deepcopy(edges) - self.assertEqual(edges, edges_copy) - - def test_pickle(self): - edges = self.dag.weighted_edge_list() - edges_pickle = pickle.dumps(edges) - edges_copy = pickle.loads(edges_pickle) - self.assertEqual(edges, edges_copy) - - def test_str(self): - res = self.dag.weighted_edge_list() - self.assertEqual("WeightedEdgeList[(0, 1, Edgy)]", str(res)) - - def test_hash(self): - res = self.dag.weighted_edge_list() - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_hash_invalid_type(self): - self.dag.add_child(0, "c", ["edgy", "not_edgy"]) - res = self.dag.weighted_edge_list() - with self.assertRaises(TypeError): - hash(res) - - def test_slice(self): - self.dag.add_edge(0, 1, None) - self.dag.add_edge(0, 1, None) - edges = self.dag.weighted_edge_list() - slice_return = edges[0:3:2] - self.assertEqual([(0, 1, "Edgy"), (0, 1, None)], slice_return) - - def test_numpy_conversion(self): - np.testing.assert_array_equal( - np.asarray(self.dag.weighted_edge_list()), np.array([(0, 1, "Edgy")], dtype=object) - ) - - -class TestPathMapping(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - - def test__eq__match(self): - self.assertTrue(retworkx.dijkstra_shortest_paths(self.dag, 0) == {1: [0, 1]}) - - def test__eq__not_match_keys(self): - self.assertFalse(retworkx.dijkstra_shortest_paths(self.dag, 0) == {2: [0, 1]}) - - def test__eq__not_match_values(self): - self.assertFalse(retworkx.dijkstra_shortest_paths(self.dag, 0) == {1: [0, 2]}) - - def test__eq__different_length(self): - self.assertFalse(retworkx.dijkstra_shortest_paths(self.dag, 0) == {1: [0, 1], 2: [0, 2]}) - - def test_eq__same_type(self): - self.assertEqual( - retworkx.dijkstra_shortest_paths(self.dag, 0), - retworkx.dijkstra_shortest_paths(self.dag, 0), - ) - - def test__eq__invalid_type(self): - self.assertFalse(retworkx.dijkstra_shortest_paths(self.dag, 0) == ["a", None]) - - def test__eq__invalid_inner_type(self): - self.assertFalse(retworkx.dijkstra_shortest_paths(self.dag, 0) == {0: {"a": None}}) - - def test__ne__match(self): - self.assertFalse(retworkx.dijkstra_shortest_paths(self.dag, 0) != {1: [0, 1]}) - - def test__ne__not_match(self): - self.assertTrue(retworkx.dijkstra_shortest_paths(self.dag, 0) != {2: [0, 1]}) - - def test__ne__not_match_values(self): - self.assertTrue(retworkx.dijkstra_shortest_paths(self.dag, 0) != {1: [0, 2]}) - - def test__ne__different_length(self): - self.assertTrue(retworkx.dijkstra_shortest_paths(self.dag, 0) != {1: [0, 1], 2: [0, 2]}) - - def test__ne__invalid_type(self): - self.assertTrue(retworkx.dijkstra_shortest_paths(self.dag, 0) != ["a", None]) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - retworkx.dijkstra_shortest_paths(self.dag, 0) > {1: [0, 2]} - - def test_deepcopy(self): - paths = retworkx.dijkstra_shortest_paths(self.dag, 0) - paths_copy = copy.deepcopy(paths) - self.assertEqual(paths, paths_copy) - - def test_pickle(self): - paths = retworkx.dijkstra_shortest_paths(self.dag, 0) - paths_pickle = pickle.dumps(paths) - paths_copy = pickle.loads(paths_pickle) - self.assertEqual(paths, paths_copy) - - def test_str(self): - res = retworkx.dijkstra_shortest_paths(self.dag, 0) - self.assertEqual("PathMapping{1: [0, 1]}", str(res)) - - def test_hash(self): - res = retworkx.dijkstra_shortest_paths(self.dag, 0) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = retworkx.dijkstra_shortest_paths(self.dag, 0) - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = retworkx.dijkstra_shortest_paths(self.dag, 0).keys() - self.assertEqual([1], list(keys)) - - def test_values(self): - values = retworkx.dijkstra_shortest_paths(self.dag, 0).values() - self.assertEqual([[0, 1]], list(values)) - - def test_items(self): - items = retworkx.dijkstra_shortest_paths(self.dag, 0).items() - self.assertEqual([(1, [0, 1])], list(items)) - - def test_iter(self): - mapping_iter = iter(retworkx.dijkstra_shortest_paths(self.dag, 0)) - output = list(mapping_iter) - self.assertEqual(output, [1]) - - def test_contains(self): - res = retworkx.dijkstra_shortest_paths(self.dag, 0) - self.assertIn(1, res) - - def test_not_contains(self): - res = retworkx.dijkstra_shortest_paths(self.dag, 0) - self.assertNotIn(0, res) - - -class TestPathLengthMapping(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - self.fn = lambda _: 1.0 - - def test__eq__match(self): - self.assertTrue(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) == {1: 1.0}) - - def test__eq__not_match_keys(self): - self.assertFalse(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) == {2: 1.0}) - - def test__eq__not_match_values(self): - self.assertFalse(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) == {1: 2.0}) - - def test__eq__different_length(self): - self.assertFalse( - retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) == {1: 1.0, 2: 2.0} - ) - - def test_eq__same_type(self): - self.assertEqual( - retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn), - retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn), - ) - - def test__eq__invalid_type(self): - self.assertFalse( - retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) == ["a", None] - ) - - def test__eq__invalid_inner_type(self): - self.assertFalse(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) == {0: "a"}) - - def test__ne__match(self): - self.assertFalse(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) != {1: 1.0}) - - def test__ne__not_match(self): - self.assertTrue(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) != {2: 1.0}) - - def test__ne__not_match_values(self): - self.assertTrue(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) != {1: 2.0}) - - def test__ne__different_length(self): - self.assertTrue( - retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) != {1: 1.0, 2: 2.0} - ) - - def test__ne__invalid_type(self): - self.assertTrue( - retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) != ["a", None] - ) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) > {1: 1.0} - - def test_deepcopy(self): - paths = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) - paths_copy = copy.deepcopy(paths) - self.assertEqual(paths, paths_copy) - - def test_pickle(self): - paths = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) - paths_pickle = pickle.dumps(paths) - paths_copy = pickle.loads(paths_pickle) - self.assertEqual(paths, paths_copy) - - def test_str(self): - res = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, lambda _: 3.14) - self.assertEqual("PathLengthMapping{1: 3.14}", str(res)) - - def test_hash(self): - res = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn).keys() - self.assertEqual([1], list(keys)) - - def test_values(self): - values = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn).values() - self.assertEqual([1.0], list(values)) - - def test_items(self): - items = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn).items() - self.assertEqual([(1, 1.0)], list(items)) - - def test_iter(self): - mapping_iter = iter(retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn)) - output = list(mapping_iter) - self.assertEqual(output, [1]) - - def test_contains(self): - res = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) - self.assertIn(1, res) - - def test_not_contains(self): - res = retworkx.dijkstra_shortest_path_lengths(self.dag, 0, self.fn) - self.assertNotIn(0, res) - - -class TestPos2DMapping(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDiGraph() - self.dag.add_node("a") - - def test__eq__match(self): - res = retworkx.random_layout(self.dag, seed=10244242) - self.assertTrue(res == {0: (0.4883489113112722, 0.6545867364101975)}) - - def test__eq__not_match_keys(self): - self.assertFalse(retworkx.random_layout(self.dag, seed=10244242) == {2: 1.0}) - - def test__eq__not_match_values(self): - self.assertFalse(retworkx.random_layout(self.dag, seed=10244242) == {1: 2.0}) - - def test__eq__different_length(self): - res = retworkx.random_layout(self.dag, seed=10244242) - self.assertFalse(res == {1: 1.0, 2: 2.0}) - - def test_eq__same_type(self): - self.assertEqual( - retworkx.random_layout(self.dag, seed=10244242), - retworkx.random_layout(self.dag, seed=10244242), - ) - - def test__eq__invalid_type(self): - self.assertFalse(retworkx.random_layout(self.dag, seed=10244242) == {"a": None}) - - def test__ne__match(self): - res = retworkx.random_layout(self.dag, seed=10244242) - self.assertFalse(res != {0: (0.4883489113112722, 0.6545867364101975)}) - - def test__ne__not_match(self): - self.assertTrue(retworkx.random_layout(self.dag, seed=10244242) != {2: 1.0}) - - def test__ne__not_match_values(self): - self.assertTrue(retworkx.random_layout(self.dag, seed=10244242) != {1: 2.0}) - - def test__ne__different_length(self): - res = retworkx.random_layout(self.dag, seed=10244242) - - self.assertTrue(res != {1: 1.0, 2: 2.0}) - - def test__ne__invalid_type(self): - self.assertTrue(retworkx.random_layout(self.dag, seed=10244242) != ["a", None]) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - retworkx.random_layout(self.dag, seed=10244242) > {1: 1.0} - - def test_deepcopy(self): - positions = retworkx.random_layout(self.dag) - positions_copy = copy.deepcopy(positions) - self.assertEqual(positions_copy, positions) - - def test_pickle(self): - pos = retworkx.random_layout(self.dag) - pos_pickle = pickle.dumps(pos) - pos_copy = pickle.loads(pos_pickle) - self.assertEqual(pos, pos_copy) - - def test_str(self): - res = retworkx.random_layout(self.dag, seed=10244242) - self.assertEqual( - "Pos2DMapping{0: [0.4883489113112722, 0.6545867364101975]}", - str(res), - ) - - def test_hash(self): - res = retworkx.random_layout(self.dag, seed=10244242) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = retworkx.random_layout(self.dag, seed=10244242) - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = retworkx.random_layout(self.dag, seed=10244242).keys() - self.assertEqual([0], list(keys)) - - def test_values(self): - values = retworkx.random_layout(self.dag, seed=10244242).values() - expected = [[0.4883489113112722, 0.6545867364101975]] - self.assertEqual(expected, list(values)) - - def test_items(self): - items = retworkx.random_layout(self.dag, seed=10244242).items() - self.assertEqual([(0, [0.4883489113112722, 0.6545867364101975])], list(items)) - - def test_iter(self): - mapping_iter = iter(retworkx.random_layout(self.dag, seed=10244242)) - output = list(mapping_iter) - self.assertEqual(output, [0]) - - def test_contains(self): - res = retworkx.random_layout(self.dag, seed=10244242) - self.assertIn(0, res) - - def test_not_contains(self): - res = retworkx.random_layout(self.dag, seed=10244242) - self.assertNotIn(1, res) - - -class TestEdgeIndices(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDiGraph() - self.dag.add_node("a") - self.dag.add_child(0, "b", "edge") - - def test__eq__match(self): - res = self.dag.edge_index_map() - self.assertTrue(res == {0: (0, 1, "edge")}) - - def test__eq__not_match_keys(self): - res = self.dag.edge_index_map() - self.assertFalse(res == {2: (0, 1, "edge")}) - - def test__eq__not_match_values(self): - res = self.dag.edge_index_map() - self.assertFalse(res == {0: (1, 2, "edge")}) - self.assertFalse(res == {0: (0, 1, "not edge")}) - - def test__eq__different_length(self): - res = self.dag.edge_index_map() - self.assertFalse(res == {1: (0, 1, "edge"), 0: (0, 1, "double edge")}) - - def test_eq__same_type(self): - self.assertEqual(self.dag.edge_index_map(), self.dag.edge_index_map()) - - def test__eq__invalid_type(self): - res = self.dag.edge_index_map() - self.assertFalse(res == {"a": ("a", "b", "c")}) - - def test__ne__match(self): - res = self.dag.edge_index_map() - self.assertFalse(res != {0: (0, 1, "edge")}) - - def test__ne__not_match(self): - res = self.dag.edge_index_map() - self.assertTrue(res, {2: (0, 1, "edge")}) - - def test__ne__not_match_values(self): - res = self.dag.edge_index_map() - self.assertTrue(res, {0: (0, 2, "edge")}) - - def test__ne__different_length(self): - res = self.dag.edge_index_map() - self.assertTrue(res != {1: (0, 1, "double edge"), 0: (0, 1, "edge")}) - - def test__ne__invalid_type(self): - res = self.dag.edge_index_map() - self.assertTrue(res != {"a": ("a", "b", "c")}) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.dag.edge_index_map() > {0: (0, 1, "edge")} - - def test_deepcopy(self): - edge_map = self.dag.edge_index_map() - edge_map_copy = copy.deepcopy(edge_map) - self.assertEqual(edge_map_copy, edge_map) - - def test_pickle(self): - edge_map = self.dag.edge_index_map() - edge_map_pickle = pickle.dumps(edge_map) - edge_map_copy = pickle.loads(edge_map_pickle) - self.assertEqual(edge_map, edge_map_copy) - - def test_str(self): - res = self.dag.edge_index_map() - self.assertEqual( - "EdgeIndexMap{0: (0, 1, edge)}", - str(res), - ) - - def test_hash(self): - res = self.dag.edge_index_map() - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = self.dag.edge_index_map() - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = self.dag.edge_index_map().keys() - self.assertEqual([0], list(keys)) - - def test_values(self): - values = self.dag.edge_index_map().values() - expected = [(0, 1, "edge")] - self.assertEqual(expected, list(values)) - - def test_items(self): - items = self.dag.edge_index_map().items() - self.assertEqual([(0, (0, 1, "edge"))], list(items)) - - def test_iter(self): - mapping_iter = iter(self.dag.edge_index_map()) - output = list(mapping_iter) - self.assertEqual(output, [0]) - - def test_contains(self): - res = self.dag.edge_index_map() - self.assertIn(0, res) - - def test_not_contains(self): - res = self.dag.edge_index_map() - self.assertNotIn(1, res) - - -class TestAllPairsPathMapping(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - self.fn = lambda _: 1.0 - - def test__eq__match(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) == {0: {1: [0, 1]}, 1: {}} - ) - - def test__eq__not_match_keys(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) == {2: {2: [0, 1]}, 1: {}} - ) - - def test__eq__not_match_values(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) == {0: {1: [0, 2]}, 1: {}} - ) - - def test__eq__different_length(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) == {1: [0, 1], 2: [0, 2]} - ) - - def test_eq__same_type(self): - self.assertEqual( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn), - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn), - ) - - def test__eq__invalid_type(self): - self.assertFalse(retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) == {"a": []}) - - def test__eq__invalid_inner_type(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) == {0: {1: None}} - ) - - def test__ne__match(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) != {0: {1: [0, 1]}, 1: {}} - ) - - def test__ne__not_match(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) != {2: [0, 1]} - ) - - def test__ne__not_match_values(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) != {1: [0, 2]} - ) - - def test__ne__different_length(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) != {1: [0, 1], 2: [0, 2]} - ) - - def test__ne__invalid_type(self): - self.assertTrue(retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) != {"a": {}}) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) > {1: [0, 2]} - - def test_deepcopy(self): - paths = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) - paths_copy = copy.deepcopy(paths) - self.assertEqual(paths, paths_copy) - - def test_pickle(self): - paths = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) - paths_pickle = pickle.dumps(paths) - paths_copy = pickle.loads(paths_pickle) - self.assertEqual(paths, paths_copy) - - def test_str(self): - res = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) - # Since run in parallel the order is not deterministic - expected_valid = [ - "AllPairsPathMapping{1: PathMapping{}, 0: PathMapping{1: [0, 1]}}", - "AllPairsPathMapping{0: PathMapping{1: [0, 1]}, 1: PathMapping{}}", - ] - self.assertIn(str(res), expected_valid) - - def test_hash(self): - res = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn).keys() - self.assertEqual([0, 1], list(sorted(keys))) - - def test_values(self): - values = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn).values() - # Since run in parallel the order is not deterministic - expected_valid = [[{1: [0, 1]}, {}], [{}, {1: [0, 1]}]] - self.assertIn(list(values), expected_valid) - - def test_items(self): - items = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn).items() - # Since run in parallel the order is not deterministic - expected_valid = [ - [(0, {1: [0, 1]}), (1, {})], - [(1, {}), (0, {1: [0, 1]})], - ] - self.assertIn(list(items), expected_valid) - - def test_iter(self): - mapping_iter = iter(retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn)) - output = list(sorted(mapping_iter)) - self.assertEqual(output, [0, 1]) - - def test_contains(self): - res = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) - self.assertIn(1, res) - - def test_not_contains(self): - res = retworkx.all_pairs_dijkstra_shortest_paths(self.dag, self.fn) - self.assertNotIn(2, res) - - -class TestAllPairsPathLengthMapping(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - node_a = self.dag.add_node("a") - self.dag.add_child(node_a, "b", "Edgy") - self.fn = lambda _: 1.0 - - def test__eq__match(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) == {0: {1: 1.0}, 1: {}} - ) - - def test__eq__not_match_keys(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) == {1: {2: 1.0}} - ) - - def test__eq__not_match_values(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) == {0: {2: 2.0}} - ) - - def test__eq__different_length(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) == {0: {1: 1.0, 2: 2.0}} - ) - - def test_eq__same_type(self): - self.assertEqual( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn), - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn), - ) - - def test__eq__invalid_type(self): - self.assertFalse(retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) == {"a": 2}) - - def test__eq__invalid_inner_type(self): - self.assertFalse(retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) == {0: "a"}) - - def test__ne__match(self): - self.assertFalse( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) != {0: {1: 1.0}, 1: {}} - ) - - def test__ne__not_match(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) != {0: {2: 1.0}} - ) - - def test__ne__not_match_values(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) != {0: {1: 2.0}} - ) - - def test__ne__different_length(self): - self.assertTrue( - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) - != {0: {1: 1.0}, 2: {1: 2.0}} - ) - - def test__ne__invalid_type(self): - self.assertTrue(retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) != {1: []}) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) > {1: 1.0} - - def test_deepcopy(self): - paths = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) - paths_copy = copy.deepcopy(paths) - self.assertEqual(paths, paths_copy) - - def test_pickle(self): - paths = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) - paths_pickle = pickle.dumps(paths) - paths_copy = pickle.loads(paths_pickle) - self.assertEqual(paths, paths_copy) - - def test_str(self): - res = retworkx.all_pairs_dijkstra_path_lengths(self.dag, lambda _: 3.14) - # Since all_pairs_dijkstra_path_lengths() is parallel the order of the - # output is non-determinisitic - valid_values = [ - "AllPairsPathLengthMapping{1: PathLengthMapping{}, " "0: PathLengthMapping{1: 3.14}}", - "AllPairsPathLengthMapping{" - "0: PathLengthMapping{1: 3.14}, " - "1: PathLengthMapping{}}", - ] - self.assertIn(str(res), valid_values) - - def test_hash(self): - res = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn).keys() - self.assertEqual([0, 1], list(sorted((keys)))) - - def test_values(self): - values = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn).values() - # Since run in parallel the order is not deterministic - valid_expected = [[{}, {1: 1.0}], [{1: 1.0}, {}]] - self.assertIn(list(values), valid_expected) - - def test_items(self): - items = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn).items() - # Since run in parallel the order is not deterministic - valid_expected = [[(0, {1: 1.0}), (1, {})], [(1, {}), (0, {1: 1.0})]] - self.assertIn(list(items), valid_expected) - - def test_iter(self): - mapping_iter = iter(retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn)) - output = list(sorted(mapping_iter)) - self.assertEqual(output, [0, 1]) - - def test_contains(self): - res = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) - self.assertIn(0, res) - - def test_not_contains(self): - res = retworkx.all_pairs_dijkstra_path_lengths(self.dag, self.fn) - self.assertNotIn(2, res) - - -class TestNodeMap(unittest.TestCase): - def setUp(self): - self.dag = retworkx.PyDAG() - self.dag.add_node("a") - self.in_dag = retworkx.generators.directed_path_graph(1) - - def test__eq__match(self): - self.assertTrue( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) == {0: 1} - ) - - def test__eq__not_match_keys(self): - self.assertFalse( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) == {2: 1} - ) - - def test__eq__not_match_values(self): - self.assertFalse( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) == {0: 2} - ) - - def test__eq__different_length(self): - self.assertFalse( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - == {0: 1, 1: 2} - ) - - def test_eq__same_type(self): - res = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - self.assertEqual(res, res) - - def test__ne__match(self): - self.assertFalse( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) != {0: 1} - ) - - def test__ne__not_match(self): - self.assertTrue( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) != {2: 2} - ) - - def test__ne__not_match_values(self): - self.assertTrue( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) != {0: 2} - ) - - def test__ne__different_length(self): - self.assertTrue( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - != {0: 1, 1: 2} - ) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) > {1: 2} - - def test__len__(self): - in_dag = retworkx.generators.directed_grid_graph(5, 5) - node_map = self.dag.substitute_node_with_subgraph(0, in_dag, lambda *args: None) - self.assertEqual(25, len(node_map)) - - def test_deepcopy(self): - node_map = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - node_map_copy = copy.deepcopy(node_map) - self.assertEqual(node_map, node_map_copy) - - def test_pickle(self): - node_map = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - node_map_pickle = pickle.dumps(node_map) - node_map_copy = pickle.loads(node_map_pickle) - self.assertEqual(node_map, node_map_copy) - - def test_str(self): - res = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - self.assertEqual("NodeMap{0: 1}", str(res)) - - def test_hash(self): - res = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - hash_res = hash(res) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(res)) - - def test_index_error(self): - res = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - with self.assertRaises(IndexError): - res[42] - - def test_keys(self): - keys = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None).keys() - self.assertEqual([0], list(keys)) - - def test_values(self): - values = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None).values() - self.assertEqual([1], list(values)) - - def test_items(self): - items = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None).items() - self.assertEqual([(0, 1)], list(items)) - - def test_iter(self): - mapping_iter = iter( - self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - ) - output = list(mapping_iter) - self.assertEqual(output, [0]) - - def test_contains(self): - res = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - self.assertIn(0, res) - - def test_not_contains(self): - res = self.dag.substitute_node_with_subgraph(0, self.in_dag, lambda *args: None) - self.assertNotIn(2, res) - - def test_iter_stable_for_same_obj(self): - graph = retworkx.PyDiGraph() - graph.add_node(0) - in_graph = retworkx.generators.directed_path_graph(5) - res = self.dag.substitute_node_with_subgraph(0, in_graph, lambda *args: None) - first_iter = list(iter(res)) - second_iter = list(iter(res)) - third_iter = list(iter(res)) - self.assertEqual(first_iter, second_iter) - self.assertEqual(first_iter, third_iter) - - -class TestChainsComparisons(unittest.TestCase): - def setUp(self): - self.graph = retworkx.generators.cycle_graph(3) - self.chains = retworkx.chain_decomposition(self.graph) - - def test__eq__match(self): - self.assertTrue(self.chains == [[(0, 2), (2, 1), (1, 0)]]) - - def test__eq__not_match(self): - self.assertFalse(self.chains == [[(0, 2), (2, 1), (2, 0)]]) - - def test__eq__different_length(self): - self.assertFalse(self.chains == [[(0, 2)]]) - - def test__eq__invalid_type(self): - with self.assertRaises(TypeError): - self.chains == [0] - - def test__ne__match(self): - self.assertFalse(self.chains != [[(0, 2), (2, 1), (1, 0)]]) - - def test__ne__not_match(self): - self.assertTrue(self.chains != [[(0, 2), (2, 1), (2, 0)]]) - - def test__ne__different_length(self): - self.assertTrue(self.chains != [[(0, 2)]]) - - def test__ne__invalid_type(self): - with self.assertRaises(TypeError): - self.chains != [0] - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.chains > [[(0, 2)]] - - def test_deepcopy(self): - chains_copy = copy.deepcopy(self.chains) - self.assertEqual(self.chains, chains_copy) - - def test_pickle(self): - chains_pickle = pickle.dumps(self.chains) - chains_copy = pickle.loads(chains_pickle) - self.assertEqual(self.chains, chains_copy) - - def test_str(self): - self.assertEqual("Chains[EdgeList[(0, 2), (2, 1), (1, 0)]]", str(self.chains)) - - def test_hash(self): - hash_res = hash(self.chains) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(self.chains)) - - def test_numpy_conversion(self): - # this test assumes the array is 1-dimensional which avoids issues with jagged arrays - self.assertTrue(np.asarray(self.chains).shape, (1,)) - - -class TestProductNodeMap(unittest.TestCase): - def setUp(self): - self.first = retworkx.PyGraph() - self.first.add_node("a0") - self.first.add_node("a1") - - self.second = retworkx.PyGraph() - self.second.add_node("b") - _, self.node_map = retworkx.graph_cartesian_product(self.first, self.second) - - def test__eq__match(self): - self.assertTrue(self.node_map == {(0, 0): 0, (1, 0): 1}) - - def test__eq__not_match_keys(self): - self.assertFalse(self.node_map == {(0, 0): 0, (2, 0): 1}) - - def test__eq__not_match_values(self): - self.assertFalse(self.node_map == {(0, 0): 0, (1, 0): 2}) - - def test__eq__different_length(self): - self.assertFalse(self.node_map == {(0, 0): 0}) - - def test_eq__same_type(self): - _, res = retworkx.graph_cartesian_product(self.first, self.second) - self.assertEqual(self.node_map, res) - - def test__ne__match(self): - self.assertFalse(self.node_map != {(0, 0): 0, (1, 0): 1}) - - def test__ne__not_match(self): - self.assertTrue(self.node_map != {(0, 0): 0, (2, 0): 1}) - - def test__ne__not_match_values(self): - self.assertTrue(self.node_map != {(0, 0): 0, (1, 0): 2}) - - def test__ne__different_length(self): - self.assertTrue(self.node_map != {(0, 0): 0}) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.node_map > {1: 2} - - def test__len__(self): - self.assertEqual(2, len(self.node_map)) - - def test_deepcopy(self): - node_map_copy = copy.deepcopy(self.node_map) - self.assertEqual(self.node_map, node_map_copy) - - def test_pickle(self): - node_map_pickle = pickle.dumps(self.node_map) - node_map_copy = pickle.loads(node_map_pickle) - self.assertEqual(self.node_map, node_map_copy) - - def test_str(self): - valid_str_output = [ - "ProductNodeMap{(0, 0): 0, (1, 0): 1}", - "ProductNodeMap{(1, 0): 1, (0, 0): 0}", - ] - self.assertTrue(str(self.node_map) in valid_str_output) - - def test_hash(self): - hash_res = hash(self.node_map) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(self.node_map)) - - def test_index_error(self): - with self.assertRaises(IndexError): - self.node_map[(1, 1)] - - def test_keys(self): - keys = self.node_map.keys() - self.assertEqual(set([(0, 0), (1, 0)]), set(keys)) - - def test_values(self): - values = self.node_map.values() - self.assertEqual(set([0, 1]), set(values)) - - def test_items(self): - items = self.node_map.items() - self.assertEqual(set([((0, 0), 0), ((1, 0), 1)]), set(items)) - - def test_iter(self): - mapping_iter = iter(self.node_map) - output = set(mapping_iter) - self.assertEqual(output, set([(0, 0), (1, 0)])) - - def test_contains(self): - self.assertIn((0, 0), self.node_map) - - def test_not_contains(self): - self.assertNotIn((1, 1), self.node_map) - - -class TestBiconnectedComponentsMap(unittest.TestCase): - def setUp(self): - self.graph = retworkx.generators.path_graph(3) - self.bicon_map = retworkx.biconnected_components(self.graph) - - def test__eq__match(self): - self.assertTrue(self.bicon_map == {(0, 1): 1, (1, 2): 0}) - - def test__eq__not_match_keys(self): - self.assertFalse(self.bicon_map == {(0, 0): 1, (2, 0): 0}) - - def test__eq__not_match_values(self): - self.assertFalse(self.bicon_map == {(0, 1): 2, (1, 2): 0}) - - def test__eq__different_length(self): - self.assertFalse(self.bicon_map == {(0, 1): 1}) - - def test_eq__same_type(self): - res = retworkx.biconnected_components(self.graph) - self.assertEqual(self.bicon_map, res) - - def test__ne__match(self): - self.assertFalse(self.bicon_map != {(0, 1): 1, (1, 2): 0}) - - def test__ne__not_match(self): - self.assertTrue(self.bicon_map != {(0, 2): 1, (1, 2): 0}) - - def test__ne__not_match_values(self): - self.assertTrue(self.bicon_map != {(0, 1): 0, (1, 2): 0}) - - def test__ne__different_length(self): - self.assertTrue(self.bicon_map != {(0, 1): 1}) - - def test__gt__not_implemented(self): - with self.assertRaises(NotImplementedError): - self.bicon_map > {1: 2} - - def test__len__(self): - self.assertEqual(2, len(self.bicon_map)) - - def test_deepcopy(self): - bicon_map_copy = copy.deepcopy(self.bicon_map) - self.assertEqual(self.bicon_map, bicon_map_copy) - - def test_pickle(self): - bicon_map_pickle = pickle.dumps(self.bicon_map) - bicon_map_copy = pickle.loads(bicon_map_pickle) - self.assertEqual(self.bicon_map, bicon_map_copy) - - def test_str(self): - valid_str_output = [ - "BiconnectedComponents{(0, 1): 1, (1, 2): 0}", - "BiconnectedComponents{(1, 2): 0, (0, 1): 1}", - ] - self.assertTrue(str(self.bicon_map) in valid_str_output) - - def test_hash(self): - hash_res = hash(self.bicon_map) - self.assertIsInstance(hash_res, int) - # Assert hash is stable - self.assertEqual(hash_res, hash(self.bicon_map)) - - def test_index_error(self): - with self.assertRaises(IndexError): - self.bicon_map[(1, 1)] - - def test_keys(self): - keys = self.bicon_map.keys() - self.assertEqual(set([(0, 1), (1, 2)]), set(keys)) - - def test_values(self): - values = self.bicon_map.values() - self.assertEqual(set([0, 1]), set(values)) - - def test_items(self): - items = self.bicon_map.items() - self.assertEqual(set([((0, 1), 1), ((1, 2), 0)]), set(items)) - - def test_iter(self): - mapping_iter = iter(self.bicon_map) - output = set(mapping_iter) - self.assertEqual(output, set([(0, 1), (1, 2)])) - - def test_contains(self): - self.assertIn((0, 1), self.bicon_map) - - def test_not_contains(self): - self.assertNotIn((0, 2), self.bicon_map) diff --git a/tests/retworkx_backwards_compat/test_dispatch.py b/tests/retworkx_backwards_compat/test_dispatch.py deleted file mode 100644 index 5bdc83e557..0000000000 --- a/tests/retworkx_backwards_compat/test_dispatch.py +++ /dev/null @@ -1,111 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import retworkx - -import numpy - - -class TestDispatchPyGraph(unittest.TestCase): - - class_type = "PyGraph" - - def setUp(self): - super().setUp() - if self.class_type == "PyGraph": - self.graph = retworkx.undirected_gnp_random_graph(10, 0.5, seed=42) - else: - self.graph = retworkx.directed_gnp_random_graph(10, 0.5, seed=42) - - def test_distance_matrix(self): - res = retworkx.distance_matrix(self.graph) - self.assertIsInstance(res, numpy.ndarray) - - def test_distance_matrix_as_undirected(self): - if self.class_type == "PyGraph": - with self.assertRaises(TypeError): - retworkx.distance_matrix(self.graph, as_undirected=True) - else: - res = retworkx.distance_matrix(self.graph, as_undirected=True) - self.assertIsInstance(res, numpy.ndarray) - - def test_adjacency_matrix(self): - res = retworkx.adjacency_matrix(self.graph) - self.assertIsInstance(res, numpy.ndarray) - - def test_all_simple_paths(self): - res = retworkx.all_simple_paths(self.graph, 0, 1) - self.assertIsInstance(res, list) - - def test_floyd_warshall(self): - res = retworkx.floyd_warshall(self.graph) - self.assertIsInstance(res, retworkx.AllPairsPathLengthMapping) - - def test_floyd_warshall_numpy(self): - res = retworkx.floyd_warshall_numpy(self.graph) - self.assertIsInstance(res, numpy.ndarray) - - if self.class_type == "PyGraph": - expected_res = retworkx.graph_floyd_warshall_numpy(self.graph) - else: - expected_res = retworkx.digraph_floyd_warshall_numpy(self.graph) - - self.assertTrue(numpy.array_equal(expected_res, res)) - - def test_astar_shortest_path(self): - res = retworkx.astar_shortest_path(self.graph, 0, lambda _: True, lambda _: 1, lambda _: 1) - self.assertIsInstance(list(res), list) - - def test_dijkstra_shortest_paths(self): - res = retworkx.dijkstra_shortest_paths(self.graph, 0) - self.assertIsInstance(res, retworkx.PathMapping) - - def test_dijkstra_shortest_path_lengths(self): - res = retworkx.dijkstra_shortest_path_lengths(self.graph, 0, lambda _: 1) - self.assertIsInstance(res, retworkx.PathLengthMapping) - - def test_k_shortest_path_lengths(self): - res = retworkx.k_shortest_path_lengths(self.graph, 0, 2, lambda _: 1) - self.assertIsInstance(res, retworkx.PathLengthMapping) - - def test_dfs_edges(self): - res = retworkx.dfs_edges(self.graph, 0) - self.assertIsInstance(list(res), list) - - def test_all_pairs_dijkstra_shortest_paths(self): - res = retworkx.all_pairs_dijkstra_shortest_paths(self.graph, lambda _: 1) - self.assertIsInstance(res, retworkx.AllPairsPathMapping) - - def test_all_pairs_dijkstra_path_lengthss(self): - res = retworkx.all_pairs_dijkstra_path_lengths(self.graph, lambda _: 1) - self.assertIsInstance(res, retworkx.AllPairsPathLengthMapping) - - def test_is_isomorphic_nodes_incompatible_raises(self): - with self.assertRaises(TypeError): - if self.class_type == "PyGraph": - retworkx.is_isomorphic(self.graph, retworkx.PyDiGraph()) - else: - retworkx.is_isomorphic(self.graph, retworkx.PyGraph()) - - def test_betweenness_centrality(self): - res = retworkx.betweenness_centrality(self.graph) - self.assertIsInstance(res, retworkx.CentralityMapping) - - def test_closeness_centrality(self): - res = retworkx.closeness_centrality(self.graph) - self.assertIsInstance(res, retworkx.CentralityMapping) - - -class TestDispatchPyDiGraph(TestDispatchPyGraph): - - class_type = "PyDiGraph" diff --git a/tests/retworkx_backwards_compat/test_graphml.py b/tests/retworkx_backwards_compat/test_graphml.py deleted file mode 100644 index 1750d68c7b..0000000000 --- a/tests/retworkx_backwards_compat/test_graphml.py +++ /dev/null @@ -1,512 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import tempfile -import numpy - -import retworkx - - -class TestGraphML(unittest.TestCase): - HEADER = """ - - - {} - - """ - - def assertDictPayloadEqual(self, xs, ys): - self.assertEqual(len(xs), len(ys)) - for key, va in xs.items(): - vb = ys.get(key, None) - self.assertTrue( - (isinstance(va, float) and isinstance(vb, float) and numpy.allclose(va, vb)) - or (va == vb) - ) - - def assertGraphEqual(self, graph, nodes, edges, directed=True, attrs={}): - self.assertTrue(isinstance(graph, retworkx.PyDiGraph if directed else retworkx.PyGraph)) - self.assertEqual(len(graph), len(nodes)) - self.assertEqual(graph.attrs, attrs) - for node_a, node_b in zip(graph.nodes(), nodes): - self.assertDictPayloadEqual(node_a, node_b) - - for ((s, t, data), edge) in zip(graph.weighted_edge_list(), edges): - self.assertEqual((graph[s]["id"], graph[t]["id"]), (edge[0], edge[1])) - self.assertDictPayloadEqual(data, edge[2]) - - def assertGraphMLRaises(self, graph_xml): - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - with self.assertRaises(Exception): - retworkx.read_graphml(fd.name) - - def test_simple(self): - graph_xml = self.HEADER.format( - """ - - yellow - - - 0.95 - - - - blue - - - - green - - - 0.98 - - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "color": "blue"}, - {"id": "n1", "color": "yellow"}, - {"id": "n2", "color": "green"}, - ] - edges = [ - ("n0", "n1", {"fidelity": 0.98}), - ("n0", "n2", {"fidelity": 0.95}), - ] - self.assertGraphEqual(graph, nodes, edges, directed=False) - - def test_multiple_graphs_in_single_file(self): - graph_xml = self.HEADER.format( - """ - - yellow - - - 0.95 - - - - blue - - - - 0.98 - - - - - red - - - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - self.assertEqual(len(graphml), 2) - graph = graphml[0] - nodes = [ - {"id": "n0", "color": "blue"}, - {"id": "n1", "color": "yellow"}, - ] - edges = [ - ("n0", "n1", {"id": "e01", "fidelity": 0.98}), - ] - self.assertGraphEqual(graph, nodes, edges, directed=False) - graph = graphml[1] - nodes = [ - {"id": "n0", "color": "red"}, - {"id": "n1", "color": "yellow"}, - ] - edges = [ - ("n0", "n1", {"id": "e01", "fidelity": 0.95}), - ] - self.assertGraphEqual(graph, nodes, edges, directed=True) - - def test_key_for_graph(self): - graph_xml = self.HEADER.format( - """ - - - true - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [{"id": "n0"}] - edges = [] - self.assertGraphEqual(graph, nodes, edges, directed=True, attrs={"test": True}) - - def test_key_for_all(self): - graph_xml = self.HEADER.format( - """ - - - I'm a graph. - - I'm a node. - - - I'm a node. - - - I'm an edge. - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "test": "I'm a node."}, - {"id": "n1", "test": "I'm a node."}, - ] - edges = [("n0", "n1", {"test": "I'm an edge."})] - self.assertGraphEqual( - graph, nodes, edges, directed=True, attrs={"test": "I'm a graph."} - ) - - def test_key_default_undefined(self): - graph_xml = self.HEADER.format( - """ - - - - true - - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "test": True}, - {"id": "n1", "test": None}, - ] - edges = [] - self.assertGraphEqual(graph, nodes, edges, directed=True) - - def test_bool(self): - graph_xml = self.HEADER.format( - """ - - false - - - - true - - - - false - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "test": True}, - {"id": "n1", "test": False}, - {"id": "n2", "test": False}, - ] - edges = [] - self.assertGraphEqual(graph, nodes, edges, directed=True) - - def test_int(self): - graph_xml = self.HEADER.format( - """ - - 42 - - - - 8 - - - - 42 - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "test": 8}, - {"id": "n1", "test": 42}, - {"id": "n2", "test": 42}, - ] - edges = [] - self.assertGraphEqual(graph, nodes, edges, directed=True) - - def test_float(self): - graph_xml = self.HEADER.format( - """ - - 4.2 - - - - 1.8 - - - - 4.2 - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "test": 1.8}, - {"id": "n1", "test": 4.2}, - {"id": "n2", "test": 4.2}, - ] - edges = [] - self.assertGraphEqual(graph, nodes, edges, directed=True) - - def test_double(self): - graph_xml = self.HEADER.format( - """ - - 4.2 - - - - 1.8 - - - - 4.2 - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "test": 1.8}, - {"id": "n1", "test": 4.2}, - {"id": "n2", "test": 4.2}, - ] - edges = [] - self.assertGraphEqual(graph, nodes, edges, directed=True) - - def test_string(self): - graph_xml = self.HEADER.format( - """ - - yellow - - - - blue - - - - yellow - - - """ - ) - - with tempfile.NamedTemporaryFile("wt") as fd: - fd.write(graph_xml) - fd.flush() - graphml = retworkx.read_graphml(fd.name) - graph = graphml[0] - nodes = [ - {"id": "n0", "test": "blue"}, - {"id": "n1", "test": "yellow"}, - {"id": "n2", "test": "yellow"}, - ] - edges = [] - self.assertGraphEqual(graph, nodes, edges, directed=True) - - def test_convert_error(self): - graph_xml = self.HEADER.format( - """ - - blah - - """ - ) - - for type in ["boolean", "int", "float", "double"]: - self.assertGraphMLRaises(graph_xml=graph_xml.format(type)) - - def test_invalid_xml(self): - graph_xml = self.HEADER.format( - """ - - - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_invalid_edgedefault(self): - graph_xml = self.HEADER.format( - """ - - - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_missing_node_id(self): - graph_xml = self.HEADER.format( - """ - - - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_missing_key_for_node(self): - graph_xml = self.HEADER.format( - """ - - - - blue - - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_invalid_key_type(self): - graph_xml = self.HEADER.format( - """ - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_unsupported_key_domain(self): - graph_xml = self.HEADER.format( - """ - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_unsupported_nested_graphs(self): - graph_xml = self.HEADER.format( - """ - - - - - - - - - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_unsupported_hyperedges(self): - graph_xml = self.HEADER.format( - """ - - - - - - - - - - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_unsupported_ports(self): - graph_xml = self.HEADER.format( - """ - - - - - - """ - ) - self.assertGraphMLRaises(graph_xml) - - def test_unsupported_nested_ports(self): - graph_xml = self.HEADER.format( - """ - - - - - - - - """ - ) - self.assertGraphMLRaises(graph_xml) diff --git a/tests/retworkx_backwards_compat/test_random.py b/tests/retworkx_backwards_compat/test_random.py deleted file mode 100644 index 67a60760c1..0000000000 --- a/tests/retworkx_backwards_compat/test_random.py +++ /dev/null @@ -1,222 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import random - -import retworkx - - -class TestGNPRandomGraph(unittest.TestCase): - def test_random_gnp_directed(self): - graph = retworkx.directed_gnp_random_graph(20, 0.5, seed=10) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 104) - - def test_random_gnp_directed_empty_graph(self): - graph = retworkx.directed_gnp_random_graph(20, 0) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 0) - - def test_random_gnp_directed_complete_graph(self): - graph = retworkx.directed_gnp_random_graph(20, 1) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 20 * (20 - 1)) - - def test_random_gnp_directed_invalid_num_nodes(self): - with self.assertRaises(ValueError): - retworkx.directed_gnp_random_graph(0, 0.5) - - def test_random_gnp_directed_invalid_probability(self): - with self.assertRaises(ValueError): - retworkx.directed_gnp_random_graph(23, 123.5) - - def test_random_gnp_undirected(self): - graph = retworkx.undirected_gnp_random_graph(20, 0.5, seed=10) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 105) - - def test_random_gnp_undirected_empty_graph(self): - graph = retworkx.undirected_gnp_random_graph(20, 0) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 0) - - def test_random_gnp_undirected_complete_graph(self): - graph = retworkx.undirected_gnp_random_graph(20, 1) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 20 * (20 - 1) / 2) - - def test_random_gnp_undirected_invalid_num_nodes(self): - with self.assertRaises(ValueError): - retworkx.undirected_gnp_random_graph(0, 0.5) - - def test_random_gnp_undirected_invalid_probability(self): - with self.assertRaises(ValueError): - retworkx.undirected_gnp_random_graph(23, 123.5) - - -class TestGNMRandomGraph(unittest.TestCase): - def test_random_gnm_directed(self): - graph = retworkx.directed_gnm_random_graph(20, 100) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 100) - # with other arguments equal, same seed results in same graph - graph_s1 = retworkx.directed_gnm_random_graph(20, 100, seed=10) - graph_s2 = retworkx.directed_gnm_random_graph(20, 100, seed=10) - self.assertEqual(graph_s1.edge_list(), graph_s2.edge_list()) - - def test_random_gnm_directed_empty_graph(self): - graph = retworkx.directed_gnm_random_graph(20, 0) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 0) - # passing a seed when passing zero edges has no effect - graph = retworkx.directed_gnm_random_graph(20, 0, 44) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 0) - - def test_random_gnm_directed_complete_graph(self): - n = 20 - max_m = n * (n - 1) - # passing the max edges for the passed number of nodes - graph = retworkx.directed_gnm_random_graph(n, max_m) - self.assertEqual(len(graph), n) - self.assertEqual(len(graph.edges()), max_m) - # passing m > the max edges n(n-1) still returns the max edges - graph = retworkx.directed_gnm_random_graph(n, max_m + 1) - self.assertEqual(len(graph), n) - self.assertEqual(len(graph.edges()), max_m) - # passing a seed when passing max edges has no effect - graph = retworkx.directed_gnm_random_graph(n, max_m, 55) - self.assertEqual(len(graph), n) - self.assertEqual(len(graph.edges()), max_m) - - def test_random_gnm_directed_invalid_num_nodes(self): - with self.assertRaises(ValueError): - retworkx.directed_gnm_random_graph(0, 5) - - def test_random_gnm_directed_invalid_num_edges(self): - with self.assertRaises(OverflowError): - retworkx.directed_gnm_random_graph(23, -5) - - def test_random_gnm_undirected(self): - graph = retworkx.undirected_gnm_random_graph(20, 100) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 100) - # with other arguments equal, same seed results in same graph - graph_s1 = retworkx.undirected_gnm_random_graph(20, 100, seed=10) - graph_s2 = retworkx.undirected_gnm_random_graph(20, 100, seed=10) - self.assertEqual(graph_s1.edge_list(), graph_s2.edge_list()) - - def test_random_gnm_undirected_empty_graph(self): - graph = retworkx.undirected_gnm_random_graph(20, 0) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 0) - # passing a seed when passing zero edges has no effect - graph = retworkx.undirected_gnm_random_graph(20, 0, 44) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 0) - - def test_random_gnm_undirected_complete_graph(self): - n = 20 - max_m = n * (n - 1) // 2 - # passing the max edges for the passed number of nodes - graph = retworkx.undirected_gnm_random_graph(n, max_m) - self.assertEqual(len(graph), n) - self.assertEqual(len(graph.edges()), max_m) - # passing m > the max edges n(n-1)/2 still returns the max edges - graph = retworkx.undirected_gnm_random_graph(n, max_m + 1) - self.assertEqual(len(graph), n) - self.assertEqual(len(graph.edges()), max_m) - # passing a seed when passing max edges has no effect - graph = retworkx.undirected_gnm_random_graph(n, max_m, 55) - self.assertEqual(len(graph), n) - self.assertEqual(len(graph.edges()), max_m) - - def test_random_gnm_undirected_invalid_num_nodes(self): - with self.assertRaises(ValueError): - retworkx.undirected_gnm_random_graph(0, 5) - - def test_random_gnm_undirected_invalid_num_edges(self): - with self.assertRaises(OverflowError): - retworkx.undirected_gnm_random_graph(23, -5) - - -class TestGeometricRandomGraph(unittest.TestCase): - def test_random_geometric_empty(self): - graph = retworkx.random_geometric_graph(20, 0) - self.assertEqual(len(graph), 20) - self.assertEqual(len(graph.edges()), 0) - - def test_random_geometric_complete(self): - r = 1.42 # > sqrt(2) - graph = retworkx.random_geometric_graph(10, r) - self.assertEqual(len(graph), 10) - self.assertEqual(len(graph.edges()), 45) - - def test_random_geometric_same_seed(self): - # with other arguments equal, same seed results in same graph - graph_s1 = retworkx.random_geometric_graph(20, 0.5, seed=10) - graph_s2 = retworkx.random_geometric_graph(20, 0.5, seed=10) - self.assertEqual(graph_s1.edge_list(), graph_s2.edge_list()) - - def test_random_geometric_dim(self): - graph = retworkx.random_geometric_graph(10, 0.5, dim=3) - self.assertEqual(len(graph[0]["pos"]), 3) - - def test_random_geometric_pos(self): - pos = [[0.1, 0.1], [0.2, 0.2], [0.3, 0.3]] - graph = retworkx.random_geometric_graph(3, 0.15, pos=pos) - self.assertEqual(set(graph.edge_list()), {(0, 1), (1, 2)}) - for i in range(3): - self.assertEqual(graph[i]["pos"], pos[i]) - - def test_random_geometric_pos_1norm(self): - pos = [[0.1, 0.1], [0.2, 0.2], [0.3, 0.3]] - graph = retworkx.random_geometric_graph(3, 0.21, pos=pos, p=1.0) - self.assertEqual(set(graph.edge_list()), {(0, 1), (1, 2)}) - - def test_random_geometric_pos_inf_norm(self): - pos = [[0.1, 0.1], [0.2, 0.2], [0.3, 0.3]] - graph = retworkx.random_geometric_graph(3, 0.11, pos=pos, p=float("inf")) - self.assertEqual(set(graph.edge_list()), {(0, 1), (1, 2)}) - - def test_random_geometric_num_nodes_invalid(self): - with self.assertRaises(ValueError): - retworkx.random_geometric_graph(0, 1.0) - - def test_random_geometric_pos_num_nodes_incomp(self): - with self.assertRaises(ValueError): - retworkx.random_geometric_graph(3, 0.15, pos=[[0.5, 0.5]]) - - -class TestRandomSubGraphIsomorphism(unittest.TestCase): - def test_random_gnm_induced_subgraph_isomorphism(self): - graph = retworkx.undirected_gnm_random_graph(50, 150) - nodes = random.sample(range(50), 25) - subgraph = graph.subgraph(nodes) - - self.assertTrue( - retworkx.is_subgraph_isomorphic(graph, subgraph, id_order=True, induced=True) - ) - - def test_random_gnm_non_induced_subgraph_isomorphism(self): - graph = retworkx.undirected_gnm_random_graph(50, 150) - nodes = random.sample(range(50), 25) - subgraph = graph.subgraph(nodes) - - indexes = list(subgraph.edge_indices()) - for idx in random.sample(indexes, len(indexes) // 2): - subgraph.remove_edge_from_index(idx) - - self.assertTrue( - retworkx.is_subgraph_isomorphic(graph, subgraph, id_order=True, induced=False) - ) diff --git a/tests/retworkx_backwards_compat/visualization/__init__.py b/tests/retworkx_backwards_compat/visualization/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/retworkx_backwards_compat/visualization/test_graphviz.py b/tests/retworkx_backwards_compat/visualization/test_graphviz.py deleted file mode 100644 index 5d90395375..0000000000 --- a/tests/retworkx_backwards_compat/visualization/test_graphviz.py +++ /dev/null @@ -1,152 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os -import subprocess -import tempfile -import unittest - -import retworkx -from retworkx.visualization import graphviz_draw - -try: - import PIL - - subprocess.run( - ["dot", "-V"], - cwd=tempfile.gettempdir(), - check=True, - capture_output=True, - ) - HAS_PILLOW = True -except Exception: - HAS_PILLOW = False - -SAVE_IMAGES = os.getenv("RUSTWORKX_TEST_PRESERVE_IMAGES", None) - - -def _save_image(image, path): - if SAVE_IMAGES: - image.save(path) - - -@unittest.skipUnless(HAS_PILLOW, "pillow and graphviz are required for running these tests") -class TestGraphvizDraw(unittest.TestCase): - def test_draw_no_args(self): - graph = retworkx.generators.star_graph(24) - image = graphviz_draw(graph) - self.assertIsInstance(image, PIL.Image.Image) - _save_image(image, "test_graphviz_draw.png") - - def test_draw_node_attr_fn(self): - graph = retworkx.PyGraph() - graph.add_node( - { - "color": "black", - "fillcolor": "green", - "label": "a", - "style": "filled", - } - ) - graph.add_node( - { - "color": "black", - "fillcolor": "red", - "label": "a", - "style": "filled", - } - ) - graph.add_edge(0, 1, dict(label="1", name="1")) - image = graphviz_draw(graph, lambda node: node) - self.assertIsInstance(image, PIL.Image.Image) - _save_image(image, "test_graphviz_draw_node_attr.png") - - def test_draw_edge_attr_fn(self): - graph = retworkx.PyGraph() - graph.add_node( - { - "color": "black", - "fillcolor": "green", - "label": "a", - "style": "filled", - } - ) - graph.add_node( - { - "color": "black", - "fillcolor": "red", - "label": "a", - "style": "filled", - } - ) - graph.add_edge(0, 1, dict(label="1", name="1")) - image = graphviz_draw(graph, lambda node: node, lambda edge: edge) - self.assertIsInstance(image, PIL.Image.Image) - _save_image(image, "test_graphviz_draw_edge_attr.png") - - def test_draw_graph_attr(self): - graph = retworkx.PyGraph() - graph.add_node( - { - "color": "black", - "fillcolor": "green", - "label": "a", - "style": "filled", - } - ) - graph.add_node( - { - "color": "black", - "fillcolor": "red", - "label": "a", - "style": "filled", - } - ) - graph.add_edge(0, 1, dict(label="1", name="1")) - graph_attr = {"bgcolor": "red"} - image = graphviz_draw(graph, lambda node: node, lambda edge: edge, graph_attr) - self.assertIsInstance(image, PIL.Image.Image) - _save_image(image, "test_graphviz_draw_graph_attr.png") - - def test_image_type(self): - graph = retworkx.directed_gnp_random_graph(50, 0.8) - image = graphviz_draw(graph, image_type="jpg") - self.assertIsInstance(image, PIL.Image.Image) - _save_image(image, "test_graphviz_draw_image_type.jpg") - - def test_image_type_invalid_type(self): - graph = retworkx.directed_gnp_random_graph(50, 0.8) - with self.assertRaises(ValueError): - graphviz_draw(graph, image_type="raw") - - def test_method(self): - graph = retworkx.directed_gnp_random_graph(50, 0.8) - image = graphviz_draw(graph, method="sfdp") - self.assertIsInstance(image, PIL.Image.Image) - _save_image(image, "test_graphviz_method.png") - - def test_method_invalid_method(self): - graph = retworkx.directed_gnp_random_graph(50, 0.8) - with self.assertRaises(ValueError): - graphviz_draw(graph, method="special") - - def test_filename(self): - graph = retworkx.generators.grid_graph(20, 20) - graphviz_draw( - graph, - filename="test_graphviz_filename.svg", - image_type="svg", - method="neato", - ) - self.assertTrue(os.path.isfile("test_graphviz_filename.svg")) - if not SAVE_IMAGES: - self.addCleanup(os.remove, "test_graphviz_filename.svg") diff --git a/tests/retworkx_backwards_compat/visualization/test_mpl.py b/tests/retworkx_backwards_compat/visualization/test_mpl.py deleted file mode 100644 index 4d600c19be..0000000000 --- a/tests/retworkx_backwards_compat/visualization/test_mpl.py +++ /dev/null @@ -1,194 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# Based on the equivalent tests for the networkx matplotlib drawer: -# https://github.com/networkx/networkx/blob/ead0e65bda59862e329f2e6f1da47919c6b07ca9/networkx/drawing/tests/test_pylab.py - -import os -import unittest - -import retworkx -from retworkx.visualization import mpl_draw - -try: - import matplotlib as mpl - import matplotlib.pyplot as plt - - mpl.use("PS") - plt.rcParams["text.usetex"] = False - HAS_MPL = True -except ImportError: - HAS_MPL = False - -SAVE_IMAGES = os.getenv("RUSTWORKX_TEST_PRESERVE_IMAGES", None) - - -def _save_images(fig, path): - fig.savefig(path, dpi=400) - if not SAVE_IMAGES: - try: - os.unlink(path) - except OSError: - pass - - -@unittest.skipUnless(HAS_MPL, "matplotlib is required for running these tests") -class TestMPLDraw(unittest.TestCase): - def test_draw(self): - graph = retworkx.generators.star_graph(24) - options = {"node_color": "black", "node_size": 100, "width": 3} - fig = mpl_draw(graph, **options) - _save_images(fig, "test.png") - - def test_node_list(self): - graph = retworkx.generators.star_graph(24) - node_list = list(range(4)) + list(range(4, 10)) + list(range(10, 14)) - fig = mpl_draw(graph, node_list=node_list) - _save_images(fig, "test_node_list.png") - - def test_edge_colormap(self): - graph = retworkx.generators.star_graph(24) - colors = range(len(graph.edge_list())) - fig = mpl_draw( - graph, - edge_color=colors, - width=4, - edge_cmap=plt.cm.Blues, - with_labels=True, - ) - _save_images(fig, "test_edge_colors.png") - - def test_arrows(self): - graph = retworkx.generators.directed_star_graph(24) - fig = mpl_draw(graph) - _save_images(fig, "test_arrows.png") - - def test_empty_graph(self): - graph = retworkx.PyGraph() - fig = mpl_draw(graph) - _save_images(fig, "test_empty.png") - - def test_axes(self): - fig, ax = plt.subplots() - graph = retworkx.directed_gnp_random_graph(50, 0.75) - mpl_draw(graph, ax=ax) - _save_images(fig, "test_axes.png") - - def test_selfloop_with_single_edge_in_edge_list(self): - fig, ax = plt.subplots() - # Graph with selfloop - graph = retworkx.generators.path_graph(2) - graph.add_edge(1, 1, None) - pos = {n: (n, n) for n in graph.node_indexes()} - mpl_draw(graph, pos, ax=ax, edge_list=[(1, 1)]) - _save_images(fig, "test_self_loop.png") - - def test_draw_edges_min_source_target_margins(self): - """Test that there is a wider gap between the node and the start of an - incident edge when min_source_margin is specified. - - This test checks that the use of min_{source/target}_margin kwargs - result in shorter (more padding) between the edges and source and - target nodes. As a crude visual example, let 's' and 't' represent - source and target nodes, respectively: - Default: - s-----------------------------t - With margins: - s ----------------------- t - """ - node_shapes = ["o", "s"] - graph = retworkx.PyGraph() - graph.extend_from_edge_list([(0, 1)]) - pos = {0: (0, 0), 1: (1, 0)} # horizontal layout - - for node_shape in node_shapes: - with self.subTest(shape=node_shape): - fig, ax = plt.subplots() - mpl_draw( - graph, - pos=pos, - ax=ax, - node_shape=node_shape, - min_source_margin=100, - min_target_margin=100, - ) - _save_images(fig, "test_node_shape_%s.png" % node_shape) - - def test_alpha_iter(self): - graph = retworkx.generators.grid_graph(4, 6) - # with fewer alpha elements than nodes - plt.subplot(131) - mpl_draw(graph, alpha=[0.1, 0.2]) - # with equal alpha elements and nodes - num_nodes = len(graph) - alpha = [x / num_nodes for x in range(num_nodes)] - colors = range(num_nodes) - plt.subplot(132) - mpl_draw(graph, node_color=colors, alpha=alpha) - # with more alpha elements than nodes - alpha.append(1) - plt.subplot(133) - mpl_draw(graph, alpha=alpha) - fig = plt.gcf() - _save_images(fig, "test_alpha_iter.png") - - def test_labels_and_colors(self): - graph = retworkx.PyGraph() - graph.add_nodes_from(list(range(8))) - edge_list = [ - (0, 1, 5), - (1, 2, 2), - (2, 3, 7), - (3, 0, 6), - (5, 6, 1), - (4, 5, 7), - (6, 7, 3), - (7, 4, 7), - ] - labels = {} - labels[0] = r"$a$" - labels[1] = r"$b$" - labels[2] = r"$c$" - labels[3] = r"$d$" - labels[4] = r"$\alpha$" - labels[5] = r"$\beta$" - labels[6] = r"$\gamma$" - labels[7] = r"$\delta$" - graph.add_edges_from(edge_list) - pos = retworkx.random_layout(graph) - mpl_draw( - graph, - pos=pos, - node_list=[0, 1, 2, 3], - node_color="r", - edge_list=[(0, 1), (1, 2), (2, 3), (3, 0)], - node_size=500, - alpha=0.75, - width=1.0, - labels=lambda x: labels[x], - font_size=16, - ) - mpl_draw( - graph, - pos=pos, - node_list=[4, 5, 6, 7], - node_color="b", - node_size=500, - alpha=0.5, - edge_list=[(4, 5), (5, 6), (6, 7), (7, 4)], - width=8, - edge_color="r", - rotate=False, - edge_labels=lambda edge: labels[edge], - ) - fig = plt.gcf() - _save_images(fig, "test_labels_and_colors.png")