1
0
Fork 0

Optimize deletion of expanded blossoms

This commit is contained in:
Joris van Rantwijk 2023-02-10 13:24:36 +01:00
parent 6d46a9d89a
commit 4203b1e5cc
1 changed files with 23 additions and 5 deletions

View File

@ -379,6 +379,7 @@ class _Blossom:
# "marker" is a temporary variable used to discover common
# ancestors in the blossom tree. It is normally False, except
# when used by "trace_alternating_paths()".
# It is also used by "expand_zero_dual_blossoms()".
self.marker: bool = False
def vertices(self) -> list[int]:
@ -927,7 +928,6 @@ class _MatchingContext:
blossom = _NonTrivialBlossom(subblossoms, path.edges)
# Insert into the blossom array.
# TODO : rework this
self.nontrivial_blossom.append(blossom)
# Link the subblossoms to the their new parent.
@ -1065,7 +1065,6 @@ class _MatchingContext:
sub.tree_edge = path_edges[p+1]
# Delete the expanded blossom.
# TODO : avoid O(n) here if possible
self.nontrivial_blossom.remove(blossom)
def expand_blossom_rec(
@ -1102,9 +1101,8 @@ class _MatchingContext:
# Trivial sub-blossom. Mark it as top-level vertex.
self.vertex_top_blossom[sub.base_vertex] = sub
# Delete the expanded blossom.
# TODO : avoid O(n) here if possible
self.nontrivial_blossom.remove(blossom)
# Deletion of the expanded blossom will be handled in
# the function "expand_zero_dual_blossoms()".
def expand_zero_dual_blossoms(self) -> None:
"""Expand all blossoms with zero dual variable (recursively).
@ -1129,11 +1127,31 @@ class _MatchingContext:
if blossom.dual_var == 0:
stack.append(blossom)
# Skip the rest of this function if there are no blossoms to delete.
if not stack:
return
# Expand blossoms.
while stack:
blossom = stack.pop()
self.expand_blossom_rec(blossom, stack)
# Mark the blossom for deletion.
blossom.marker = True
# Delete the expanded blossoms.
# We do this in one pass over the array to ensure O(n) time.
p = 0
for (i, blossom) in enumerate(self.nontrivial_blossom):
if not blossom.marker:
# Keep this blossom.
if i > p:
self.nontrivial_blossom[p] = blossom
p += 1
# Trim the array.
del self.nontrivial_blossom[p:]
#
# Augmenting:
#