Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add max weight matching function #229

Merged
merged 44 commits into from
Feb 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
98fa26e
Add max weight matching function
mtreinish Jan 15, 2021
850c533
Fix most of the test panics
mtreinish Jan 17, 2021
4f54cdc
Fix panic in one test
mtreinish Jan 18, 2021
b25f9bf
Remove unused verify_optimum() function
mtreinish Jan 18, 2021
ecf1f09
Remove unnecessary BlossomList struct and just use Vec<Vec<usize>>
mtreinish Jan 18, 2021
85b96e1
Fix tests
mtreinish Jan 18, 2021
48f3192
Fix docs build
mtreinish Jan 18, 2021
b7ee890
Fix typos in code comments
mtreinish Jan 20, 2021
134f6db
Fix handling of holes in node indices and add test
mtreinish Jan 20, 2021
83776c7
Merge branch 'master' into max_weight_matching
mtreinish Jan 21, 2021
91c7f87
Merge branch 'master' into max_weight_matching
mtreinish Jan 21, 2021
9bbffa9
Merge branch 'master' into max_weight_matching
mtreinish Jan 21, 2021
7a72299
Merge branch 'master' into max_weight_matching
mtreinish Jan 23, 2021
308c82a
Add test to compare output with random graph to networkx
mtreinish Jan 25, 2021
6239be7
Use tox for non-x86 travis ci jobs
mtreinish Jan 25, 2021
4d48492
Add networkx to coverage job
mtreinish Jan 25, 2021
d68e2d1
Update src/max_weight_matching.rs
mtreinish Jan 26, 2021
81a59a4
Also reset label_ends on each stage iteration
mtreinish Jan 26, 2021
967ed58
Merge branch 'master' into max_weight_matching
mtreinish Jan 27, 2021
72ab8f0
Merge branch 'master' into max_weight_matching
mtreinish Jan 27, 2021
aeeec76
Update src/max_weight_matching.rs
mtreinish Jan 29, 2021
87654ca
Merge branch 'master' into max_weight_matching
mtreinish Jan 29, 2021
37b518d
Add more details to dual_var comment
mtreinish Jan 29, 2021
0c6ea26
Add more random graph test cases
mtreinish Jan 29, 2021
fb16064
Change output format to a set of tuples
mtreinish Jan 29, 2021
59bbda2
Clean up from review comments
mtreinish Jan 29, 2021
6e27785
Merge branch 'master' into max_weight_matching
mtreinish Feb 8, 2021
71bc037
Add back verify_optimum() function and make it an optional flag
mtreinish Feb 9, 2021
d469f52
Fix test lint
mtreinish Feb 9, 2021
4725f59
Merge branch 'master' into max_weight_matching
mtreinish Feb 9, 2021
cfd9121
Fallback to checking valid matching and optimum result
mtreinish Feb 9, 2021
ce65f27
Merge branch 'max_weight_matching' of github.com:mtreinish/retworkx i…
mtreinish Feb 10, 2021
c4ca1a8
Fix test lint
mtreinish Feb 10, 2021
18c13f0
Merge branch 'master' into max_weight_matching
mtreinish Feb 21, 2021
dc5d215
Use HashMap for mate instead of Vec
mtreinish Feb 21, 2021
71780e1
Switch best_edge_to to HashMap
mtreinish Feb 21, 2021
a2fdbb4
Merge branch 'master' into max_weight_matching
mtreinish Feb 22, 2021
1b59c97
Add test with weights
mtreinish Feb 22, 2021
6dc8ea5
Fix nx miss check
mtreinish Feb 22, 2021
2a7989b
Add max cardinality random weight test
mtreinish Feb 22, 2021
a117f75
Add random test cases with negative weights too
mtreinish Feb 22, 2021
0418c50
Use subtest for each iteration of random loop
mtreinish Feb 22, 2021
973267e
Add missing tox install to travis config
mtreinish Feb 22, 2021
8570e9a
Merge branch 'master' into max_weight_matching
mtreinish Feb 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
- name: Download grcov
run: curl -L https://github.com/mozilla/grcov/releases/download/v0.6.1/grcov-linux-x86_64.tar.bz2 | tar jxf -
- name: Install deps
run: pip install -U setuptools-rust
run: pip install -U setuptools-rust networkx
- name: Build retworkx
run: python setup.py develop
env:
Expand Down
9 changes: 3 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@ before_install:
- sh tools/install_rust.sh
- export PATH=~/.cargo/bin:$PATH
- which python
- pip install -U pip virtualenv
install:
- virtualenv test-venv
- test-venv/bin/pip install -U .
- pip install -U pip virtualenv tox
script:
- cd tests && ../test-venv/bin/python -m unittest discover .
- tox -epy
stages:
- name: Linux non-x86_64
if: tag IS blank
Expand All @@ -42,7 +39,7 @@ jobs:
- sh tools/install_rust.sh
- export PATH=~/.cargo/bin:$PATH
- which python
- pip install -U pip virtualenv
- pip install -U pip virtualenv tox
- rustup default 1.49.0
- name: Python 3.7 Tests arm64 Linux
stage: Linux non-x86_64
Expand Down
109 changes: 82 additions & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Specific Graph Type Methods
retworkx.digraph_dfs_edges
retworkx.digraph_find_cycle
retworkx.digraph_union
retworkx.max_weight_matching

