Skip to content

v1.7.0 - rotation-based lattice enumeration

Choose a tag to compare

@oedokumaci oedokumaci released this 18 Apr 13:15

Highlights

Ships the classical Gusfield-Irving 1989 rotation algorithm for enumerating the stable-matching lattice, plus two public primitives that expose the rotation structure directly for fine-grained lattice navigation.

  • enumerate_stable_matchings(men_rank, women_rank, method='rotation') — default; scales comfortably past n=50 with runtime O(n² + |L|·n²), where |L| is the number of stable matchings. Replaces the vectorized brute force as the default method; the brute-force method remains available via method='brute' as a correctness oracle for small instances.
  • exposed_rotations(men_rank, women_rank, matching) — returns the rotations currently applicable at a given stable matching. Each exposed rotation corresponds to a one-step move down the lattice.
  • apply_rotation(matching, rotation) — takes that step, producing the next stable matching.

The two primitives are the building blocks for any algorithm that walks the stable-matching lattice (search, incremental maintenance under preference changes, learned policies, and so on).

Correctness

Cross-validated against the brute-force enumerator on random n=3..7 instances — full set equality in every case. New tests confirm:

  • exposed_rotations is empty at the women-optimal (lattice infimum)
  • exposed_rotations is non-empty at the men-optimal when |L| > 1
  • apply_rotation preserves stability and produces a strictly different matching
  • apply_rotation does not mutate its input arrays

Scaling smoke test runs the rotation enumerator at n=20 — impossible for brute force (20! = 2.4e18 permutations).

Compatibility

Backwards-compatible — no signature changes to existing functions. Code that currently calls enumerate_stable_matchings(men_rank, women_rank) will silently switch from brute force to rotation (same output set, different algorithm).

Full changelog: v1.6.0...v1.7.0