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.
self.base_vertex: int = base_vertex
# A top-level blossom that are part of an alternating tree,
# has labels S or T. Unlabeled top-level blossoms are not (yet)
# part of any alternating tree.
# A top-level blossom that is part of an alternating tree,
# has label S or T. An unlabeled top-level blossom is not part
# of any alternating tree.
self.label: int = _LABEL_NONE
# Labeled top-level blossoms keep track of the edge through which
# they are attached to an alternating tree.
# A labeled top-level blossoms keeps track of the edge through which
# it is attached to the alternating tree.
#
# "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.
@ -401,7 +401,8 @@ class _Blossom:
# queue.
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
# "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
# 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)
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
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".
"""
self.vertex_sedge_queue[x].clear()
@ -861,7 +862,14 @@ class _MatchingContext:
#
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.label == _LABEL_NONE
@ -911,7 +919,10 @@ class _MatchingContext:
self.scan_queue.extend(vertices)
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.label == _LABEL_NONE
@ -1005,7 +1016,10 @@ class _MatchingContext:
self.delta2_remove_edge(e, y, by)
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.label == _LABEL_T
@ -1028,7 +1042,10 @@ class _MatchingContext:
self.delta2_enable_blossom(blossom)
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.label == _LABEL_S
@ -1180,7 +1197,7 @@ class _MatchingContext:
Assign label S to the new blossom.
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.
@ -1273,7 +1290,7 @@ class _MatchingContext:
def expand_unlabeled_blossom(self, blossom: _NonTrivialBlossom) -> None:
"""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
@ -1305,7 +1322,7 @@ class _MatchingContext:
def expand_t_blossom(self, blossom: _NonTrivialBlossom) -> None:
"""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
@ -1713,8 +1730,9 @@ class _MatchingContext:
where "k" is the number of intra-blossom edges removed from
the delta3 queue.
Since each edge can be inserted into the delta3 queue at most
once per stage, this function takes total time O((n + m) * log(n))
At most O(n) delta steps can occur during a stage.
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.
Returns:
@ -1770,7 +1788,7 @@ class _MatchingContext:
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.
"""
for x in range(self.graph.num_vertex):
@ -1857,7 +1875,7 @@ class _MatchingContext:
Also applies delayed updates to dual variables.
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.
"""