Universal Functions
'''''''''''''''''''
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
features:
- |
Add a new function, :func:`~retworkx.max_weight_matching` for computing the
maximum-weighted matching for a :class:`~retworkx.PyGraph` object.
66 changes: 66 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod generators;
mod graph;
mod iterators;
mod k_shortest_path;
mod max_weight_matching;
mod union;

use std::cmp::{Ordering, Reverse};
Expand Down Expand Up @@ -2492,6 +2493,70 @@ pub fn cycle_basis(
cycles
}

/// Compute a maximum-weighted matching for a :class:`~retworkx.PyGraph`
///
/// A matching is a subset of edges in which no node occurs more than once.
/// The weight of a matching is the sum of the weights of its edges.
/// A maximal matching cannot add more edges and still be a matching.
/// The cardinality of a matching is the number of matched edges.
///
/// This function takes time :math:`O(n^3)` where ``n`` is the number of nodes
/// in the graph.
///
/// This method is based on the "blossom" method for finding augmenting
/// paths and the "primal-dual" method for finding a matching of maximum
/// weight, both methods invented by Jack Edmonds [1]_.
///
/// :param PyGraph graph: The undirected graph to compute the max weight
/// matching for. Expects to have no parallel edges (multigraphs are
/// untested currently).
/// :param bool max_cardinality: If True, compute the maximum-cardinality
/// matching with maximum weight among all maximum-cardinality matchings.
/// Defaults False.
/// :param callable weight_fn: An optional callable that will be passed a
/// single argument the edge object for each edge in the graph. It is
/// expected to return an ``int`` weight for that edge. For example,
/// if the weights are all integers you can use: ``lambda x: x``. If not
/// specified the value for ``default_weight`` will be used for all
/// edge weights.
/// :param int default_weight: The ``int`` value to use for all edge weights
/// in the graph if ``weight_fn`` is not specified. Defaults to ``1``.
/// :param bool verify_optimum: A boolean flag to run a check that the found
/// solution is optimum. If set to true an exception will be raised if
/// the found solution is not optimum. This is mostly useful for testing.
///
/// :returns: A set of tuples ofthe matching, Note that only a single
/// direction will be listed in the output, for example:
/// ``{(0, 1),}``.
/// :rtype: set
///
/// .. [1] "Efficient Algorithms for Finding Maximum Matching in Graphs",
/// Zvi Galil, ACM Computing Surveys, 1986.
///
#[pyfunction(
max_cardinality = "false",
default_weight = 1,
verify_optimum = "false"
)]
#[text_signature = "(graph, /, max_cardinality=False, weight_fn=None, default_weight=1, verify_optimum=False)"]
pub fn max_weight_matching(
py: Python,
graph: &graph::PyGraph,
max_cardinality: bool,
weight_fn: Option<PyObject>,
default_weight: i128,
verify_optimum: bool,
) -> PyResult<HashSet<(usize, usize)>> {
max_weight_matching::max_weight_matching(
py,
graph,
max_cardinality,
weight_fn,
default_weight,
verify_optimum,
)
}

/// Compute the strongly connected components for a directed graph
///
/// This function is implemented using Kosaraju's algorithm
Expand Down Expand Up @@ -2661,6 +2726,7 @@ fn retworkx(py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(digraph_find_cycle))?;
m.add_wrapped(wrap_pyfunction!(digraph_k_shortest_path_lengths))?;
m.add_wrapped(wrap_pyfunction!(graph_k_shortest_path_lengths))?;
m.add_wrapped(wrap_pyfunction!(max_weight_matching))?;
m.add_class::<digraph::PyDiGraph>()?;
m.add_class::<graph::PyGraph>()?;
m.add_class::<iterators::BFSSuccessors>()?;
Expand Down
Loading