Clean up redundant type annotations "int|float"
This commit is contained in:
parent
c8a3f7f684
commit
91d4afb271
|
@ -12,7 +12,7 @@ from typing import NamedTuple, Optional
|
||||||
|
|
||||||
|
|
||||||
def maximum_weight_matching(
|
def maximum_weight_matching(
|
||||||
edges: Sequence[tuple[int, int, int|float]]
|
edges: Sequence[tuple[int, int, float]]
|
||||||
) -> list[tuple[int, int]]:
|
) -> list[tuple[int, int]]:
|
||||||
"""Compute a maximum-weighted matching in the general undirected weighted
|
"""Compute a maximum-weighted matching in the general undirected weighted
|
||||||
graph given by "edges".
|
graph given by "edges".
|
||||||
|
@ -93,8 +93,8 @@ def maximum_weight_matching(
|
||||||
|
|
||||||
|
|
||||||
def adjust_weights_for_maximum_cardinality_matching(
|
def adjust_weights_for_maximum_cardinality_matching(
|
||||||
edges: Sequence[tuple[int, int, int|float]]
|
edges: Sequence[tuple[int, int, float]]
|
||||||
) -> Sequence[tuple[int, int, int|float]]:
|
) -> Sequence[tuple[int, int, float]]:
|
||||||
"""Adjust edge weights such that the maximum-weight matching of
|
"""Adjust edge weights such that the maximum-weight matching of
|
||||||
the adjusted graph is a maximum-cardinality matching, equal to
|
the adjusted graph is a maximum-cardinality matching, equal to
|
||||||
a matching in the original graph that has maximum weight out of all
|
a matching in the original graph that has maximum weight out of all
|
||||||
|
@ -157,7 +157,7 @@ def adjust_weights_for_maximum_cardinality_matching(
|
||||||
if min_weight > 0 and min_weight >= num_vertex * weight_range:
|
if min_weight > 0 and min_weight >= num_vertex * weight_range:
|
||||||
return edges
|
return edges
|
||||||
|
|
||||||
delta: int|float
|
delta: float
|
||||||
if weight_range > 0:
|
if weight_range > 0:
|
||||||
# Increase weights to make minimum edge weight large enough
|
# Increase weights to make minimum edge weight large enough
|
||||||
# to improve any non-maximum-cardinality matching.
|
# to improve any non-maximum-cardinality matching.
|
||||||
|
@ -180,7 +180,7 @@ class MatchingError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _check_input_types(edges: Sequence[tuple[int, int, int|float]]) -> None:
|
def _check_input_types(edges: Sequence[tuple[int, int, float]]) -> None:
|
||||||
"""Check that the input consists of valid data types and valid
|
"""Check that the input consists of valid data types and valid
|
||||||
numerical ranges.
|
numerical ranges.
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ def _check_input_types(edges: Sequence[tuple[int, int, int|float]]) -> None:
|
||||||
f" less than {float_limit:g}")
|
f" less than {float_limit:g}")
|
||||||
|
|
||||||
|
|
||||||
def _check_input_graph(edges: Sequence[tuple[int, int, int|float]]) -> None:
|
def _check_input_graph(edges: Sequence[tuple[int, int, float]]) -> None:
|
||||||
"""Check that the input is a valid graph, without any multi-edges and
|
"""Check that the input is a valid graph, without any multi-edges and
|
||||||
without any self-edges.
|
without any self-edges.
|
||||||
|
|
||||||
|
@ -259,8 +259,8 @@ def _check_input_graph(edges: Sequence[tuple[int, int, int|float]]) -> None:
|
||||||
|
|
||||||
|
|
||||||
def _remove_negative_weight_edges(
|
def _remove_negative_weight_edges(
|
||||||
edges: Sequence[tuple[int, int, int|float]]
|
edges: Sequence[tuple[int, int, float]]
|
||||||
) -> Sequence[tuple[int, int, int|float]]:
|
) -> Sequence[tuple[int, int, float]]:
|
||||||
"""Remove edges with negative weight.
|
"""Remove edges with negative weight.
|
||||||
|
|
||||||
This does not change the solution of the maximum-weight matching problem,
|
This does not change the solution of the maximum-weight matching problem,
|
||||||
|
@ -278,7 +278,7 @@ class _GraphInfo:
|
||||||
These data remain unchanged while the algorithm runs.
|
These data remain unchanged while the algorithm runs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, edges: Sequence[tuple[int, int, int|float]]) -> None:
|
def __init__(self, edges: Sequence[tuple[int, int, float]]) -> None:
|
||||||
"""Initialize the graph representation and prepare an adjacency list.
|
"""Initialize the graph representation and prepare an adjacency list.
|
||||||
|
|
||||||
This function takes time O(n + m).
|
This function takes time O(n + m).
|
||||||
|
@ -296,7 +296,7 @@ class _GraphInfo:
|
||||||
# "w" is the edge weight.
|
# "w" is the edge weight.
|
||||||
#
|
#
|
||||||
# These data remain unchanged while the algorithm runs.
|
# These data remain unchanged while the algorithm runs.
|
||||||
self.edges: Sequence[tuple[int, int, int|float]] = edges
|
self.edges: Sequence[tuple[int, int, float]] = edges
|
||||||
|
|
||||||
# num_vertex = the number of vertices.
|
# num_vertex = the number of vertices.
|
||||||
if edges:
|
if edges:
|
||||||
|
@ -448,7 +448,7 @@ class _NonTrivialBlossom(_Blossom):
|
||||||
#
|
#
|
||||||
# "dual_var" is the current value of the dual variable.
|
# "dual_var" is the current value of the dual variable.
|
||||||
# New blossoms start with dual variable 0.
|
# New blossoms start with dual variable 0.
|
||||||
self.dual_var: int|float = 0
|
self.dual_var: float = 0
|
||||||
|
|
||||||
# For a non-trivial, top-level S-blossom,
|
# For a non-trivial, top-level S-blossom,
|
||||||
# "best_edge_set" is a list of least-slack edges between this blossom
|
# "best_edge_set" is a list of least-slack edges between this blossom
|
||||||
|
@ -538,7 +538,7 @@ class _MatchingContext:
|
||||||
#
|
#
|
||||||
# Vertex duals are initialized to half the maximum edge weight.
|
# Vertex duals are initialized to half the maximum edge weight.
|
||||||
max_weight = max(w for (_x, _y, w) in graph.edges)
|
max_weight = max(w for (_x, _y, w) in graph.edges)
|
||||||
self.vertex_dual_2x: list[int|float] = num_vertex * [max_weight]
|
self.vertex_dual_2x: list[float] = num_vertex * [max_weight]
|
||||||
|
|
||||||
# For each T-vertex or unlabeled vertex "x",
|
# For each T-vertex or unlabeled vertex "x",
|
||||||
# "vertex_best_edge[x]" is the edge index of the least-slack edge
|
# "vertex_best_edge[x]" is the edge index of the least-slack edge
|
||||||
|
@ -548,7 +548,7 @@ class _MatchingContext:
|
||||||
# Queue of S-vertices to be scanned.
|
# Queue of S-vertices to be scanned.
|
||||||
self.queue: collections.deque[int] = collections.deque()
|
self.queue: collections.deque[int] = collections.deque()
|
||||||
|
|
||||||
def edge_slack_2x(self, e: int) -> int|float:
|
def edge_slack_2x(self, e: int) -> float:
|
||||||
"""Return 2 times the slack of the edge with index "e".
|
"""Return 2 times the slack of the edge with index "e".
|
||||||
|
|
||||||
The result is only valid for edges that are not between vertices
|
The result is only valid for edges that are not between vertices
|
||||||
|
@ -611,7 +611,7 @@ class _MatchingContext:
|
||||||
blossom.best_edge = -1
|
blossom.best_edge = -1
|
||||||
blossom.best_edge_set = None
|
blossom.best_edge_set = None
|
||||||
|
|
||||||
def lset_add_vertex_edge(self, y: int, e: int, slack: int|float) -> None:
|
def lset_add_vertex_edge(self, y: int, e: int, slack: float) -> None:
|
||||||
"""Add edge "e" from an S-vertex to unlabeled vertex or T-vertex "y".
|
"""Add edge "e" from an S-vertex to unlabeled vertex or T-vertex "y".
|
||||||
|
|
||||||
This function takes time O(1) per call.
|
This function takes time O(1) per call.
|
||||||
|
@ -625,7 +625,7 @@ class _MatchingContext:
|
||||||
if slack < best_slack:
|
if slack < best_slack:
|
||||||
self.vertex_best_edge[y] = e
|
self.vertex_best_edge[y] = e
|
||||||
|
|
||||||
def lset_get_best_vertex_edge(self) -> tuple[int, int|float]:
|
def lset_get_best_vertex_edge(self) -> tuple[int, float]:
|
||||||
"""Return the index and slack of the least-slack edge between
|
"""Return the index and slack of the least-slack edge between
|
||||||
any S-vertex and unlabeled vertex.
|
any S-vertex and unlabeled vertex.
|
||||||
|
|
||||||
|
@ -637,7 +637,7 @@ class _MatchingContext:
|
||||||
or (-1, 0) if there is no suitable edge.
|
or (-1, 0) if there is no suitable edge.
|
||||||
"""
|
"""
|
||||||
best_index = -1
|
best_index = -1
|
||||||
best_slack: int|float = 0
|
best_slack: float = 0
|
||||||
|
|
||||||
for x in range(self.graph.num_vertex):
|
for x in range(self.graph.num_vertex):
|
||||||
if self.vertex_top_blossom[x].label == _LABEL_NONE:
|
if self.vertex_top_blossom[x].label == _LABEL_NONE:
|
||||||
|
@ -662,7 +662,7 @@ class _MatchingContext:
|
||||||
self,
|
self,
|
||||||
blossom: _Blossom,
|
blossom: _Blossom,
|
||||||
e: int,
|
e: int,
|
||||||
slack: int|float
|
slack: float
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add edge "e" between the specified S-blossom and another S-blossom.
|
"""Add edge "e" between the specified S-blossom and another S-blossom.
|
||||||
|
|
||||||
|
@ -708,12 +708,12 @@ class _MatchingContext:
|
||||||
# each top-level S-blossom. This array is indexed by the base vertex
|
# each top-level S-blossom. This array is indexed by the base vertex
|
||||||
# of the blossoms.
|
# of the blossoms.
|
||||||
best_edge_to_blossom: list[int] = num_vertex * [-1]
|
best_edge_to_blossom: list[int] = num_vertex * [-1]
|
||||||
zero_slack: int|float = 0
|
zero_slack: float = 0
|
||||||
best_slack_to_blossom: list[int|float] = num_vertex * [zero_slack]
|
best_slack_to_blossom: list[float] = num_vertex * [zero_slack]
|
||||||
|
|
||||||
# And find the overall least-slack edge to any other S-blossom.
|
# And find the overall least-slack edge to any other S-blossom.
|
||||||
best_edge = -1
|
best_edge = -1
|
||||||
best_slack: int|float = 0
|
best_slack: float = 0
|
||||||
|
|
||||||
# Add the least-slack edges of every S-sub-blossom.
|
# Add the least-slack edges of every S-sub-blossom.
|
||||||
for sub in blossom.subblossoms:
|
for sub in blossom.subblossoms:
|
||||||
|
@ -774,7 +774,7 @@ class _MatchingContext:
|
||||||
# Keep the overall least-slack edge.
|
# Keep the overall least-slack edge.
|
||||||
blossom.best_edge = best_edge
|
blossom.best_edge = best_edge
|
||||||
|
|
||||||
def lset_get_best_blossom_edge(self) -> tuple[int, int|float]:
|
def lset_get_best_blossom_edge(self) -> tuple[int, float]:
|
||||||
"""Return the index and slack of the least-slack edge between
|
"""Return the index and slack of the least-slack edge between
|
||||||
any pair of top-level S-blossoms.
|
any pair of top-level S-blossoms.
|
||||||
|
|
||||||
|
@ -786,7 +786,7 @@ class _MatchingContext:
|
||||||
or (-1, 0) if there is no suitable edge.
|
or (-1, 0) if there is no suitable edge.
|
||||||
"""
|
"""
|
||||||
best_index = -1
|
best_index = -1
|
||||||
best_slack: int|float = 0
|
best_slack: float = 0
|
||||||
|
|
||||||
for blossom in self.trivial_blossom + self.nontrivial_blossom:
|
for blossom in self.trivial_blossom + self.nontrivial_blossom:
|
||||||
if (blossom.label == _LABEL_S) and (blossom.parent is None):
|
if (blossom.label == _LABEL_S) and (blossom.parent is None):
|
||||||
|
@ -1396,7 +1396,7 @@ class _MatchingContext:
|
||||||
|
|
||||||
def substage_calc_dual_delta(
|
def substage_calc_dual_delta(
|
||||||
self
|
self
|
||||||
) -> tuple[int, float|int, int, Optional[_NonTrivialBlossom]]:
|
) -> tuple[int, float, int, Optional[_NonTrivialBlossom]]:
|
||||||
"""Calculate a delta step in the dual LPP problem.
|
"""Calculate a delta step in the dual LPP problem.
|
||||||
|
|
||||||
This function returns the minimum of the 4 types of delta values,
|
This function returns the minimum of the 4 types of delta values,
|
||||||
|
@ -1460,7 +1460,7 @@ class _MatchingContext:
|
||||||
|
|
||||||
return (delta_type, delta_2x, delta_edge, delta_blossom)
|
return (delta_type, delta_2x, delta_edge, delta_blossom)
|
||||||
|
|
||||||
def substage_apply_delta_step(self, delta_2x: int|float) -> None:
|
def substage_apply_delta_step(self, delta_2x: float) -> None:
|
||||||
"""Apply a delta step to the dual LPP variables."""
|
"""Apply a delta step to the dual LPP variables."""
|
||||||
|
|
||||||
num_vertex = self.graph.num_vertex
|
num_vertex = self.graph.num_vertex
|
||||||
|
@ -1582,7 +1582,7 @@ class _MatchingContext:
|
||||||
def _verify_blossom_edges(
|
def _verify_blossom_edges(
|
||||||
ctx: _MatchingContext,
|
ctx: _MatchingContext,
|
||||||
blossom: _NonTrivialBlossom,
|
blossom: _NonTrivialBlossom,
|
||||||
edge_slack_2x: list[int|float]
|
edge_slack_2x: list[float]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Descend down the blossom tree to find edges that are contained
|
"""Descend down the blossom tree to find edges that are contained
|
||||||
in blossoms.
|
in blossoms.
|
||||||
|
@ -1610,7 +1610,7 @@ def _verify_blossom_edges(
|
||||||
|
|
||||||
# Keep track of the sum of blossom duals at each depth along
|
# Keep track of the sum of blossom duals at each depth along
|
||||||
# the current descent path.
|
# the current descent path.
|
||||||
path_sum_dual: list[int|float] = [0]
|
path_sum_dual: list[float] = [0]
|
||||||
|
|
||||||
# Keep track of the number of matched edges at each depth along
|
# Keep track of the number of matched edges at each depth along
|
||||||
# the current descent path.
|
# the current descent path.
|
||||||
|
@ -1759,7 +1759,7 @@ def _verify_optimum(ctx: _MatchingContext) -> None:
|
||||||
|
|
||||||
# Calculate the slack of each edge.
|
# Calculate the slack of each edge.
|
||||||
# A correction will be needed for edges inside blossoms.
|
# A correction will be needed for edges inside blossoms.
|
||||||
edge_slack_2x: list[int|float] = [
|
edge_slack_2x: list[float] = [
|
||||||
ctx.vertex_dual_2x[x] + ctx.vertex_dual_2x[y] - 2 * w
|
ctx.vertex_dual_2x[x] + ctx.vertex_dual_2x[y] - 2 * w
|
||||||
for (x, y, w) in ctx.graph.edges]
|
for (x, y, w) in ctx.graph.edges]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue