From 753a3c1ec298ecacc870628bc4d9794328f83ee8 Mon Sep 17 00:00:00 2001 From: "Myers, Audun D" Date: Wed, 7 Aug 2024 14:02:30 -0400 Subject: [PATCH 1/7] adding new contributor guidelines --- docs/source/contributions.rst | 50 ++++++++++++++++++ .../images/module_addition_file_structure.png | Bin 0 -> 62722 bytes docs/source/index.rst | 1 + 3 files changed, 51 insertions(+) create mode 100644 docs/source/contributions.rst create mode 100755 docs/source/images/module_addition_file_structure.png diff --git a/docs/source/contributions.rst b/docs/source/contributions.rst new file mode 100644 index 00000000..cb919d42 --- /dev/null +++ b/docs/source/contributions.rst @@ -0,0 +1,50 @@ +HyperNetX Contributor Guidelines +**************************************************** + +We welcome contributions to HyperNetX! +This document outlines the process for contributing to various aspects of the codebase. +We currently only provide guidelines for new modules, but we are not opposed to other forms of contribution to the HyperNetX library. + +Contributing New Modules +============================ + +We happily accept the contribution of new modules or methods to the HyperNetX library. We will do our best to keep modules functioning with new release but may ask contributors to update code when possible. +The required new files for any new module are listed below and an example file structure of the additional files is shown in the figure below. + +.. image:: ./images/module_addition_file_structure.png + :width: 300px + :align: right + +* Python file: Create a new Python file named **.py** under the folder **hypernetx/hypernetx/algorithms/.**. This file will contain the core functionalities of your module. + +* Jupyter Notebook: Create a Jupyter notebook under in the folder **hypernetx/tutorials/advanced/.** that demonstrates usage examples of your module. This notebook should be named **Advanced - .ipynb**. Please look at the current advanced module number and choose an appropriate number. + +* Test file: Write unit tests for your module in a file named **test_.py** under the tests folder located at **hypernetx/tests/algorithms/.**. These tests should ensure the correctness and functionality of your code. + +Step-by-Step Process +~~~~~~~~~~~~~~~~~~~~ + +#. Branch Creation: Create a new branch from the main development branch for your contribution. This allows you to isolate your changes and work independently. Use a descriptive branch name that reflects the module you're adding (e.g., add_). + +#. Code Implementation: Implement the functionalities of your module in a new **.py** file located in **hypernetx/hypernetx/algorithms/.**. Please validate that your code dependencies are not in conflict with the core HNX dependencies. Any additional dependencies should be documented thoroughly including in the notebook creation step. + +#. Documentation: Write docstrings for your code to explain the purpose and usage of functions and classes. Additionally provide an overview description of the module in the python file. For an example of the correct docstring format please see the module **hypernetx/hypernetx/algorithms/s_centrality_measures.py**. + +#. Jupyter Notebook Creation: Create a Jupyter notebook named **Advanced - .ipynb** under advanced tutorials folder **hypernetx/tutorials/advanced/.**. This notebook should showcase how to use your module and demonstrate its capabilities with thorough documentation. Additionally, please provide clear documentation on any new dependencies outside of core HNX that are required. + +#. Testing: Write unit tests in the test_.py file to ensure your module functions as expected. This should be located in the algorithm tests folder. In the top hypernetx directory you can use the makefile and the command ``make test`` to validate everything is passing. Please see other tests and follow a similar format. + +#. __init__.py Update: Update the __init__.py file in the **hypernetx/hypernetx/algorithms/** folder to import your new module. Please follow the style of importing used by the other modules. + +#. Commit and Push: Commit your changes with clear and concise commit messages describing each modification. Push your commits to your branch on the remote repository. + +#. Pull Request: Create a pull request from your branch to the main development branch. This will initiate a code review process. + +Additional Notes +~~~~~~~~~~~~~~~~~~~~ + +* Make sure your code adheres to PEP 8 style guidelines for Python code. +* Please add comments to your code to explain complex logic or non-obvious functionalities. +* During the review process, address any feedback or suggestions from reviewers promptly. + +By following these guidelines, you can ensure a smooth and efficient contribution process for adding new modules to HyperNetX. We appreciate your contributions to the project! \ No newline at end of file diff --git a/docs/source/images/module_addition_file_structure.png b/docs/source/images/module_addition_file_structure.png new file mode 100755 index 0000000000000000000000000000000000000000..b85580bee88e9cd6985f43ccc6e85b44d2765632 GIT binary patch literal 62722 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≶&xlJXL*qz6YCPn778B*^#JRDOb3CR>gq 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 literal 0 HcmV?d00001 diff --git a/docs/source/index.rst b/docs/source/index.rst index df2b8110..b0010eb8 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -61,6 +61,7 @@ Contents Visualization Widget Algorithms: Modularity and Clustering Publications + Contributors Guide license From b624f1e9c949c23a0532beda7ee4526882716664 Mon Sep 17 00:00:00 2001 From: "Myers, Audun D" Date: Wed, 7 Aug 2024 14:26:15 -0400 Subject: [PATCH 2/7] additional updates to contributions guidelines --- docs/source/contributions.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/contributions.rst b/docs/source/contributions.rst index cb919d42..9f9b3b6a 100644 --- a/docs/source/contributions.rst +++ b/docs/source/contributions.rst @@ -9,13 +9,14 @@ Contributing New Modules ============================ We happily accept the contribution of new modules or methods to the HyperNetX library. We will do our best to keep modules functioning with new release but may ask contributors to update code when possible. +Contributions can be slow, but the closer the pull request is to our guidelines the faster this process will be. The required new files for any new module are listed below and an example file structure of the additional files is shown in the figure below. .. image:: ./images/module_addition_file_structure.png :width: 300px :align: right -* Python file: Create a new Python file named **.py** under the folder **hypernetx/hypernetx/algorithms/.**. This file will contain the core functionalities of your module. +* Python file: Create a new Python file named **.py** under the folder **hypernetx/hypernetx/algorithms/.**. This file will contain the core functionalities of your module. All methods need to have docstrings in the new module. * Jupyter Notebook: Create a Jupyter notebook under in the folder **hypernetx/tutorials/advanced/.** that demonstrates usage examples of your module. This notebook should be named **Advanced - .ipynb**. Please look at the current advanced module number and choose an appropriate number. @@ -30,7 +31,7 @@ Step-by-Step Process #. Documentation: Write docstrings for your code to explain the purpose and usage of functions and classes. Additionally provide an overview description of the module in the python file. For an example of the correct docstring format please see the module **hypernetx/hypernetx/algorithms/s_centrality_measures.py**. -#. Jupyter Notebook Creation: Create a Jupyter notebook named **Advanced - .ipynb** under advanced tutorials folder **hypernetx/tutorials/advanced/.**. This notebook should showcase how to use your module and demonstrate its capabilities with thorough documentation. Additionally, please provide clear documentation on any new dependencies outside of core HNX that are required. +#. Jupyter Notebook Creation: Create a Jupyter notebook named **Advanced - .ipynb** under advanced tutorials folder **hypernetx/tutorials/advanced/.**. This notebook should showcase how to use your module and demonstrate its capabilities with thorough documentation. Additionally, in the notebook and any other documentation please provide clear documentation on any new dependencies outside of core HNX that are required. #. Testing: Write unit tests in the test_.py file to ensure your module functions as expected. This should be located in the algorithm tests folder. In the top hypernetx directory you can use the makefile and the command ``make test`` to validate everything is passing. Please see other tests and follow a similar format. @@ -46,5 +47,6 @@ Additional Notes * Make sure your code adheres to PEP 8 style guidelines for Python code. * Please add comments to your code to explain complex logic or non-obvious functionalities. * During the review process, address any feedback or suggestions from reviewers promptly. +* Any dependencies in core HNX should not be changed for new modules. Also please list any additionally dependencies thoroughly. By following these guidelines, you can ensure a smooth and efficient contribution process for adding new modules to HyperNetX. We appreciate your contributions to the project! \ No newline at end of file From bb3f233e8484f8a0c435e80d9ab04ba210fde1b0 Mon Sep 17 00:00:00 2001 From: "Myers, Audun D" Date: Wed, 14 Aug 2024 15:27:06 -0400 Subject: [PATCH 3/7] updating contributions guideline with rst documentation stuff and figure update. --- docs/source/contributions.rst | 6 +++++- .../images/module_addition_file_structure.png | Bin 62722 -> 71865 bytes 2 files changed, 5 insertions(+), 1 deletion(-) mode change 100755 => 100644 docs/source/images/module_addition_file_structure.png diff --git a/docs/source/contributions.rst b/docs/source/contributions.rst index 9f9b3b6a..8a50041b 100644 --- a/docs/source/contributions.rst +++ b/docs/source/contributions.rst @@ -13,7 +13,7 @@ Contributions can be slow, but the closer the pull request is to our guidelines The required new files for any new module are listed below and an example file structure of the additional files is shown in the figure below. .. image:: ./images/module_addition_file_structure.png - :width: 300px + :width: 330px :align: right * Python file: Create a new Python file named **.py** under the folder **hypernetx/hypernetx/algorithms/.**. This file will contain the core functionalities of your module. All methods need to have docstrings in the new module. @@ -22,6 +22,8 @@ The required new files for any new module are listed below and an example file s * Test file: Write unit tests for your module in a file named **test_.py** under the tests folder located at **hypernetx/tests/algorithms/.**. These tests should ensure the correctness and functionality of your code. +* Documentation: Write an rst file named **.rst** under the algorithms documentation folder located at **hypernetx/docs/source/algorithms/.**. This documentations should focus on the mathematics or theory behind your module with citations to relevant papers and documents. Additionally it should provide code snippets demonstrating usage that parallel the tutorial. + Step-by-Step Process ~~~~~~~~~~~~~~~~~~~~ @@ -35,6 +37,8 @@ Step-by-Step Process #. Testing: Write unit tests in the test_.py file to ensure your module functions as expected. This should be located in the algorithm tests folder. In the top hypernetx directory you can use the makefile and the command ``make test`` to validate everything is passing. Please see other tests and follow a similar format. +# Read the Docs: Include your rst file in the algorithms folder of the source docs overviewing the theory/mathematics of the new module with example code. See other rst files as examples of formatting. + #. __init__.py Update: Update the __init__.py file in the **hypernetx/hypernetx/algorithms/** folder to import your new module. Please follow the style of importing used by the other modules. #. Commit and Push: Commit your changes with clear and concise commit messages describing each modification. Push your commits to your branch on the remote repository. diff --git a/docs/source/images/module_addition_file_structure.png b/docs/source/images/module_addition_file_structure.png old mode 100755 new mode 100644 index b85580bee88e9cd6985f43ccc6e85b44d2765632..6308decb1cdfb1de7f5b978b0e39f8a9284776df GIT binary patch literal 71865 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≶&xlJXL*qz6YCPn778B*^#JRDOb3CR>gq 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 From 138e5580978485242ffaef9da65f29a1c7690778 Mon Sep 17 00:00:00 2001 From: "Myers, Audun D" Date: Wed, 9 Oct 2024 14:30:26 -0400 Subject: [PATCH 4/7] adding_HG_matching code, tests, rst, and notebook --- .../source/algorithms/matching_algorithms.rst | 61 ++ hypernetx/algorithms/matching_algorithms.py | 596 ++++++++++++++++++ tests/algorithms/test_matching.py | 180 ++++++ .../Advanced 7 - Matching algorithms.ipynb | 261 ++++++++ 4 files changed, 1098 insertions(+) create mode 100644 docs/source/algorithms/matching_algorithms.rst create mode 100644 hypernetx/algorithms/matching_algorithms.py create mode 100644 tests/algorithms/test_matching.py create mode 100644 tutorials/advanced/Advanced 7 - Matching algorithms.ipynb diff --git a/docs/source/algorithms/matching_algorithms.rst b/docs/source/algorithms/matching_algorithms.rst new file mode 100644 index 00000000..1a85b58f --- /dev/null +++ b/docs/source/algorithms/matching_algorithms.rst @@ -0,0 +1,61 @@ +Matching Algorithms for Hypergraphs +=================================== + +Introduction +------------ +This module implements various algorithms for finding matchings in hypergraphs. These algorithms are based on the methods described in the paper: + +*Distributed Algorithms for Matching in Hypergraphs* by Oussama Hanguir and Clifford Stein. + +The paper addresses the problem of finding matchings in d-uniform hypergraphs, where each hyperedge contains exactly d vertices. The matching problem is NP-complete for d ≥ 3, making it one of the classic challenges in computational theory. The algorithms described here are designed for the Massively Parallel Computation (MPC) model, which is suitable for processing large-scale hypergraphs. + +Mathematical Foundation +------------------------ +The algorithms in this module provide different trade-offs between approximation ratios, memory usage, and computation rounds: + +1. **O(d²)-approximation algorithm**: + - This algorithm partitions the hypergraph into random subgraphs and computes a matching for each subgraph. The results are combined to obtain a matching for the original hypergraph. + - Approximation ratio: O(d²) + - Rounds: 3 + - Memory: O(√nm) + +2. **d-approximation algorithm**: + - Uses sampling and post-processing to iteratively build a maximal matching. + - Approximation ratio: d + - Rounds: O(log n) + - Memory: O(dn) + +3. **d(d−1 + 1/d)²-approximation algorithm**: + - Utilizes the concept of HyperEdge Degree Constrained Subgraphs (HEDCS) to find an approximate matching. + - Approximation ratio: d(d−1 + 1/d)² + - Rounds: 3 + - Memory: O(√nm) for linear hypergraphs, O(n√nm) for general cases. + +These algorithms are crucial for applications that require scalable parallel processing, such as combinatorial auctions, scheduling, and multi-agent systems. + +Usage Example +------------- +Below is an example of how to use the matching algorithms module. + +```python +from hypernetx.algorithms import matching_algorithms as ma + +# Example hypergraph data +hypergraph = ... # Assume this is a d-uniform hypergraph + +# Compute a matching using the O(d²)-approximation algorithm +matching = ma.matching_approximation_d_squared(hypergraph) + +# Compute a matching using the d-approximation algorithm +matching_d = ma.matching_approximation_d(hypergraph) + +# Compute a matching using the d(d−1 + 1/d)²-approximation algorithm +matching_d_squared = ma.matching_approximation_dd(hypergraph) + +print(matching, matching_d, matching_d_squared) + + +References +------------- + +- Oussama Hanguir, Clifford Stein, Distributed Algorithms for Matching in Hypergraphs, https://arxiv.org/pdf/2009.09605 diff --git a/hypernetx/algorithms/matching_algorithms.py b/hypernetx/algorithms/matching_algorithms.py new file mode 100644 index 00000000..bf80b978 --- /dev/null +++ b/hypernetx/algorithms/matching_algorithms.py @@ -0,0 +1,596 @@ +""" +An implementation of the algorithms in: +"Distributed Algorithms for Matching in Hypergraphs", + by Oussama Hanguir and Clifford Stein (2020), https://arxiv.org/abs/2009.09605v1 +Programmer: Shira Rot, Niv +Date: 22.5.2024 +""" + +from functools import lru_cache +import hypernetx as hnx +from hypernetx.classes.hypergraph import Hypergraph +import math +import random +from concurrent.futures import ThreadPoolExecutor + +def approximation_matching_checking(optimal: list, approx: list) -> bool: + """ + Checks if the approximate list contains at least one element that is a subset of each element in the optimal list. + + Parameters + ---------- + optimal : list of lists + A list of lists representing the optimal solutions. + approx : list of lists + A list of lists representing the approximate solutions. + + Returns + ------- + bool + True if the approximate list contains at least one element that is a subset of each element in the optimal list, False otherwise. + """ + for e in optimal: + count = 0 + e_checks = set(e) + for e_m in approx: + e_m_checks = set(e_m) + common_elements = e_checks.intersection(e_m_checks) + checking = bool(common_elements) + if checking: + count += 1 + if count < 1: + return False + return True + + +def greedy_matching(hypergraph: Hypergraph, k: int) -> list: + """ + Greedy algorithm for hypergraph matching. + + This algorithm constructs a random k-partitioning of G and finds a maximal matching. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + A Hypergraph object. + k : int + The number of partitions. + + Returns + ------- + list + The edges of the graph for the greedy matching. + + Raises + ------ + NonUniformHypergraphError + If the hypergraph is not uniform (i.e., if the edges have different sizes). + + Examples + ------- + >>> import numpy as np + >>> np.random.seed(42) + >>> random.seed(42) + >>> edges = {'e1': [1, 2, 3], 'e2': [2, 3, 4], 'e3': [1, 4, 5]} + >>> hypergraph = Hypergraph(edges) + >>> k = 2 + >>> matching = greedy_matching(hypergraph, k) + >>> matching + [(2, 3, 4)] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> edges_large = {f'e{i}': list(range(i, i + 3)) for i in range(1, 50)} + >>> hypergraph_large = Hypergraph(edges_large) + >>> k = 5 + >>> matching_large = greedy_matching(hypergraph_large, k) + >>> len(matching_large) + 12 + + >>> edges_non_uniform = {'e1': [1, 2, 3], 'e2': [4, 5], 'e3': [6, 7, 8, 9]} + >>> hypergraph_non_uniform = Hypergraph(edges_non_uniform) + >>> try: + ... greedy_matching(hypergraph_non_uniform, k) + ... except NonUniformHypergraphError: + ... print("NonUniformHypergraphError raised") + NonUniformHypergraphError raised + """ + + # Check if the hypergraph is empty + if not hypergraph.incidence_dict: + return [] + + # Check if the hypergraph is d-uniform + edge_sizes = {len(edge) for edge in hypergraph.incidence_dict.values()} + if len(edge_sizes) > 1: + raise NonUniformHypergraphError("The hypergraph is not d-uniform.") + + # Partition the hypergraph into k subgraphs + partitions = partition_hypergraph(hypergraph, k) + + # Find maximum matching for each partition in parallel + with ThreadPoolExecutor() as executor: + MM_list = list(executor.map(maximal_matching, partitions)) + + # Initialize the matching set + M = set() + + # Process each partition's matching + for MM_Gi in MM_list: + # Add edges to M if they do not violate the matching property + for edge in MM_Gi: + if not any(set(edge) & set(matching_edge) for matching_edge in M): + M.add(tuple(edge)) + + return list(M) + + +class MemoryLimitExceededError(Exception): + """Custom exception to indicate memory limit exceeded during hypergraph matching.""" + + pass + + +class NonUniformHypergraphError(Exception): + """Custom exception to indicate non d-uniform hypergraph during matching.""" + + pass + + +# necessary because Python's lru_cache decorator +# requires hashable inputs to cache function results. +def edge_tuple(hypergraph): + """ + Converts hypergraph edges to a hashable tuple. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + A Hypergraph object. + + Returns + ------- + tuple + A tuple representing the hypergraph edges, where each element is a tuple containing the edge name and its sorted vertices. + """ + return tuple( + (edge, tuple(sorted(hypergraph.edges[edge]))) + for edge in sorted(hypergraph.edges) + ) + + +@lru_cache(maxsize=None) # to cache the results of this function +def cached_maximal_matching(edges): + """ + Cached version of maximal matching calculation. + + Parameters + ---------- + edges : tuple + A tuple representing the hypergraph edges, where each element is a tuple containing the edge name and its sorted vertices. + + Returns + ------- + list + A list of matching edges. + """ + hypergraph = hnx.Hypergraph( + dict(edges) + ) # Converts the tuple of edges back into a hypergraph. + matching = [] + matched_vertices = set() # vertices that have already been matched. + + for edge in hypergraph.incidence_dict.values(): + if not any( + vertex in matched_vertices for vertex in edge + ): # Checks if current edge is already matched. + matching.append(sorted(edge)) # Adds the current edge to the matching. + matched_vertices.update(edge) + return matching # Returns the list of matching edges. + + +def maximal_matching(hypergraph: Hypergraph) -> list: + """ + Finds a maximal matching in the hypergraph. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + A Hypergraph object. + + Returns + ------- + list + A list of matching edges. + """ + edges = edge_tuple(hypergraph) + return cached_maximal_matching(edges) + + +def sample_edges(hypergraph: Hypergraph, p: float) -> Hypergraph: + """ + Samples edges from the hypergraph with probability p. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + The input hypergraph. + p : float + The probability of sampling each edge. + + Returns + ------- + hnx.Hypergraph + A new hypergraph containing the sampled edges. + """ + sampled_edges = [ + edge for edge in hypergraph.incidence_dict.values() if random.random() < p + ] + return hnx.Hypergraph( + {f"e{i}": tuple(edge) for i, edge in enumerate(sampled_edges)} + ) + + +def sampling_round(S: Hypergraph, p: float, s: int) -> tuple: + """ + Performs a single sampling round on the hypergraph. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + The input hypergraph. + p : float + The probability of sampling each edge. + s : int + The maximum number of edges to include in the matching. + + Returns + ------- + tuple + A tuple containing the maximal matching and the sampled hypergraph. If the sampled hypergraph has more than s edges, None and the sampled hypergraph are returned. + """ + E_prime = sample_edges(S, p) + if len(E_prime.incidence_dict.values()) > s: + return None, E_prime + matching = maximal_matching(E_prime) + return matching, E_prime + + +def iterated_sampling( + hypergraph: Hypergraph, s: int, max_iterations: int = 100 +) -> list: + """ + Iterated Sampling for Hypergraph Matching. + + Uses iterated sampling to find a maximal matching in a d-uniform hypergraph. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + A Hypergraph object. + s : int + The amount of memory available for the computer. + max_iterations : int, optional + The maximum number of iterations to perform. Defaults to 100. + + Returns + ------- + list + The edges of the graph for the approximate matching. + + Raises + ------ + MemoryLimitExceededError + If the memory limit is exceeded during the matching process. + + Examples + ------- + >>> import numpy as np + >>> np.random.seed(42) + >>> random.seed(42) + >>> hypergraph = Hypergraph({0: (1, 2, 3), 1: (2, 3, 4), 2: (3, 4, 5)}) + >>> result = iterated_sampling(hypergraph, 1) + >>> result + [[2, 3, 4]] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> hypergraph = Hypergraph({0: (1, 2, 3, 4), 1: (2, 3, 4, 5), 2: (3, 4, 5, 6)}) + >>> result = iterated_sampling(hypergraph, 2) + >>> result + [[2, 3, 4, 5]] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> hypergraph = Hypergraph({0: (1, 2, 3), 1: (4, 5, 6)}) + >>> result = None + >>> try: + ... result = iterated_sampling(hypergraph, 0) # Insufficient memory, expect failure + ... except MemoryLimitExceededError: + ... pass + >>> result is None + True + + >>> np.random.seed(42) + >>> random.seed(42) + >>> hypergraph = Hypergraph({0: (1, 2, 3), 1: (4, 5, 6)}) + >>> result = iterated_sampling(hypergraph, 10) # Large enough memory, expect a result + >>> result + [[4, 5, 6], [1, 2, 3]] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> hypergraph = Hypergraph({0: (1, 2, 3), 1: (2, 3, 4), 2: (3, 4, 5), 3: (5, 6, 7), 4: (6, 7, 8), 5: (7, 8, 9)}) + >>> result = iterated_sampling(hypergraph, 3) + >>> result + [[2, 3, 4], [5, 6, 7]] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> s = 10 + >>> edges_d4 = {'e1': [1, 2, 3, 4], 'e2': [2, 3, 4, 5], 'e3': [3, 4, 5, 6], 'e4': [4, 5, 6, 7]} + >>> hypergraph_d4 = Hypergraph(edges_d4) + >>> approximate_matching_d4 = iterated_sampling(hypergraph_d4, s) + >>> approximate_matching_d4 + [[2, 3, 4, 5]] + + >>> edges_d5 = {'e1': [1, 2, 3, 4, 5], 'e2': [2, 3, 4, 5, 6], 'e3': [3, 4, 5, 6, 7]} + >>> hypergraph_d5 = Hypergraph(edges_d5) + >>> approximate_matching_d5 = iterated_sampling(hypergraph_d5, s) + >>> approximate_matching_d5 + [[1, 2, 3, 4, 5]] + + >>> edges_d6 = {'e1': [1, 2, 3, 4, 5, 6], 'e2': [2, 3, 4, 5, 6, 7], 'e3': [3, 4, 5, 6, 7, 8]} + >>> hypergraph_d6 = Hypergraph(edges_d6) + >>> approximate_matching_d6 = iterated_sampling(hypergraph_d6, s) + >>> approximate_matching_d6 + [[1, 2, 3, 4, 5, 6]] + + >>> edges_large = {f'e{i}': [i, i + 1, i + 2] for i in range(1, 101)} + >>> hypergraph_large = Hypergraph(edges_large) + >>> approximate_matching_large = iterated_sampling(hypergraph_large, s) + >>> len(approximate_matching_large) + 26 + """ + + d = max((len(edge) for edge in hypergraph.incidence_dict.values()), default=0) + M = [] + S = hypergraph + p = s / (5 * len(S.edges) * d) if len(S.edges) > 0 else 0 + iterations = 0 + + while iterations < max_iterations: + iterations += 1 + M_prime, E_prime = sampling_round(S, p, s) + if M_prime is None: + raise MemoryLimitExceededError( + "Memory limit exceeded during hypergraph matching" + ) + + M.extend(M_prime) + unmatched_vertices = set(S.nodes) - set(v for edge in M_prime for v in edge) + induced_edges = [ + edge + for edge in S.incidence_dict.values() + if all(v in unmatched_vertices for v in edge) + ] + if len(induced_edges) <= s: + M.extend( + maximal_matching( + hnx.Hypergraph( + {f"e{i}": tuple(edge) for i, edge in enumerate(induced_edges)} + ) + ) + ) + break + S = hnx.Hypergraph( + {f"e{i}": tuple(edge) for i, edge in enumerate(induced_edges)} + ) + p = s / (5 * len(S.edges) * d) if len(S.edges) > 0 else 0 + + if iterations >= max_iterations: + raise MemoryLimitExceededError( + "Max iterations reached without finding a solution" + ) + + return M + + +def check_beta_condition(beta, beta_minus, d): + """ + Checks if the beta condition is satisfied. + + Parameters + ---------- + beta : int + The current beta value. + beta_minus : int + The previous beta value. + d : int + The degree of the hypergraph. + + Returns + ------- + bool + True if the beta condition is satisfied, False otherwise. + """ + return (beta - beta_minus) >= (d - 1) + + +def build_HEDCS(hypergraph, beta, beta_minus): + """ + Constructs a Hyper-Edge Degree Constrained Subgraph (HEDCS) from the given hypergraph. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + The input hypergraph. + beta : int + Degree threshold for adding edges. + beta_minus : int + Complementary degree threshold for adding edges. + + Returns + ------- + hnx.Hypergraph + The constructed HEDCS. + """ + H = hnx.Hypergraph(hypergraph.incidence_dict) # Initialize H to be equal to G + degrees = {node: 0 for node in hypergraph.nodes} # Initialize vertex degrees + + for edge in H.edges: + for node in H.edges[edge]: + degrees[node] += 1 + + while True: + violating_edge = None + for edge in list(H.edges): + edge_degree_sum = sum(degrees[node] for node in H.edges[edge]) + if edge_degree_sum > beta: + violating_edge = edge + H.remove_edge(violating_edge) + for node in H.edges[violating_edge]: + degrees[node] -= 1 + break + + for edge in list(hypergraph.edges): + if edge not in H.edges: + edge_degree_sum = sum(degrees[node] for node in hypergraph.edges[edge]) + if edge_degree_sum < beta_minus: + violating_edge = edge + H.add_edge(violating_edge, hypergraph.edges[violating_edge]) + for node in H.edges[violating_edge]: + degrees[node] += 1 + break + + if violating_edge is None: + break + return H + + +def partition_hypergraph(hypergraph, k): + """ + Partitions a hypergraph into k approximately equal-sized subgraphs. + + Parameters + ---------- + hypergraph : hnx.Hypergraph + The input hypergraph. + k : int + The number of partitions. + + Returns + ------- + list[hnx.Hypergraph] + A list of k partitioned hypergraphs. + """ + edges = list(hypergraph.incidence_dict.items()) + random.shuffle(edges) + partitions = [edges[i::k] for i in range(k)] + return [hnx.Hypergraph(dict(part)) for part in partitions] + + +def HEDCS_matching(hypergraph: Hypergraph, s: int) -> list: + """ + HEDCS-Matching for Approximate Hypergraph Matching. + + This algorithm constructs Hyper-Edge Degree Constrained Subgraphs (HEDCS) + to find an approximate maximal matching in a d-uniform hypergraph. It leverages + parallelization to efficiently handle larger hypergraphs. + + Parameters + ---------- + hypergraph : Hypergraph + The input hypergraph. + s : int + The amount of memory available per machine. + + Returns + ------- + list + The edges of the graph for the approximate matching. + + Raises + ------- + NonUniformHypergraphError + If the hypergraph is not d-uniform (all edges don't have the same size). + ValueError + If the calculated beta and beta_minus values do not satisfy the beta condition. + + Examples + ------- + >>> import numpy as np + >>> np.random.seed(42) + >>> random.seed(42) + >>> hypergraph = Hypergraph({0: (1, 2)}) + >>> result = HEDCS_matching(hypergraph, 10) + >>> result + [[1, 2]] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> hypergraph = Hypergraph({0: (1, 2), 1: (3, 4)}) + >>> result = HEDCS_matching(hypergraph, 10) + >>> result + [[1, 2], [3, 4]] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> edges = {'e1': [1, 2, 3], 'e2': [2, 3, 4], 'e3': [1, 4, 5]} + >>> hypergraph = Hypergraph(edges) + >>> s = 10 + >>> approximate_matching = HEDCS_matching(hypergraph, s) + >>> approximate_matching + [[1, 2, 3]] + + >>> np.random.seed(42) + >>> random.seed(42) + >>> edges_large = {f'e{i}': [i, i + 1, i + 2] for i in range(1, 101)} + >>> hypergraph_large = Hypergraph(edges_large) + >>> approximate_matching_large = HEDCS_matching(hypergraph_large, s) + >>> len(approximate_matching_large) + 34 + """ + + edge_sizes = {len(edge) for edge in hypergraph.incidence_dict.values()} + if len(edge_sizes) > 1: + raise NonUniformHypergraphError("The hypergraph is not d-uniform.") + + d = next(iter(edge_sizes)) + n = len(hypergraph.nodes) + m = len(hypergraph.edges) + + beta = 500 * d * 3 * n * 2 * (math.log(n) * 3) + gamma = 1 / (2 * n * math.log(n)) + k = math.ceil(m / (s * math.log(n))) + beta_minus = (1 - gamma) * beta + + if not check_beta_condition(beta, beta_minus, d): + raise ValueError(f"beta - beta_minus must be >= {d - 1}") + + # Partition the hypergraph + partitions = partition_hypergraph(hypergraph, k) + + # Build HEDCS for each partition in parallel + with ThreadPoolExecutor() as executor: + HEDCS_list = list( + executor.map(lambda part: build_HEDCS(part, beta, beta_minus), partitions) + ) + + # Combine all the edges from the HEDCS subgraphs + combined_edges = {} + for H in HEDCS_list: + combined_edges.update(H.incidence_dict) + + combined_hypergraph = hnx.Hypergraph(combined_edges) + + # Find the maximum matching in the combined hypergraph + max_matching = maximal_matching(combined_hypergraph) + + return max_matching + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/tests/algorithms/test_matching.py b/tests/algorithms/test_matching.py new file mode 100644 index 00000000..4b38fc7f --- /dev/null +++ b/tests/algorithms/test_matching.py @@ -0,0 +1,180 @@ +""" +An implementation of the algorithms in: +"Distributed Algorithms for Matching in Hypergraphs", by Oussama Hanguir and Clifford Stein (2020), https://arxiv.org/abs/2009.09605v1 +Programmer: Shira Rot, Niv +Date: 22.5.2024 +""" + +import pytest +from hypernetx.classes.hypergraph import Hypergraph +from hypernetx.algorithms.matching_algorithms import ( + greedy_matching, + HEDCS_matching, + MemoryLimitExceededError, + approximation_matching_checking, +) +from hypernetx.algorithms.matching_algorithms import iterated_sampling + + +def test_greedy_d_approximation_empty_input(): + """ + Test for an empty input hypergraph. + """ + k = 2 + empty_hypergraph = Hypergraph({}) + assert greedy_matching(empty_hypergraph, k) == [] + + +def test_greedy_d_approximation_small_inputs(): + """ + Test for small input hypergraphs. + """ + k = 2 + hypergraph_1 = Hypergraph({"e1": {1, 2, 3}, "e2": {4, 5, 6}}) + assert greedy_matching(hypergraph_1, k) == [(1, 2, 3), (4, 5, 6)] + + hypergraph_2 = Hypergraph( + { + "e1": {1, 2, 3}, + "e2": {4, 5, 6}, + "e3": {7, 8, 9}, + "e4": {1, 4, 7}, + "e5": {2, 5, 8}, + "e6": {3, 6, 9}, + } + ) + result = greedy_matching(hypergraph_2, k) + assert len(result) == 3 + assert all(edge in [(1, 2, 3), (4, 5, 6), (7, 8, 9)] for edge in result) + + +def test_greedy_d_approximation_large_input(): + """ + Test for a large input hypergraph. + """ + k = 2 + large_hypergraph = Hypergraph( + {f"e{i}": {i, i + 1, i + 2} for i in range(1, 100, 3)} + ) + result = greedy_matching(large_hypergraph, k) + assert len(result) == len(large_hypergraph.edges) + assert all(edge in [(i, i + 1, i + 2) for i in range(1, 100, 3)] for edge in result) + + +def test_iterated_sampling_single_edge(): + """ + Test for a hypergraph with a single edge. + It checks if the result is not None and if all edges in the result have at least 2 vertices. + """ + hypergraph = Hypergraph({0: (1, 2, 3)}) + result = iterated_sampling(hypergraph, 10) + assert result is not None and all(len(edge) >= 2 for edge in result) + + +def test_iterated_sampling_two_disjoint_edges(): + """ + Test for a hypergraph with two disjoint edges. + It checks if the result is not None and if all edges in the result have at least 2 vertices. + """ + hypergraph = Hypergraph({0: (1, 2), 1: (3, 4)}) + result = iterated_sampling(hypergraph, 10) + assert result is not None and all(len(edge) >= 2 for edge in result) + + +def test_iterated_sampling_insufficient_memory(): + """ + Test for a hypergraph with insufficient memory. + It checks if the function raises a MemoryLimitExceededError when memory is set to 0. + """ + hypergraph = Hypergraph({0: (1, 2, 3)}) + with pytest.raises(MemoryLimitExceededError): + iterated_sampling(hypergraph, 0) + + +def test_iterated_sampling_large_memory(): + """ + Test for a hypergraph with sufficient memory. + It checks if the result is not None when memory is set to 10. + """ + hypergraph = Hypergraph({0: (1, 2, 3), 1: (4, 5, 6)}) + result = iterated_sampling(hypergraph, 10) + assert result is not None + + +def test_iterated_sampling_max_iterations(): + """ + Test for a hypergraph reaching maximum iterations. + """ + hypergraph = Hypergraph( + { + 0: (1, 2, 3), + 1: (2, 3, 4), + 2: (3, 4, 5), + 3: (5, 6, 7), + 4: (6, 7, 8), + 5: (7, 8, 9), + } + ) + result = iterated_sampling(hypergraph, 3) + assert result is None or all(len(edge) >= 2 for edge in result) + + +def test_iterated_sampling_large_hypergraph(): + """ + Test for a large hypergraph. + """ + edges_large = {f"e{i}": [i, i + 1, i + 2] for i in range(1, 101)} + hypergraph_large = Hypergraph(edges_large) + optimal_matching_large = [edges_large[f"e{i}"] for i in range(1, 101, 3)] + result = iterated_sampling(hypergraph_large, 10) + assert result is not None and approximation_matching_checking( + optimal_matching_large, result + ) + + +def test_HEDCS_matching_single_edge(): + """ + Test for a hypergraph with a single edge. + """ + hypergraph = Hypergraph({0: (1, 2)}) + result = HEDCS_matching(hypergraph, 10) + assert result is not None and all(len(edge) >= 2 for edge in result) + + +def test_HEDCS_matching_two_edges(): + """ + Test for a hypergraph with two disjoint edges. + """ + hypergraph = Hypergraph({0: (1, 2), 1: (3, 4)}) + result = HEDCS_matching(hypergraph, 10) + assert result is not None and all(len(edge) >= 2 for edge in result) + + +def test_HEDCS_matching_with_optimal_matching(): + """ + Test with a hypergraph where the optimal matching is known. + """ + edges = {"e1": [1, 2, 3], "e2": [2, 3, 4], "e3": [1, 4, 5]} + hypergraph = Hypergraph(edges) + s = 10 + optimal_matching = [[1, 2, 3]] # Assuming we know the optimal matching + approximate_matching = HEDCS_matching(hypergraph, s) + assert approximation_matching_checking(optimal_matching, approximate_matching) + + +def test_HEDCS_matching_large_hypergraph(): + """ + Test with a larger hypergraph. + """ + edges_large = {f"e{i}": [i, i + 1, i + 2] for i in range(1, 101)} + hypergraph_large = Hypergraph(edges_large) + s = 10 + optimal_matching_large = [edges_large[f"e{i}"] for i in range(1, 101, 3)] + approximate_matching_large = HEDCS_matching(hypergraph_large, s) + assert approximation_matching_checking( + optimal_matching_large, approximate_matching_large + ) + + +if __name__ == "__main__": + pytest.main() diff --git a/tutorials/advanced/Advanced 7 - Matching algorithms.ipynb b/tutorials/advanced/Advanced 7 - Matching algorithms.ipynb new file mode 100644 index 00000000..9146655d --- /dev/null +++ b/tutorials/advanced/Advanced 7 - Matching algorithms.ipynb @@ -0,0 +1,261 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hypergraph Matching Algorithms Tutorial\n", + "\n", + "This tutorial highlights the implementation and usage of several hypergraph matching algorithms as presented in our publication: [Distributed Algorithms for Matching in Hypergraphs](https://arxiv.org/abs/2009.09605v1).\n", + "\n", + "## Algorithms Covered\n", + "- Greedy Matching\n", + "- Iterated Sampling\n", + "- HEDCS Matching\n", + "\n", + "We will demonstrate how to use these algorithms with example hypergraphs and compare their performance." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import hypernetx as hnx\n", + "from hypernetx.classes.hypergraph import Hypergraph\n", + "from hypernetx.algorithms.matching_algorithms import greedy_matching, iterated_sampling, HEDCS_matching\n", + "import random\n", + "import logging\n", + "import time\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example Hypergraph" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Example hypergraph data\n", + "hypergraph_data = {\n", + " 0: (1, 2, 3),\n", + " 1: (4, 5, 6),\n", + " 2: (7, 8, 9),\n", + " 3: (1, 4, 7),\n", + " 4: (2, 5, 8),\n", + " 5: (3, 6, 9)\n", + "}\n", + "\n", + "# Creating a Hypergraph\n", + "hypergraph = Hypergraph(hypergraph_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Greedy Matching Algorithm\n", + "The Greedy Matching algorithm constructs a random k-partitioning of the hypergraph and finds a maximal matching. \n", + "\n", + "### Parameters:\n", + "- `hypergraph`: The input hypergraph.\n", + "- `k`: The number of partitions to divide the hypergraph into.\n", + "\n", + "### Example Usage:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Greedy Matching Result: [(7, 8, 9), (1, 2, 3), (4, 5, 6)]\n" + ] + } + ], + "source": [ + "k = 3\n", + "greedy_result = greedy_matching(hypergraph, k)\n", + "print(\"Greedy Matching Result:\", greedy_result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Iterated Sampling Algorithm\n", + "The Iterated Sampling algorithm uses sampling to find a maximal matching in a d-uniform hypergraph. \n", + "\n", + "### Parameters:\n", + "- `hypergraph`: The input hypergraph.\n", + "- `s`: The number of samples to use in the algorithm.\n", + "\n", + "### Example Usage:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iterated Sampling Result: [[7, 8, 9], [1, 2, 3], [4, 5, 6]]\n" + ] + } + ], + "source": [ + "s = 10\n", + "iterated_result = iterated_sampling(hypergraph, s)\n", + "print(\"Iterated Sampling Result:\", iterated_result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## HEDCS Matching Algorithm\n", + "The HEDCS Matching algorithm constructs a Hyper-Edge Degree Constrained Subgraph (HEDCS) to find a maximal matching. \n", + "\n", + "### Parameters:\n", + "- `hypergraph`: The input hypergraph.\n", + "- `s`: The number of samples to use in the algorithm.\n", + "\n", + "### Example Usage:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "HEDCS Matching Result: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n" + ] + } + ], + "source": [ + "hedcs_result = HEDCS_matching(hypergraph, s)\n", + "print(\"HEDCS Matching Result:\", hedcs_result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Performance Comparison\n", + "We will compare the performance of the algorithms on large random hypergraphs." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAIjCAYAAAA0vUuxAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAACet0lEQVR4nOzdd3gUVd/G8e+mJ4SEnlACCYROAAGRIh2NiDSlioQmShVERFAfKSIISkfB8tAUpCmgoICU0IsgICK9S68JCaTuvn/sw74sCZCEJJNyf65rLzJnZ2Z/WzLsnXPmjMlisVgQERERERGRh3IwugAREREREZGMTsFJRERERETkMRScREREREREHkPBSURERERE5DEUnERERERERB5DwUlEREREROQxFJxEREREREQeQ8FJRERERETkMRScREREREREHkPBScQAn332GcWLF8fR0ZHKlSsbXY5kcqGhoZhMJkJDQ40u5YnExcUxePBg/Pz8cHBwoGXLlkaXlC2dPn0ak8nE559/bnQpaeLe78uSJUseu26XLl3w9/dP+6Ke0OzZszGZTJw+fdqQx0/OMSg5r79IRqPgJML//6dz7+bm5kapUqXo27cvly9fTtXHWrNmDYMHD6Z27drMmjWL0aNHp+r+s6vQ0FBefvllfH19cXFxoUCBAjRr1oyffvrJ6NIkiWbOnMlnn31G69atmTNnDm+//fZD161fvz4VKlRI9L6s/sU/o7v3xdhkMvH9998nuk7t2rUxmUwPfQ8f58svv2T27NlPUGXmUr16dUwmE9OnTze6lCSbP38+kyZNMroMkVTlZHQBIhnJyJEjCQgIICoqii1btjB9+nR+/fVX/v77bzw8PFLlMdavX4+DgwP//e9/cXFxSZV9ZnfDhg1j5MiRlCxZkjfffJNixYpx/fp1fv31V1555RXmzZvHq6++anSZaaZu3brcvXs303+e1q9fT+HChZk4caLRpUgqcHNzY/78+bz22mt27adPn2bbtm24ubmleN9ffvkl+fLlo0uXLk9Y5aN98803mM3mNH2Mxzl27Bh//PEH/v7+zJs3j169ehlaT2ISOwbNnz+fv//+mwEDBhhXmEgqU3ASuU+TJk2oVq0aAK+//jp58+ZlwoQJLF++nA4dOjzRvu/cuYOHhwdXrlzB3d091b7kWiwWoqKicHd3T5X9ZTZLlixh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7Pd2zJgxFpPJZDlz5kyCffTr18/WZjabLU2bNrW4uLhYrl69arFY/v/znzdvXsuNGzds6977ffvll18SPN797n0eFy9ebFmxYoXFZDJZzp49a7FYLJZ3333XdjxJ7P1O6jGofPnylnr16iVYNynHnHv1lS1b1hIdHW27f/LkyRbAcuDAAVtb586d7Y6TyXltgoKCLEWKFLHcvn3b1hYaGmoBEhx7H6Zv374WPz8/W+1r1qyxAJa9e/farXfv/7BTp05ZLBaL5dKlSxYnJydLy5Yt7dYbPny4BbD7zA8YMMAC2B2Db9++bQkICLD4+/vbjk/JOQZZLBZL06ZNE32eyXn97/3uzJ8/39Z2+PBhC2BxcHCw7Nixw9a+evXqBL833t7elj59+iSoQSSlNFRP5D6NGzcmf/78+Pn50b59ezw9PVm6dCmFCxfmp59+wmw207ZtW65du2a7+fr6UrJkSTZs2GC3L1dXV7p27Zqkx/31118BGDhwoF37O++8A5BgyERAQADBwcGJ7iskJMTur8HPPPMMFouFbt262a33zDPPcO7cOeLi4mxt958nFRYWxrVr16hXrx4nT560G+IFUK5cOerUqWNbzp8/P6VLl+bkyZO2th9//JFKlSol+IslgMlkAqx/LS9btixlypSxe13vDZN88HW9X3h4OECSepvA+jr7+vrana/m7OzMW2+9RUREBBs3brRbv02bNrbeGbC+ZgCvvfYaTk5Odu0xMTGcP3/ebvtChQrZPXcvLy9CQkLYu3cvly5dAqyfEwcH66E4Pj6e69ev4+npSenSpRMdTtK5c+fHns92r+bVq1dz586dh74WkPTPXFLe74c9jqOjI2+99VaCx7FYLPz222+P3P5R/P39+f333xPcEpvJrW3btri5uTFv3jxb2+rVq7l27VqCyQuABD2s/fr1sz0fIFWOB6tWrcLZ2ZkePXrY2hwcHBI89v0Smxjg/s9DZGQk165do1atWlgsFvbu3Ztg/b59+9p+NplM9O3bl5iYmATDnNq1a0fu3Llty/fe/8e95/d7/vnnyZMnDwsWLMBisbBgwYJHni+anGNQYpJyzLmna9eudr0lyXl+j3ttLly4wIEDBwgJCbHraalXrx5BQUGP3T9YexgXLlxIu3btbLXfG8Z4/+c4MevWrSMuLo7evXvbtd/7HN/v119/pXr16jz7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ZcuYOHEic+fOZenSpXh4eFC8eHH69++fpGFQo0aNomHDhkyZMoXp06dz48YNcufOTY0aNVi+fLntvXF3dyc0NJQhQ4YwZ84cwsPDKV26NLNmzUpwQcjUULJkSaZOncq7777LkSNHCAgIYOHChXYzIr7//vtERkYyf/58Fi5cSJUqVVi5ciVDhgxJ8eNWqlSJ4OBgfvnlF86fP4+HhweVKlXit99+o0aNGrb10uMz5+DgwM8//8xHH33EwoULmTVrFv7+/nz22We2GfzS073rTh06dMh2AdnELFy4kI8++oghQ4bg5ORE3759+eyzz+zWedLjgaOjIytXrqR///7MmTMHBwcHWrVqxbBhw6hduzZubm6P3YezszO//PKL7Rw2Nzc3WrVqRd++fRMNCY6OjqxatYpevXrx7rvvkjNnToYNG2Z3PTejJOcY9NFHH3HmzBnGjRvH7du3qVevHg0bNkzSMSe9NGvWjB9++IHhw4czZMgQSpYsyezZs5kzZw4HDx586HZXrlxh7dq1dOjQ4aHn8TRq1AgPDw++//77RIMTwNixY/Hw8OCbb75h7dq11KxZkzVr1vDss8/afbZ8fHzYtm0b7733HlOnTiUqKoqKFSvyyy+/PFHPc+/evdm3bx+zZs1i4sSJFCtWLF2Dk4eHB71792bNmjW2WTADAwP58ssvE52dUiQpTJbMdGaviEgm4e/vT4UKFWzDBCXjeOqpp8iTJw/r1q1LcN/w4cMZMWIEV69efeJzzFJq2bJltGrVii1btlC7du1U22+XLl1YsmTJY3s7JG1VrlyZ/PnzP/Q8tLR069YtcufOzahRo2wXDxaRpNM5TiIikm3s3r2bffv22U2kYKS7d+/aLcfHxzN16lS8vLyoUqWKQVVJaoiNjU1wrmFoaCj79++nfv36af74D3624P/PaUyPxxfJijRUT0REsry///6bPXv2MH78eAoWLEi7du2MLgmwXpD07t271KxZk+joaH766Se2bdvG6NGjU23aZzHG+fPnady4Ma+99hqFChXi8OHDzJgxA19fX3r27Jnmj79w4UJmz57Niy++iKenJ1u2bOGHH37g+eefT9WeTJHsRMFJRESyvCVLljBy5EhKly7NDz/8kKTzh9JDw4YNGT9+PCtWrCAqKorAwECmTp1K3759jS5NnlDu3LmpWrUq3377LVevXiVHjhw0bdqUTz/9NNGLW6e2ihUr4uTkxLhx4wgPD7dNGDFq1Kg0f2yRrErnOImIiIiIiDyGznESERERERF5DAUnERERERGRx8h25ziZzWYuXLhAzpw5k3RxQRERERERyZosFgu3b9+mUKFCj73gc7YLThcuXMDPz8/oMkREREREJIM4d+7cYy+Une2CU86cOQHri+Pl5WVwNSIiIiIiYpTw8HD8/PxsGeFRsl1wujc8z8vLS8FJRERERESSdAqPJocQERERERF5DAUnERERERGRx1BwEhEREREReYxsd45TUlgsFuLi4oiPjze6FJHHcnR0xMnJSdPri4iIiKQhBacHxMTEcPHiRe7cuWN0KSJJ5uHhQcGCBXFxcTG6FBEREZEsScHpPmazmVOnTuHo6EihQoVwcXHRX/ElQ7NYLMTExHD16lVOnTpFyZIlH3vxNhERERFJPgWn+8TExGA2m/Hz88PDw8PockSSxN3dHWdnZ86cOUNMTAxubm5GlyQiIiKS5ehP04nQX+wls9FnVkRERCRt6duWiIiIiIjIYyg4iYiIiIiIPIaCk6Sp4cOHU7lyZaPLeGKhoaGYTCZu3br10HWyynMVERERkYQUnLKQS5cu0b9/fwIDA3Fzc8PHx4fatWszffr0TD29ur+/PyaTiQULFiS4r3z58phMJmbPnp3k/c2ePZtcuXKlXoH/M2jQINatW5fq+xURERER42lWvSzi5MmT1K5dm1y5cjF69GiCgoJwdXXlwIEDfP311xQuXJjmzZsnum1sbCzOzs7pXHHy+Pn5MWvWLNq3b29r27FjB5cuXSJHjhwGVvb/PD098fT0NLoMEREREUkD6nF6DIvFwp2YOENuFoslyXX27t0bJycndu/eTdu2bSlbtizFixenRYsWrFy5kmbNmtnWNZlMTJ8+nebNm5MjRw4++eQTAJYvX06VKlVwc3OjePHijBgxgri4ONt2t27d4vXXXyd//vx4eXnRsGFD9u/fb1fHp59+io+PDzlz5qR79+5ERUXZ7tu0aRPOzs5cunTJbpsBAwZQp06dRz6/jh07snHjRs6dO2drmzlzJh07dsTJyT7/T5gwgaCgIHLkyIGfnx+9e/cmIiICsA6569q1K2FhYZhMJkwmE8OHDwcgOjqa9957Dz8/P1xdXQkMDOS///2v3b737NlDtWrV8PDwoFatWhw5csR234ND9bp06ULLli35/PPPKViwIHnz5qVPnz7Exsba1rl48SJNmzbF3d2dgIAA5s+fj7+/P5MmTXrk6yEiIiIi6Us9To9xNzaech+tNuSx/xkZjIfL49+i69evs2bNGkaPHv3Q3pcHL+Q7fPhwPv30UyZNmoSTkxObN28mJCSEKVOmUKdOHU6cOMEbb7wBwLBhwwBo06YN7u7u/Pbbb3h7e/PVV1/RqFEjjh49Sp48eVi0aBHDhw/niy++4Nlnn+W7775jypQpFC9eHIC6detSvHhxvvvuO959913A2ts1b948xo0b98jn6OPjQ3BwMHPmzOHDDz/kzp07LFy4kI0bNzJ37ly7dR0cHJgyZQoBAQGcPHmS3r17M3jwYL788ktq1arFpEmT+Oijj2yh514vUUhICNu3b2fKlClUqlSJU6dOce3aNbt9f/DBB4wfP578+fPTs2dPunXrxtatWx9a94YNGyhYsCAbNmzg+PHjtGvXjsqVK9OjRw/bY167do3Q0FCcnZ0ZOHAgV65ceeRrISIiIiLpTz1OWcDx48exWCyULl3arj1fvny24WPvvfee3X2vvvoqXbt2pXjx4hQtWpQRI0YwZMgQOnfuTPHixXnuuef4+OOP+eqrrwDYsmULu3btYvHixVSrVo2SJUvy+eefkytXLpYsWQLApEmT6N69O927d6d06dKMGjWKcuXK2T1u9+7dmTVrlm35l19+ISoqirZt2z72eXbr1o3Zs2djsVhYsmQJJUqUSHQyhgEDBtCgQQP8/f1p2LAho0aNYtGiRQC4uLjg7e2NyWTC19cXX19fPD09OXr0KIsWLWLmzJm0atWK4sWL06hRI9q1a2e3708++YR69epRrlw5hgwZwrZt2+x61R6UO3dupk2bRpkyZXjppZdo2rSp7Tyow4cPs3btWr755hueeeYZqlSpwrfffsvdu3cf+1qIiIiISPpSj9NjuDs78s/IYMMe+0ns2rULs9lMx44diY6OtruvWrVqdsv79+9n69attmF7APHx8URFRXHnzh32799PREQEefPmtdvu7t27nDhxAoBDhw7Rs2dPu/tr1qzJhg0bbMtdunThww8/ZMeOHdSoUYPZs2fTtm3bJJ2n1LRpU9588002bdrEzJkz6datW6LrrV27ljFjxnD48GHCw8OJi4uzPQ8PD49Et9m3bx+Ojo7U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SEIE/6amtWvX4sUXX0RZWRlSUlLw+uuvY/To0R77b926Fc888wzOnTuHpKQkrF69GlOmTPHrvSorKxEZGYmrV6/CbDYH6hSIiIiIiKidaUw20LXSmDx6++238cQTT2DlypU4cuQIUlJSMHHiRFRUVGj2//zzzzFnzhzcf//9OHr0KDIzM5GZmYmTJ0+28siJiIiIiOhGEfQrTmPGjMGoUaPw5z//GQAgyzJ69eqF3/72t1i6dKlb/1mzZqGmpgY7duxQ2m699VYMHToU69evd+tfV1eHuro65XVlZSV69erFK05ERERERDe4dnPFyWKxoKCgAOnp6UqbTqdDeno68vLyNPfJy8tT9QeAiRMneuy/atUqREZGKo9evXoF7gSIiIiIiOiGENTgdPHiRdjtdsTGxqraY2NjUVZWprlPWVlZo/ovW7YMV69eVR7nz58PzOCJiIiIiOiG0eG/Vc9kMsFkMgV7GERERERE1I4F9YpTdHQ09Ho9ysvLVe3l5eWIi4vT3CcuLq5R/YmIiIiIiJorqMHJaDRixIgR2LNnj9ImyzL27NmD1NRUzX1SU1NV/QFg9+7dHvsTERERERE1V9Bv1XviiSeQlZWFkSNHYvTo0fjTn/6EmpoazJs3DwDw61//GjfddBNWrVoFAHjssccwfvx4/PGPf8TUqVOxZcsW5Ofn469//WswT4OIiIiIiDqwoAenWbNm4fvvv8eKFStQVlaGoUOHYteuXcoXQJSUlECna7gwNnbsWPz73//G7373Ozz99NNISkrC9u3bMXjw4GCdAhERERERdXBB/z1Ora0x39VOREREREQdV7v5PU5ERERERETtAYMTERERERGRDwxOREREREREPjA4ERERERER+cDgRERERERE5AODExERERERkQ8MTkRERERERD4wOBEREREREflgCPYAWpvj9/1WVlYGeSRERERERBRMjkzgyAje3HDBqaqqCgDQq1evII+EiIiIiIjagqqqKkRGRnrtIwl/4lUHIssyLly4gIiICEiSFOzhoLKyEr169cL58+dhNpuDPZwOh/VtWaxvy2J9Wxbr27JY35bF+rYs1rdltaX6CiFQVVWFHj16QKfz/lNMN9wVJ51Oh549ewZ7GG7MZnPQJ05Hxvq2LNa3ZbG+LYv1bVmsb8tifVsW69uy2kp9fV1pcuCXQxAREREREfnA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XY2zZ88iPj6+4/z7G+xvp+iIqqqqxNGjR8XRo0cFAPHyyy+Lo0ePim+//VYIIUR2draIiooS77//vjh+/LiYPn26SExMFD/++KNyjEmTJolhw4aJQ4cOif3794ukpCQxZ86cYJ1Sm+KtvlVVVeLJJ58UeXl5ori4WPznP/8Rw4cPF0lJSaK2tlY5Buvr2cMPPywiIyNFTk6OKC0tVR7Xrl1T+jz00EPi5ptvFnv37hX5+fkiNTVVpKamKtttNpsYPHiwyMjIEIWFhWLXrl2ie/fuYtmyZcE4pTbFV33PnDkjfv/734v8/HxRXFws3n//fdG7d28xbtw45Risr2dLly4Vubm5ori4WBw/flwsXbpUSJIkPvnkEyEE525zeasv527guX7DG+dv4DnXmHO4eRYvXixycnJEcXGxOHDggEhPTxfR0dGioqJCCNEx5i+DUwvYt2+fAOD2yMrKEkLUfyX5M888I2JjY4XJZBJpaWmiqKhIdYxLly6JOXPmiPDwcGE2m8W8efNEVVVVEM6m7fFW32vXromMjAzRvXt3ERISIhISEsT8+fNVX20pBOvrjVZtAYiNGzcqfX788UfxyCOPiC5duojOnTuLX/ziF6K0tFR1nHPnzonJkyeL0NBQER0dLRYvXiysVmsrn03b46u+JSUlYty4caJr167CZDKJvn37iiVLloirV6+qjsP6arvvvvtEQkKCMBqNonv37iItLU0JTUJw7jaXt/py7gaea3Di/A085xpzDjfPrFmzRHx8vDAajeKmm24Ss2bNEmfOnFG2d4T5KwkhROtd3yIiIiIiImp/+DNOREREREREPjA4ERERERER+cDgRERERERE5AODExERERERkQ8MTkRERERERD4wOBEREREREfnA4EREREREROQDgxMREREREZEPDE5ERERNdO7cOUiShMLCwoAeNycnB5Ik4cqVKwE9LhERNR2DExERabr33nuRmZnp1s5FffMdO3YMP//5zxETE4NOnTrhlltuwaxZs1BRUQEAGDt2LEpLSxEZGRnkkRIRkQODExERtUsWi6VJ+9ntdsiyHODR+O/7779HWloaunbtio8//hinT5/Gxo0b0aNHD9TU1AAAjEYj4uLiIElS0MZJRERqDE5ERNRkNTU1MJvNePfdd1Xt27dvR1hYGKqqqpTb2bZs2YKxY8eiU6dOGDx4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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def generate_random_hypergraph(n, d, m):\n", + " edges = {f'e{i}': random.sample(range(1, n+1), d) for i in range(m)}\n", + " return Hypergraph(edges)\n", + "\n", + "# Generate random hypergraphs of increasing size\n", + "sizes = [100, 200, 300, 400, 500]\n", + "greedy_times = []\n", + "iterated_times = []\n", + "hedcs_times = []\n", + "\n", + "for size in sizes:\n", + " hypergraph = generate_random_hypergraph(size, 3, size)\n", + " \n", + " start_time = time.time()\n", + " greedy_matching(hypergraph, k)\n", + " greedy_times.append(time.time() - start_time)\n", + " \n", + " start_time = time.time()\n", + " iterated_sampling(hypergraph, s, max_iterations = 500)\n", + " iterated_times.append(time.time() - start_time)\n", + " \n", + " start_time = time.time()\n", + " HEDCS_matching(hypergraph, s)\n", + " hedcs_times.append(time.time() - start_time)\n", + "\n", + "# Plot the results\n", + "plt.figure(figsize=(10, 6))\n", + "plt.plot(sizes, greedy_times, label='Greedy Matching')\n", + "plt.plot(sizes, iterated_times, label='Iterated Sampling')\n", + "plt.plot(sizes, hedcs_times, label='HEDCS Matching')\n", + "plt.xlabel('Hypergraph Size')\n", + "plt.ylabel('Time (seconds)')\n", + "plt.title('Performance Comparison of Hypergraph Matching Algorithms')\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion\n", + "In this tutorial, we demonstrated the implementation and usage of several hypergraph matching algorithms. We also compared their performance on random hypergraphs of increasing size.\n", + "\n", + "For more details, please refer to our publication: [Distributed Algorithms for Matching in Hypergraphs](https://arxiv.org/abs/2009.09605v1)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 0f8659c72ae28b91f558925614c89a677504ac02 Mon Sep 17 00:00:00 2001 From: "Myers, Audun D" Date: Wed, 9 Oct 2024 14:32:37 -0400 Subject: [PATCH 5/7] adding HG matching to __init__ under algorithms --- hypernetx/algorithms/__init__.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hypernetx/algorithms/__init__.py b/hypernetx/algorithms/__init__.py index 78b30c49..3dd7129d 100644 --- a/hypernetx/algorithms/__init__.py +++ b/hypernetx/algorithms/__init__.py @@ -19,6 +19,13 @@ hypergraph_homology_basis, interpret, ) +from hypernetx.algorithms.matching_algorithms import ( + greedy_matching, + maximal_matching, + iterated_sampling, + HEDCS_matching, + approximation_matching_checking, +) from hypernetx.algorithms.s_centrality_measures import ( s_betweenness_centrality, s_harmonic_closeness_centrality, @@ -116,4 +123,10 @@ "two_section", "kumar", "last_step", + # matching_algorithms API's + "greedy_matching", + "maximal_matching", + "iterated_sampling", + "HEDCS_matching", + "approximation_matching_checking", ] From d03ce197094de0acd721d687cd34b0de2a5c8326 Mon Sep 17 00:00:00 2001 From: "ryan.danehy@pnnl.gov" Date: Tue, 22 Oct 2024 15:37:09 -0700 Subject: [PATCH 6/7] Fix pre-commit failure --- hypernetx/algorithms/matching_algorithms.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hypernetx/algorithms/matching_algorithms.py b/hypernetx/algorithms/matching_algorithms.py index bf80b978..ef13e8df 100644 --- a/hypernetx/algorithms/matching_algorithms.py +++ b/hypernetx/algorithms/matching_algorithms.py @@ -13,6 +13,7 @@ import random from concurrent.futures import ThreadPoolExecutor + def approximation_matching_checking(optimal: list, approx: list) -> bool: """ Checks if the approximate list contains at least one element that is a subset of each element in the optimal list. @@ -494,8 +495,8 @@ def HEDCS_matching(hypergraph: Hypergraph, s: int) -> list: """ HEDCS-Matching for Approximate Hypergraph Matching. - This algorithm constructs Hyper-Edge Degree Constrained Subgraphs (HEDCS) - to find an approximate maximal matching in a d-uniform hypergraph. It leverages + This algorithm constructs Hyper-Edge Degree Constrained Subgraphs (HEDCS) + to find an approximate maximal matching in a d-uniform hypergraph. It leverages parallelization to efficiently handle larger hypergraphs. Parameters From 27ffc4fe104498b05a3e309492419e5542fe2750 Mon Sep 17 00:00:00 2001 From: "ryan.danehy@pnnl.gov" Date: Tue, 22 Oct 2024 15:46:57 -0700 Subject: [PATCH 7/7] =?UTF-8?q?bump:=20version=202.3.7=20=E2=86=92=202.3.8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cz.toml | 2 +- docs/source/conf.py | 2 +- hypernetx/__init__.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.cz.toml b/.cz.toml index ee9e1967..45c84afd 100644 --- a/.cz.toml +++ b/.cz.toml @@ -1,6 +1,6 @@ [tool.commitizen] name = "cz_conventional_commits" -version = "2.3.7" +version = "2.3.8" version_provider = "poetry" version_files = [ "pyproject.toml", diff --git a/docs/source/conf.py b/docs/source/conf.py index fa5f7849..52050268 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ import os -__version__ = "2.3.7" +__version__ = "2.3.8" # If extensions (or modules to document with autodoc) are in another directory, diff --git a/hypernetx/__init__.py b/hypernetx/__init__.py index 3acc7796..d198b9f7 100644 --- a/hypernetx/__init__.py +++ b/hypernetx/__init__.py @@ -11,4 +11,4 @@ from hypernetx.utils import * from hypernetx.utils.toys import * -__version__ = "2.3.7" +__version__ = "2.3.8" diff --git a/pyproject.toml b/pyproject.toml index e50760f4..38627341 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "hypernetx" -version = "2.3.7" +version = "2.3.8" description = "HyperNetX is a Python library for the creation and study of hypergraphs." authors = ["Brenda Praggastis ", "Dustin Arendt ", "Sinan Aksoy ", "Emilie Purvine ",

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%0AnDDs#2b$x0- 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