1
0
Fork 0

Improve comments and docstrings

This commit is contained in:
Joris van Rantwijk 2024-06-30 21:38:12 +02:00
parent 0e76e6472b
commit 4c6115fb2f
1 changed files with 37 additions and 19 deletions

View File

@ -371,13 +371,13 @@ class _Blossom:
# vertex in the blossom. # vertex in the blossom.
self.base_vertex: int = base_vertex self.base_vertex: int = base_vertex
# A top-level blossom that are part of an alternating tree, # A top-level blossom that is part of an alternating tree,
# has labels S or T. Unlabeled top-level blossoms are not (yet) # has label S or T. An unlabeled top-level blossom is not part
# part of any alternating tree. # of any alternating tree.
self.label: int = _LABEL_NONE self.label: int = _LABEL_NONE
# Labeled top-level blossoms keep track of the edge through which # A labeled top-level blossoms keeps track of the edge through which
# they are attached to an alternating tree. # it is attached to the alternating tree.
# #
# "tree_edge = (x, y)" if the blossom is attached to an alternating # "tree_edge = (x, y)" if the blossom is attached to an alternating
# tree via edge "(x, y)" and vertex "y" is contained in the blossom. # tree via edge "(x, y)" and vertex "y" is contained in the blossom.
@ -401,7 +401,8 @@ class _Blossom:
# queue. # queue.
self.delta2_node: Optional[PriorityQueue.Node] = None self.delta2_node: Optional[PriorityQueue.Node] = None
# Support variable for lazy updating of vertex dual variables. # This variable holds pending lazy updates to the dual variables
# of the vertices inside the blossom.
self.vertex_dual_offset: float = 0 self.vertex_dual_offset: float = 0
# "marker" is a temporary variable used to discover common # "marker" is a temporary variable used to discover common
@ -556,7 +557,7 @@ class _MatchingContext:
# "vertex_set_node[x]" represents the vertex "x" inside the # "vertex_set_node[x]" represents the vertex "x" inside the
# union-find datastructure of its top-level blossom. # union-find datastructure of its top-level blossom.
# #
# Initially, each vertex belongs to its owwn trivial top-level blossom. # Initially, each vertex belongs to its own trivial top-level blossom.
self.vertex_set_node = [b.vertex_set.insert(i, math.inf) self.vertex_set_node = [b.vertex_set.insert(i, math.inf)
for (i, b) in enumerate(self.trivial_blossom)] for (i, b) in enumerate(self.trivial_blossom)]
@ -754,7 +755,7 @@ class _MatchingContext:
It is assumed that the blossom containing "x" has already been It is assumed that the blossom containing "x" has already been
disabled for delta2 tracking. disabled for delta2 tracking.
This function takes time O(k * log(n)), This function takes time O(k + log(n)),
where "k" is the number of edges incident on "x". where "k" is the number of edges incident on "x".
""" """
self.vertex_sedge_queue[x].clear() self.vertex_sedge_queue[x].clear()
@ -861,7 +862,14 @@ class _MatchingContext:
# #
def assign_blossom_label_s(self, blossom: _Blossom) -> None: def assign_blossom_label_s(self, blossom: _Blossom) -> None:
"""Change an unlabeled top-level blossom into an S-blossom.""" """Change an unlabeled top-level blossom into an S-blossom.
For a blossom with "j" vertices and "k" incident edges,
this function takes time O(j * log(n) + k).
This function is called at most once per blossom per stage.
It therefore takes total time O(n * log(n) + m) per stage.
"""
assert blossom.parent is None assert blossom.parent is None
assert blossom.label == _LABEL_NONE assert blossom.label == _LABEL_NONE
@ -911,7 +919,10 @@ class _MatchingContext:
self.scan_queue.extend(vertices) self.scan_queue.extend(vertices)
def assign_blossom_label_t(self, blossom: _Blossom) -> None: def assign_blossom_label_t(self, blossom: _Blossom) -> None:
"""Change an unlabeled top-level blossom into a T-blossom.""" """Change an unlabeled top-level blossom into a T-blossom.
This function takes time O(log(n)).
"""
assert blossom.parent is None assert blossom.parent is None
assert blossom.label == _LABEL_NONE assert blossom.label == _LABEL_NONE
@ -1005,7 +1016,10 @@ class _MatchingContext:
self.delta2_remove_edge(e, y, by) self.delta2_remove_edge(e, y, by)
def remove_blossom_label_t(self, blossom: _Blossom) -> None: def remove_blossom_label_t(self, blossom: _Blossom) -> None:
"""Change a top-level T-blossom into an unlabeled blossom.""" """Change a top-level T-blossom into an unlabeled blossom.
This function takes time O(log(n)).
"""
assert blossom.parent is None assert blossom.parent is None
assert blossom.label == _LABEL_T assert blossom.label == _LABEL_T
@ -1028,7 +1042,10 @@ class _MatchingContext:
self.delta2_enable_blossom(blossom) self.delta2_enable_blossom(blossom)
def change_s_blossom_to_subblossom(self, blossom: _Blossom) -> None: def change_s_blossom_to_subblossom(self, blossom: _Blossom) -> None:
"""Change a top-level S-blossom into an S-subblossom.""" """Change a top-level S-blossom into an S-subblossom.
This function takes time O(1).
"""
assert blossom.parent is None assert blossom.parent is None
assert blossom.label == _LABEL_S assert blossom.label == _LABEL_S
@ -1180,7 +1197,7 @@ class _MatchingContext:
Assign label S to the new blossom. Assign label S to the new blossom.
Relabel all T-sub-blossoms as S and add their vertices to the queue. Relabel all T-sub-blossoms as S and add their vertices to the queue.
This function takes total time O(n * log(n)) per stage. This function takes total time O((n + m) * log(n)) per stage.
""" """
# Check that the path is odd-length. # Check that the path is odd-length.
@ -1273,7 +1290,7 @@ class _MatchingContext:
def expand_unlabeled_blossom(self, blossom: _NonTrivialBlossom) -> None: def expand_unlabeled_blossom(self, blossom: _NonTrivialBlossom) -> None:
"""Expand the specified unlabeled blossom. """Expand the specified unlabeled blossom.
This function takes total time O(n*log(n)) per stage. This function takes total time O(n * log(n)) per stage.
""" """
assert blossom.parent is None assert blossom.parent is None
@ -1305,7 +1322,7 @@ class _MatchingContext:
def expand_t_blossom(self, blossom: _NonTrivialBlossom) -> None: def expand_t_blossom(self, blossom: _NonTrivialBlossom) -> None:
"""Expand the specified T-blossom. """Expand the specified T-blossom.
This function takes total time O(n*log(n)) per stage. This function takes total time O(n * log(n) + m) per stage.
""" """
assert blossom.parent is None assert blossom.parent is None
@ -1713,8 +1730,9 @@ class _MatchingContext:
where "k" is the number of intra-blossom edges removed from where "k" is the number of intra-blossom edges removed from
the delta3 queue. the delta3 queue.
Since each edge can be inserted into the delta3 queue at most At most O(n) delta steps can occur during a stage.
once per stage, this function takes total time O((n + m) * log(n)) Each edge can be inserted into the delta3 queue at most once per stage.
Therefore, this function takes total time O((n + m) * log(n))
per stage. per stage.
Returns: Returns:
@ -1770,7 +1788,7 @@ class _MatchingContext:
Assign label S to all vertices and add them to the scan queue. Assign label S to all vertices and add them to the scan queue.
This function takes time O(n). This function takes time O(n + m).
It is called once, at the beginning of the algorithm. It is called once, at the beginning of the algorithm.
""" """
for x in range(self.graph.num_vertex): for x in range(self.graph.num_vertex):
@ -1857,7 +1875,7 @@ class _MatchingContext:
Also applies delayed updates to dual variables. Also applies delayed updates to dual variables.
Also resets tracking of least-slack edges. Also resets tracking of least-slack edges.
This function takes time O(n * log(n)). This function takes time O((n + m) * log(n)).
It is called once, at the end of the algorithm. It is called once, at the end of the algorithm.
""" """