1
0
Fork 0

Rename Python module to "mwmatching"

This commit is contained in:
Joris van Rantwijk 2023-02-14 20:49:24 +01:00
parent f0624fa2a5
commit 3f5d61d0e7
4 changed files with 39 additions and 40 deletions

5
python/run_matching.py Normal file → Executable file
View File

@ -12,9 +12,8 @@ import math
import os.path import os.path
from typing import Optional, TextIO from typing import Optional, TextIO
from max_weight_matching import ( from mwmatching import (maximum_weight_matching,
maximum_weight_matching, adjust_weights_for_maximum_cardinality_matching)
adjust_weights_for_maximum_cardinality_matching)
def parse_int_or_float(s: str) -> int|float: def parse_int_or_float(s: str) -> int|float:

View File

@ -4,8 +4,8 @@ import math
import unittest import unittest
from unittest.mock import Mock from unittest.mock import Mock
import max_weight_matching import mwmatching
from max_weight_matching import ( from mwmatching import (
maximum_weight_matching as mwm, maximum_weight_matching as mwm,
adjust_weights_for_maximum_cardinality_matching as adj) adjust_weights_for_maximum_cardinality_matching as adj)
@ -340,7 +340,7 @@ class TestGraphInfo(unittest.TestCase):
"""Test _GraphInfo helper class.""" """Test _GraphInfo helper class."""
def test_empty(self): def test_empty(self):
graph = max_weight_matching._GraphInfo([]) graph = mwmatching._GraphInfo([])
self.assertEqual(graph.num_vertex, 0) self.assertEqual(graph.num_vertex, 0)
self.assertEqual(graph.edges, []) self.assertEqual(graph.edges, [])
self.assertEqual(graph.adjacent_edges, []) self.assertEqual(graph.adjacent_edges, [])
@ -355,8 +355,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate, vertex_mate,
vertex_dual_2x, vertex_dual_2x,
nontrivial_blossom): nontrivial_blossom):
ctx = Mock(spec=max_weight_matching._MatchingContext) ctx = Mock(spec=mwmatching._MatchingContext)
ctx.graph = max_weight_matching._GraphInfo(edges) ctx.graph = mwmatching._GraphInfo(edges)
ctx.vertex_mate = vertex_mate ctx.vertex_mate = vertex_mate
ctx.vertex_dual_2x = vertex_dual_2x ctx.vertex_dual_2x = vertex_dual_2x
ctx.nontrivial_blossom = nontrivial_blossom ctx.nontrivial_blossom = nontrivial_blossom
@ -369,7 +369,7 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[-1, 2, 1], vertex_mate=[-1, 2, 1],
vertex_dual_2x=[0, 20, 2], vertex_dual_2x=[0, 20, 2],
nontrivial_blossom=[]) nontrivial_blossom=[])
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_asymmetric_matching(self): def test_asymmetric_matching(self):
edges = [(0,1,10), (1,2,11)] edges = [(0,1,10), (1,2,11)]
@ -378,8 +378,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[-1, 2, 0], vertex_mate=[-1, 2, 0],
vertex_dual_2x=[0, 20, 2], vertex_dual_2x=[0, 20, 2],
nontrivial_blossom=[]) nontrivial_blossom=[])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_nonexistent_matched_edge(self): def test_nonexistent_matched_edge(self):
edges = [(0,1,10), (1,2,11)] edges = [(0,1,10), (1,2,11)]
@ -388,8 +388,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[2, -1, 0], vertex_mate=[2, -1, 0],
vertex_dual_2x=[11, 11, 11], vertex_dual_2x=[11, 11, 11],
nontrivial_blossom=[]) nontrivial_blossom=[])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_negative_vertex_dual(self): def test_negative_vertex_dual(self):
edges = [(0,1,10), (1,2,11)] edges = [(0,1,10), (1,2,11)]
@ -398,8 +398,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[-1, 2, 1], vertex_mate=[-1, 2, 1],
vertex_dual_2x=[-2, 22, 0], vertex_dual_2x=[-2, 22, 0],
nontrivial_blossom=[]) nontrivial_blossom=[])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_unmatched_nonzero_dual(self): def test_unmatched_nonzero_dual(self):
edges = [(0,1,10), (1,2,11)] edges = [(0,1,10), (1,2,11)]
@ -408,8 +408,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[-1, 2, 1], vertex_mate=[-1, 2, 1],
vertex_dual_2x=[9, 11, 11], vertex_dual_2x=[9, 11, 11],
nontrivial_blossom=[]) nontrivial_blossom=[])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_negative_edge_slack(self): def test_negative_edge_slack(self):
edges = [(0,1,10), (1,2,11)] edges = [(0,1,10), (1,2,11)]
@ -418,8 +418,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[-1, 2, 1], vertex_mate=[-1, 2, 1],
vertex_dual_2x=[0, 11, 11], vertex_dual_2x=[0, 11, 11],
nontrivial_blossom=[]) nontrivial_blossom=[])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_matched_edge_slack(self): def test_matched_edge_slack(self):
edges = [(0,1,10), (1,2,11)] edges = [(0,1,10), (1,2,11)]
@ -428,8 +428,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[-1, 2, 1], vertex_mate=[-1, 2, 1],
vertex_dual_2x=[0, 20, 11], vertex_dual_2x=[0, 20, 11],
nontrivial_blossom=[]) nontrivial_blossom=[])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_negative_blossom_dual(self): def test_negative_blossom_dual(self):
# #
@ -438,11 +438,11 @@ class TestVerificationFail(unittest.TestCase):
# \----8-----/ # \----8-----/
# #
edges = [(0,1,7), (0,2,8), (1,2,9), (2,3,6)] edges = [(0,1,7), (0,2,8), (1,2,9), (2,3,6)]
blossom = max_weight_matching._NonTrivialBlossom( blossom = mwmatching._NonTrivialBlossom(
subblossoms=[ subblossoms=[
max_weight_matching._Blossom(0), mwmatching._Blossom(0),
max_weight_matching._Blossom(1), mwmatching._Blossom(1),
max_weight_matching._Blossom(2)], mwmatching._Blossom(2)],
edges=[0,2,1]) edges=[0,2,1])
for sub in blossom.subblossoms: for sub in blossom.subblossoms:
sub.parent = blossom sub.parent = blossom
@ -452,8 +452,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[1, 0, 3, 2], vertex_mate=[1, 0, 3, 2],
vertex_dual_2x=[4, 6, 8, 4], vertex_dual_2x=[4, 6, 8, 4],
nontrivial_blossom=[blossom]) nontrivial_blossom=[blossom])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
def test_blossom_not_full(self): def test_blossom_not_full(self):
# #
@ -466,11 +466,11 @@ class TestVerificationFail(unittest.TestCase):
# \----2-----/ # \----2-----/
# #
edges = [(0,1,7), (0,2,2), (1,2,5), (0,3,8), (1,4,8)] edges = [(0,1,7), (0,2,2), (1,2,5), (0,3,8), (1,4,8)]
blossom = max_weight_matching._NonTrivialBlossom( blossom = mwmatching._NonTrivialBlossom(
subblossoms=[ subblossoms=[
max_weight_matching._Blossom(0), mwmatching._Blossom(0),
max_weight_matching._Blossom(1), mwmatching._Blossom(1),
max_weight_matching._Blossom(2)], mwmatching._Blossom(2)],
edges=[0,2,1]) edges=[0,2,1])
for sub in blossom.subblossoms: for sub in blossom.subblossoms:
sub.parent = blossom sub.parent = blossom
@ -480,8 +480,8 @@ class TestVerificationFail(unittest.TestCase):
vertex_mate=[3, 4, -1, 0, 1], vertex_mate=[3, 4, -1, 0, 1],
vertex_dual_2x=[4, 10, 0, 12, 6], vertex_dual_2x=[4, 10, 0, 12, 6],
nontrivial_blossom=[blossom]) nontrivial_blossom=[blossom])
with self.assertRaises(max_weight_matching.MatchingError): with self.assertRaises(mwmatching.MatchingError):
max_weight_matching._verify_optimum(ctx) mwmatching._verify_optimum(ctx)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -20,11 +20,11 @@ count_delta_step = [0]
def patch_matching_code() -> None: def patch_matching_code() -> None:
"""Patch the matching code to count events.""" """Patch the matching code to count events."""
import max_weight_matching import mwmatching
orig_make_blossom = max_weight_matching._MatchingContext.make_blossom orig_make_blossom = mwmatching._MatchingContext.make_blossom
orig_substage_calc_dual_delta = ( orig_substage_calc_dual_delta = (
max_weight_matching._MatchingContext.substage_calc_dual_delta) mwmatching._MatchingContext.substage_calc_dual_delta)
def stub_make_blossom(*args, **kwargs): def stub_make_blossom(*args, **kwargs):
count_make_blossom[0] += 1 count_make_blossom[0] += 1
@ -36,8 +36,8 @@ def patch_matching_code() -> None:
# print("DELTA", ret) # print("DELTA", ret)
return ret return ret
max_weight_matching._MatchingContext.make_blossom = stub_make_blossom mwmatching._MatchingContext.make_blossom = stub_make_blossom
max_weight_matching._MatchingContext.substage_calc_dual_delta = ( mwmatching._MatchingContext.substage_calc_dual_delta = (
stub_substage_calc_dual_delta) stub_substage_calc_dual_delta)
@ -45,12 +45,12 @@ def run_max_weight_matching(
edges: list[tuple[int, int, int]] edges: list[tuple[int, int, int]]
) -> tuple[list[tuple[int, int]], int, int]: ) -> tuple[list[tuple[int, int]], int, int]:
"""Run the matching algorithm and count subroutine calls.""" """Run the matching algorithm and count subroutine calls."""
import max_weight_matching import mwmatching
count_make_blossom[0] = 0 count_make_blossom[0] = 0
count_delta_step[0] = 0 count_delta_step[0] = 0
pairs = max_weight_matching.maximum_weight_matching(edges) pairs = mwmatching.maximum_weight_matching(edges)
return (pairs, count_make_blossom[0], count_delta_step[0]) return (pairs, count_make_blossom[0], count_delta_step[0])