Linear Assignment Problem solver (LAPJV/LAPMOD)
The 'lap' library provides a fast Python solver for the Linear Assignment Problem (LAP) using the Jonker-Volgenant algorithm for both dense (LAPJV) and sparse (LAPMOD) cost matrices. It's implemented from scratch based on original research papers. Currently at version 0.5.13, it sees active but infrequent releases, usually a few per year, ensuring ongoing maintenance and compatibility updates.
Warnings
- gotcha When building `lap` from source (e.g., if pre-built wheels are unavailable or a custom environment requires it), a C++ compiler (like Microsoft Visual C++ 14.0 or greater on Windows) is required.
- gotcha The `lapmod` solver is generally faster than `lapjv` for very large matrices (side > ~5000) that are also sparse (<50% finite coefficients). For smaller or denser matrices, `lapjv` might be preferred or perform similarly.
- gotcha The `lap.lapmod` function directly supports only square matrices. For non-square assignment problems, it's crucial to transform the cost matrix into a square form (e.g., by padding with infinite costs or using `extend_cost=True` with `lapjv`).
- gotcha The `lap` library expects a cost matrix where `np.inf` or large numbers represent prohibitive costs for assignments. Incorrectly using `0` or negative numbers for non-assignment costs can lead to unexpected results or incorrect optimal assignments.
Install
-
pip install lap
Imports
- lapjv
import lap cost, x, y = lap.lapjv(C)
- lapmod
import lap cost, x, y = lap.lapmod(C)
Quickstart
import lap
import numpy as np
# Example for LAPJV (dense matrix)
# C is the cost matrix, e.g., representing costs for assigning rows to columns
C_dense = np.random.rand(4, 5) # 4 rows, 5 columns
cost, x, y = lap.lapjv(C_dense, extend_cost=True)
print(f"LAPJV Cost: {cost}\nRow assignments (x): {x}\nColumn assignments (y): {y}")
# Example for LAPMOD (sparse matrix) - typically faster for larger, sparse matrices
# For simplicity, using a dense matrix here, but 'lapmod' is optimized for sparse inputs.
# Note: lapmod primarily expects square matrices for direct use, consider extensions for non-square.
C_sparse_example = np.array([
[1, np.inf, 3, np.inf],
[np.inf, 2, np.inf, 4],
[5, np.inf, 6, np.inf],
[np.inf, 7, np.inf, 8]
])
cost_mod, x_mod, y_mod = lap.lapmod(C_sparse_example)
print(f"\nLAPMOD Cost: {cost_mod}\nRow assignments (x): {x_mod}\nColumn assignments (y): {y_mod}")