Source code for gasm.lap
"""Linear Assignment Problem (LAP) solver registry.
GASM ends with a LAP on the converged vertex (or edge) score matrix, searching
for a maximum-score assignment. Solvers are registered by name so that new ones
can be added without touching the rest of the code base. The ``lap`` argument of
:func:`gasm.match` selects one of them, ``'auto'`` picking the best available
solver for the active platform.
Currently available:
- ``'jv'``: Jonker-Volgenant, via :func:`scipy.optimize.linear_sum_assignment`
(CPU).
- ``'auction'``: Bertsekas auction algorithm with epsilon-scaling (native GPU
implementation; falls back to a NumPy reference on CPU).
"""
from __future__ import annotations
from typing import Callable
_CPU_SOLVERS: dict[str, Callable] = {}
[docs]
def register_cpu_solver(name: str, func: Callable) -> None:
"""Register a CPU LAP solver under ``name``."""
_CPU_SOLVERS[name] = func
[docs]
def get_cpu_solver(name: str) -> Callable:
"""Return the CPU LAP solver registered under ``name``.
``'auto'`` resolves to the Jonker-Volgenant solver.
"""
if name == "auto":
name = "jv"
if name not in _CPU_SOLVERS:
raise ValueError(
f"Unknown LAP solver '{name}'. Available: {sorted(_CPU_SOLVERS)} or 'auto'."
)
return _CPU_SOLVERS[name]
[docs]
def available() -> list[str]:
"""List the registered CPU LAP solver names."""
return sorted(_CPU_SOLVERS)
# Register built-in solvers.
from . import jv as _jv # noqa: E402
from . import auction as _auction # noqa: E402
register_cpu_solver("jv", _jv.solve)
register_cpu_solver("auction", _auction.solve)