Use FIFO queue for S-vertices
This commit is contained in:
parent
caac6825a6
commit
0e79e1d2f6
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
|
import collections
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from typing import NamedTuple, Optional
|
from typing import NamedTuple, Optional
|
||||||
|
|
||||||
|
@ -545,9 +546,8 @@ class _MatchingContext:
|
||||||
# between "x" and any S-vertex, or -1 if no such edge has been found.
|
# between "x" and any S-vertex, or -1 if no such edge has been found.
|
||||||
self.vertex_best_edge: list[int] = num_vertex * [-1]
|
self.vertex_best_edge: list[int] = num_vertex * [-1]
|
||||||
|
|
||||||
# "queue" is a list of S-vertices that must be scanned.
|
# Queue of S-vertices to be scanned.
|
||||||
# We call it a queue, but it is actually a stack.
|
self.queue: collections.deque[int] = collections.deque()
|
||||||
self.queue: list[int] = []
|
|
||||||
|
|
||||||
def edge_slack_2x(self, e: int) -> int|float:
|
def edge_slack_2x(self, e: int) -> int|float:
|
||||||
"""Return 2 times the slack of the edge with index "e".
|
"""Return 2 times the slack of the edge with index "e".
|
||||||
|
@ -1361,7 +1361,7 @@ class _MatchingContext:
|
||||||
while self.queue:
|
while self.queue:
|
||||||
|
|
||||||
# Take a vertex from the queue.
|
# Take a vertex from the queue.
|
||||||
x = self.queue.pop()
|
x = self.queue.popleft()
|
||||||
|
|
||||||
# Double-check that "x" is an S-vertex.
|
# Double-check that "x" is an S-vertex.
|
||||||
bx = self.vertex_top_blossom[x]
|
bx = self.vertex_top_blossom[x]
|
||||||
|
|
|
@ -194,22 +194,22 @@ class TestMaximumWeightMatching(unittest.TestCase):
|
||||||
def test46_expand_unlabeled_blossom(self):
|
def test46_expand_unlabeled_blossom(self):
|
||||||
"""expand blossom before assigning label T"""
|
"""expand blossom before assigning label T"""
|
||||||
#
|
#
|
||||||
# 5--[2]--3--[4]
|
# 3--[1]
|
||||||
# / |
|
# / |
|
||||||
# [0]--5--[1] 5
|
# [2]--1--[4] 7
|
||||||
# \ |
|
# \ |
|
||||||
# 5--[3]--3--[5]
|
# 5--[3]--5--[5]
|
||||||
#
|
#
|
||||||
self.assertEqual(
|
self.assertIn(
|
||||||
mwm([(0,1,5), (1,2,5), (1,3,5), (2,3,5), (2,4,3), (3,5,3)]),
|
mwm([(1,3,7), (1,4,3), (2,4,1), (3,4,5), (3,5,5)]),
|
||||||
[(0,1), (2,4), (3,5)])
|
([(1,3), (2,4)], [(1,4), (3,5)]))
|
||||||
|
|
||||||
def test47_expand_unlabeled_outer(self):
|
def test47_expand_unlabeled_outer(self):
|
||||||
"""expand outer blossom before assigning label T"""
|
"""expand outer blossom before assigning label T"""
|
||||||
#
|
#
|
||||||
# [3]--10--[1]--15--[2]--12--[5]
|
# [3]--10--[1]--15--[2]--12--[5]
|
||||||
# _/ \_ | |
|
# _/ \_ | |
|
||||||
# 11 16_ 8 15
|
# 11 16_ 8 15
|
||||||
# / \ | |
|
# / \ | |
|
||||||
# [4] [6]---7--[7]
|
# [4] [6]---7--[7]
|
||||||
#
|
#
|
||||||
|
@ -217,6 +217,19 @@ class TestMaximumWeightMatching(unittest.TestCase):
|
||||||
mwm([(1,2,15), (1,3,10), (1,4,11), (1,6,17), (2,5,12), (2,6,8), (5,7,15), (6,7,7)]),
|
mwm([(1,2,15), (1,3,10), (1,4,11), (1,6,17), (2,5,12), (2,6,8), (5,7,15), (6,7,7)]),
|
||||||
[(1,4), (2,6), (5,7)])
|
[(1,4), (2,6), (5,7)])
|
||||||
|
|
||||||
|
def test48_expand_unlabeled_nested(self):
|
||||||
|
"""expand nested blossom before assigning label T"""
|
||||||
|
#
|
||||||
|
# [5]--11--[1]--11 14--[3]
|
||||||
|
# | \ / |
|
||||||
|
# 12 [4] 14
|
||||||
|
# | / \ |
|
||||||
|
# [6]--11--[2]--12 11--[7]
|
||||||
|
#
|
||||||
|
self.assertEqual(
|
||||||
|
mwm([(1,2,12), (1,4,11), (1,5,11), (2,4,12), (2,6,11), (3,4,14), (3,7,14), (4,7,11)]),
|
||||||
|
[(1,5), (2,4), (3,7)])
|
||||||
|
|
||||||
def test_fail_bad_input(self):
|
def test_fail_bad_input(self):
|
||||||
"""bad input values"""
|
"""bad input values"""
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
@ -315,6 +328,10 @@ class TestCornerCases(unittest.TestCase):
|
||||||
pairs = mwm([(0,2,13), (1,2,11), (2,3,39), (2,4,17), (3,4,35)])
|
pairs = mwm([(0,2,13), (1,2,11), (2,3,39), (2,4,17), (3,4,35)])
|
||||||
self.assertEqual(pairs, [(0,2), (3,4)])
|
self.assertEqual(pairs, [(0,2), (3,4)])
|
||||||
|
|
||||||
|
def test17(self):
|
||||||
|
pairs = mwm([(0,1,48), (0,2,44), (0,4,48), (1,4,36), (3,4,31)])
|
||||||
|
self.assertEqual(pairs, [(0,2), (1,4)])
|
||||||
|
|
||||||
|
|
||||||
class TestAdjustWeightForMaxCardinality(unittest.TestCase):
|
class TestAdjustWeightForMaxCardinality(unittest.TestCase):
|
||||||
"""Test adjust_weights_for_maximum_cardinality_matching() function."""
|
"""Test adjust_weights_for_maximum_cardinality_matching() function."""
|
||||||
|
|
Loading…
Reference in New Issue