Core API¶
gale_shapley_algorithm
¶
gale-shapley-algorithm: A Python implementation of the Gale-Shapley algorithm.
Modules:
-
algorithm–Algorithm module.
-
matching–Convenience function for creating matchings.
-
numeric–Numpy-backed primitives for large-scale stable-matching work.
-
person–Person module.
-
result–Result types for the Gale-Shapley algorithm.
-
stability–Stability analysis for matchings.
Classes:
-
Algorithm–Gale-Shapley Algorithm class.
-
MatchingResult–Result of running the Gale-Shapley algorithm.
-
Person–Person class, base class for Proposer and Responder.
-
Proposer–Proposer class, subclass of Person.
-
Responder–Responder class, subclass of Person.
-
StabilityResult–Result of a stability check on a matching.
Functions:
-
check_stability–Check the stability of an algorithm's matching.
-
create_matching–Create a matching from preference dictionaries.
-
find_blocking_pairs–Find all blocking pairs in a matching.
-
is_individually_rational–Check if the matching is individually rational.
Algorithm
dataclass
¶
Gale-Shapley Algorithm class.
Uses slots for memory efficiency.
Methods:
-
execute–Run the algorithm and return structured results.
-
format_all_preferences–Format preferences of all proposers and responders as a string.
-
format_matches–Format all matches as a string.
-
proposers_propose–Makes all unmatched proposers propose to their next choice.
-
responders_respond–Makes all responders that are awaiting to respond respond.
-
terminate–Returns True if all proposers are matched, False otherwise.
Attributes:
-
awaiting_to_respond_responders(list[Responder]) –Returns responders that are awaiting to respond.
-
persons(list[Proposer | Responder]) –Returns all proposers and responders.
-
unmatched_proposers(list[Proposer]) –Returns unmatched proposers, excludes self matches.
awaiting_to_respond_responders
property
¶
Returns responders that are awaiting to respond.
unmatched_proposers
property
¶
Returns unmatched proposers, excludes self matches.
execute
¶
execute() -> MatchingResult
Run the algorithm and return structured results.
Returns:
-
MatchingResult–MatchingResult with rounds, matches, unmatched, self_matches, all_matched.
Source code in src/gale_shapley_algorithm/algorithm.py
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | |
format_all_preferences
¶
Format preferences of all proposers and responders as a string.
Parameters:
Source code in src/gale_shapley_algorithm/algorithm.py
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
format_matches
¶
format_matches() -> str
Format all matches as a string.
Source code in src/gale_shapley_algorithm/algorithm.py
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
proposers_propose
¶
proposers_propose() -> None
Makes all unmatched proposers propose to their next choice.
Source code in src/gale_shapley_algorithm/algorithm.py
36 37 38 39 | |
responders_respond
¶
responders_respond() -> None
Makes all responders that are awaiting to respond respond.
Source code in src/gale_shapley_algorithm/algorithm.py
41 42 43 44 | |
terminate
¶
terminate() -> bool
Returns True if all proposers are matched, False otherwise.
Source code in src/gale_shapley_algorithm/algorithm.py
46 47 48 | |
MatchingResult
dataclass
¶
MatchingResult(rounds: int, matches: dict[str, str], unmatched: list[str], self_matches: list[str], all_matched: bool)
Result of running the Gale-Shapley algorithm.
Person
¶
Person class, base class for Proposer and Responder.
Methods:
-
format_preferences–Format the preferences of the person as a string, * indicates acceptable.
-
is_acceptable–Check if person is acceptable (ranked at or above self in preferences).
Attributes:
-
is_matched(bool) –Returns True if the person is matched to someone or self, False if match is None.
Source code in src/gale_shapley_algorithm/person.py
13 14 15 16 17 | |
is_matched
property
¶
is_matched: bool
Returns True if the person is matched to someone or self, False if match is None.
format_preferences
¶
format_preferences() -> str
Format the preferences of the person as a string, * indicates acceptable.
Source code in src/gale_shapley_algorithm/person.py
42 43 44 45 46 47 48 49 50 | |
is_acceptable
¶
Check if person is acceptable (ranked at or above self in preferences).
Parameters:
Raises:
-
ValueError–If person is not in preferences.
Returns:
-
bool–True if person is acceptable, False otherwise.
Source code in src/gale_shapley_algorithm/person.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
Proposer
¶
Bases: Person
Proposer class, subclass of Person.
Methods:
-
format_preferences–Format the preferences of the person as a string, * indicates acceptable.
-
is_acceptable–Check if person is acceptable (ranked at or above self in preferences).
-
propose–Propose to the next acceptable responder. If self is next, set match to self.
Attributes:
-
acceptable_to_propose(tuple[Responder | Proposer, ...]) –Returns a tuple of acceptable responders to propose to.
-
is_matched(bool) –Returns True if the person is matched to someone or self, False if match is None.
-
next_proposal(Responder | Proposer) –Returns the next acceptable responder to propose to, or self if exhausted.
Source code in src/gale_shapley_algorithm/person.py
61 62 63 | |
acceptable_to_propose
property
¶
Returns a tuple of acceptable responders to propose to.
is_matched
property
¶
is_matched: bool
Returns True if the person is matched to someone or self, False if match is None.
next_proposal
property
¶
Returns the next acceptable responder to propose to, or self if exhausted.
format_preferences
¶
format_preferences() -> str
Format the preferences of the person as a string, * indicates acceptable.
Source code in src/gale_shapley_algorithm/person.py
42 43 44 45 46 47 48 49 50 | |
is_acceptable
¶
Check if person is acceptable (ranked at or above self in preferences).
Parameters:
Raises:
-
ValueError–If person is not in preferences.
Returns:
-
bool–True if person is acceptable, False otherwise.
Source code in src/gale_shapley_algorithm/person.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
propose
¶
propose() -> None
Propose to the next acceptable responder. If self is next, set match to self.
Source code in src/gale_shapley_algorithm/person.py
82 83 84 85 86 87 88 89 | |
Responder
¶
Bases: Person
Responder class, subclass of Person.
Methods:
-
format_preferences–Format the preferences of the person as a string, * indicates acceptable.
-
is_acceptable–Check if person is acceptable (ranked at or above self in preferences).
-
respond–Respond to proposals and clear the current_proposals.
Attributes:
-
acceptable_proposals(list[Proposer]) –Returns a list of acceptable proposals among the current proposals.
-
awaiting_to_respond(bool) –Returns True if current_proposals is not empty.
-
is_matched(bool) –Returns True if the person is matched to someone or self, False if match is None.
Source code in src/gale_shapley_algorithm/person.py
95 96 97 | |
acceptable_proposals
property
¶
Returns a list of acceptable proposals among the current proposals.
awaiting_to_respond
property
¶
awaiting_to_respond: bool
Returns True if current_proposals is not empty.
is_matched
property
¶
is_matched: bool
Returns True if the person is matched to someone or self, False if match is None.
format_preferences
¶
format_preferences() -> str
Format the preferences of the person as a string, * indicates acceptable.
Source code in src/gale_shapley_algorithm/person.py
42 43 44 45 46 47 48 49 50 | |
is_acceptable
¶
Check if person is acceptable (ranked at or above self in preferences).
Parameters:
Raises:
-
ValueError–If person is not in preferences.
Returns:
-
bool–True if person is acceptable, False otherwise.
Source code in src/gale_shapley_algorithm/person.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
respond
¶
respond() -> None
Respond to proposals and clear the current_proposals.
Source code in src/gale_shapley_algorithm/person.py
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
StabilityResult
dataclass
¶
StabilityResult(is_stable: bool, is_individually_rational: bool, blocking_pairs: list[tuple[str, str]])
Result of a stability check on a matching.
check_stability
¶
check_stability(algorithm: Algorithm) -> StabilityResult
Check the stability of an algorithm's matching.
Parameters:
Returns:
-
StabilityResult–StabilityResult with is_stable, is_individually_rational, and blocking_pairs.
Source code in src/gale_shapley_algorithm/stability.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | |
create_matching
¶
create_matching(proposer_preferences: dict[str, list[str]], responder_preferences: dict[str, list[str]]) -> MatchingResult
Create a matching from preference dictionaries.
This is the simplest way to use the library. Provide preference rankings for each side and get back a MatchingResult.
Persons not listed in a preference list are considered unacceptable. Each person is automatically added to their own preference list at the end (making everyone they listed acceptable).
Parameters:
-
(proposer_preferences¶dict[str, list[str]]) –Mapping of proposer names to ordered list of responder names.
-
(responder_preferences¶dict[str, list[str]]) –Mapping of responder names to ordered list of proposer names.
Returns:
-
MatchingResult–MatchingResult with the matching outcome.
Example
result = create_matching( ... proposer_preferences={ ... "alice": ["bob", "charlie"], ... "dave": ["charlie", "bob"], ... }, ... responder_preferences={ ... "bob": ["alice", "dave"], ... "charlie": ["dave", "alice"], ... }, ... ) result.matches
Source code in src/gale_shapley_algorithm/matching.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | |
find_blocking_pairs
¶
find_blocking_pairs(proposers: list[Proposer], responders: list[Responder]) -> list[tuple[str, str]]
Find all blocking pairs in a matching.
A blocking pair (p, r) exists when proposer p and responder r both prefer each other over their current matches.
Parameters:
-
(proposers¶list[Proposer]) –List of proposers in the matching.
-
(responders¶list[Responder]) –List of responders in the matching.
Returns:
Source code in src/gale_shapley_algorithm/stability.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
is_individually_rational
¶
Check if the matching is individually rational.
A matching is individually rational if every matched person finds their match acceptable (ranked at or above themselves).
Parameters:
-
(proposers¶list[Proposer]) –List of proposers in the matching.
-
(responders¶list[Responder]) –List of responders in the matching.
Returns:
-
bool–True if individually rational, False otherwise.
Source code in src/gale_shapley_algorithm/stability.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
numeric subpackage¶
Numpy-backed primitives for large-scale / numerical work. Install with the
numeric extra:
pip install "gale-shapley-algorithm[numeric]"
Gale-Shapley on rank matrices¶
gs
¶
Numpy Gale-Shapley deferred acceptance on rank matrices.
Type Aliases:
-
Selector–Picks which free proposer goes next.
Classes:
-
GSStats–Result of a traced Gale-Shapley run.
Functions:
-
fifo_selector–Return the first index — pops in arrival order (FIFO).
-
gale_shapley–Run proposer-optimal deferred acceptance.
-
gale_shapley_traced–Run proposer-optimal deferred acceptance and return per-proposer statistics.
-
lifo_selector–Return the last index — equivalent to
list.pop()(LIFO). -
men_optimal_gs–Return the men-optimal stable matching (conventionally men propose, women dispose).
-
men_optimal_traced–Men-optimal stable matching with per-man proposal stats.
-
random_selector–Build a uniform-random selector backed by a numpy
Generator. -
women_optimal_gs–Return the women-optimal stable matching, still in men-indexed form
match[m] = w. -
women_optimal_traced–Women-optimal stable matching with per-woman proposal stats.
Selector
¶
Picks which free proposer goes next.
Receives the current free list of proposer ids and returns an index into
that list (0..len(free)-1; negative indices supported per list.pop
semantics). The default is :func:lifo_selector, which matches the
historical behavior of :func:gale_shapley (free.pop()).
GSStats
dataclass
¶
GSStats(match: NDArray[int16], proposals: int, proposals_per_proposer: NDArray[int16])
Result of a traced Gale-Shapley run.
eq=False because :attr:match and :attr:proposals_per_proposer are
numpy arrays whose __eq__ returns an array, not a bool — so the
dataclass-generated __eq__ would raise. Compare fields directly.
Attributes:
-
match(NDArray[int16]) –shape
(n,), dtypeint16. Proposer-indexed:match[p]is the responder paired with proposerp. The wrapper :func:women_optimal_tracedre-indexes this to be men-indexed; see its docstring. -
proposals(int) –total number of proposal events. Equals
proposals_per_proposer.sum(). -
proposals_per_proposer(NDArray[int16]) –shape
(n,), dtypeint16.proposals_per_proposer[p]is the number of proposals made by proposerp, which also equals the rank (1-indexed) ofp's final match inp's preference list.
fifo_selector
¶
Return the first index — pops in arrival order (FIFO).
Source code in src/gale_shapley_algorithm/numeric/gs.py
37 38 39 40 | |
gale_shapley
¶
gale_shapley(proposer_rank: NDArray[integer], responder_rank: NDArray[integer]) -> NDArray[int16]
Run proposer-optimal deferred acceptance.
Parameters:
-
(proposer_rank¶NDArray[integer]) –(n, n)array whereproposer_rank[i, j]is the 1-indexed position of responderjin proposeri's preference list. Each row must be a permutation of1..n. -
(responder_rank¶NDArray[integer]) –(n, n)array with the symmetric convention.
Returns:
-
NDArray[int16]–matchof shape(n,), dtypeint16, wherematch[i]is -
NDArray[int16]–the responder paired with proposer
i.
Raises:
-
ValueError–if the two arrays don't have the same square shape, or any row is not a permutation of
1..n.
Source code in src/gale_shapley_algorithm/numeric/gs.py
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
gale_shapley_traced
¶
gale_shapley_traced(proposer_rank: NDArray[integer], responder_rank: NDArray[integer], *, selector: Selector = lifo_selector) -> GSStats
Run proposer-optimal deferred acceptance and return per-proposer statistics.
Mechanically identical to :func:gale_shapley (sequential McVitie-Wilson
on the free-proposer pool), but exposes the proposal count and a
pluggable proposer-selection rule. The final matching is invariant under
selector choice (Knuth); the proposal count is not.
Parameters:
-
(proposer_rank¶NDArray[integer]) –(n, n)array whereproposer_rank[i, j]is the 1-indexed position of responderjin proposeri's preference list. Each row must be a permutation of1..n. -
(responder_rank¶NDArray[integer]) –(n, n)array with the symmetric convention. -
(selector¶Selector, default:lifo_selector) –picks which free proposer acts next; defaults to :func:
lifo_selector. See :data:Selector.
Returns:
Raises:
-
ValueError–if the two arrays don't have the same square shape, or any row is not a permutation of
1..n. -
IndexError–if
selectorreturns an index outside the free list.
Source code in src/gale_shapley_algorithm/numeric/gs.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
lifo_selector
¶
Return the last index — equivalent to list.pop() (LIFO).
Source code in src/gale_shapley_algorithm/numeric/gs.py
31 32 33 34 | |
men_optimal_gs
¶
men_optimal_gs(men_rank: NDArray[integer], women_rank: NDArray[integer]) -> NDArray[int16]
Return the men-optimal stable matching (conventionally men propose, women dispose).
Source code in src/gale_shapley_algorithm/numeric/gs.py
197 198 199 | |
men_optimal_traced
¶
men_optimal_traced(men_rank: NDArray[integer], women_rank: NDArray[integer], *, selector: Selector = lifo_selector) -> GSStats
Men-optimal stable matching with per-man proposal stats.
Equivalent to gale_shapley_traced(men_rank, women_rank, selector=...);
provided for symmetry with :func:men_optimal_gs.
Parameters:
-
(men_rank¶NDArray[integer]) –(n, n)rank matrix for men (proposers). -
(women_rank¶NDArray[integer]) –(n, n)rank matrix for women (responders). -
(selector¶Selector, default:lifo_selector) –see :data:
Selector.
Returns:
Source code in src/gale_shapley_algorithm/numeric/gs.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | |
random_selector
¶
Build a uniform-random selector backed by a numpy Generator.
Roth-Vande Vate-style: pick a free proposer uniformly at random each step. Final matching is invariant to selector choice (Knuth's order independence) but the proposal count is not — random order is a useful baseline against LIFO/FIFO for amortized analysis.
Parameters:
-
(rng¶Generator) –a numpy
Generator(usenp.random.default_rng(seed)for determinism).
Returns:
-
A(Selector) –data:
Selectorclosure that drawsrng.integers(len(free))per call.
Source code in src/gale_shapley_algorithm/numeric/gs.py
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | |
women_optimal_gs
¶
women_optimal_gs(men_rank: NDArray[integer], women_rank: NDArray[integer]) -> NDArray[int16]
Return the women-optimal stable matching, still in men-indexed form match[m] = w.
Source code in src/gale_shapley_algorithm/numeric/gs.py
202 203 204 | |
women_optimal_traced
¶
women_optimal_traced(men_rank: NDArray[integer], women_rank: NDArray[integer], *, selector: Selector = lifo_selector) -> GSStats
Women-optimal stable matching with per-woman proposal stats.
Runs :func:gale_shapley_traced with women as the proposing side. The
returned match is re-indexed to men-indexed form for consistency with
:func:women_optimal_gs. proposals_per_proposer remains
women-indexed, since women are the proposers in this run.
Parameters:
-
(men_rank¶NDArray[integer]) –(n, n)rank matrix for men. -
(women_rank¶NDArray[integer]) –(n, n)rank matrix for women. -
(selector¶Selector, default:lifo_selector) –see :data:
Selector.
Returns:
-
GSStats–class:
GSStatswithmatch[m] = w(men-indexed) and -
GSStats–proposals_per_proposer[w] = number of proposals woman w made -
GSStats–(women-indexed).
proposalsis the unambiguous total.
Source code in src/gale_shapley_algorithm/numeric/gs.py
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | |
Stability checks¶
stability
¶
Vectorized stability checks for rank-matrix matchings.
Functions:
-
find_blocking_pairs–Return every
(proposer, responder)pair that blocksmatch. -
is_stable–Return
Trueiffmatchis a perfect matching with no blocking pair. -
is_stable_batch–Vectorized stability check across a batch of matchings.
find_blocking_pairs
¶
find_blocking_pairs(proposer_rank: NDArray[integer], responder_rank: NDArray[integer], match: NDArray[integer]) -> list[tuple[int, int]]
Return every (proposer, responder) pair that blocks match.
A blocking pair (p, r) is one where p strictly prefers r to
his current partner and r strictly prefers p to her current
partner.
Parameters:
-
(proposer_rank¶NDArray[integer]) –(n, n)rank matrix for the proposing side. -
(responder_rank¶NDArray[integer]) –(n, n)rank matrix for the responding side. -
(match¶NDArray[integer]) –(n,)men-indexed matching.
Returns:
Source code in src/gale_shapley_algorithm/numeric/stability.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
is_stable
¶
is_stable(proposer_rank: NDArray[integer], responder_rank: NDArray[integer], match: NDArray[integer]) -> bool
Return True iff match is a perfect matching with no blocking pair.
Source code in src/gale_shapley_algorithm/numeric/stability.py
53 54 55 56 57 58 59 60 61 62 63 64 | |
is_stable_batch
¶
is_stable_batch(proposer_rank: NDArray[integer], responder_rank: NDArray[integer], matchings: NDArray[integer]) -> NDArray[bool_]
Vectorized stability check across a batch of matchings.
Memory use is O(K * n**2) where K is the batch size. For K = n! (full permutation enumeration) the tensor grows as O(n**2 * n!), ~12 MB at n=8 and ~360 MB at n=10 — caller's responsibility to keep K bounded.
Parameters:
-
(proposer_rank¶NDArray[integer]) –(n, n)rank matrix. -
(responder_rank¶NDArray[integer]) –(n, n)rank matrix. -
(matchings¶NDArray[integer]) –(K, n)array of candidate men-indexed matchings.
Returns:
-
NDArray[bool_]–(K,)bool array.
Source code in src/gale_shapley_algorithm/numeric/stability.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | |
Stable-matching lattice enumeration¶
lattice
¶
Enumerate the full stable-matching lattice of an SMP instance.
Two enumeration strategies are provided:
rotation (default, Gusfield-Irving 1989): navigates the lattice by exposing
and eliminating rotations. Runs in O(n**2 + |L| * n**2) where |L| is the number
of stable matchings. Scales past n=50 comfortably; the only asymptotic cost is
|L| itself, which is empirically small for uniform-random preferences but can
be exponential in adversarial instances.
brute: vectorized batched brute force over all n! permutations. Simple,
memory-bounded via batching, but capped at max_n (default 10) because n!
grows fast. Useful as a correctness oracle for testing the rotation
implementation, and for instances where you want the deterministic n!-enumeration
order.
Also exports two lower-level primitives that expose the rotation structure
itself: :func:exposed_rotations returns the rotations currently applicable
at a given stable matching, and :func:apply_rotation takes one step down
the lattice. These are the building blocks for any algorithm that walks the
stable-matching lattice (lattice-navigation search, RL agents that learn a
rotation policy, incremental maintenance under preference changes, etc.).
References
Gusfield, D. (1987). "Three Fast Algorithms for Four Problems in Stable Marriage." SIAM J. Comput. 16(1). Irving, R. W. and Leather, P. (1986). "The Complexity of Counting Stable Marriages." SIAM J. Comput. 15(3). Gusfield, D. and Irving, R. W. (1989). The Stable Marriage Problem: Structure and Algorithms. MIT Press.
Functions:
-
apply_rotation–Apply a rotation to a stable matching, producing the next matching.
-
enumerate_stable_matchings–Return every stable matching of the instance.
-
exposed_rotations–Return the list of rotations currently exposed at
matching.
apply_rotation
¶
Apply a rotation to a stable matching, producing the next matching.
Parameters:
-
(matching¶NDArray[integer]) –(n,)men-indexed stable matching. -
(rotation¶NDArray[integer]) –(r, 2)array from :func:exposed_rotations.
Returns:
-
NDArray[int16]–A fresh
(n,)int16 matching. Input arrays are not mutated.
Source code in src/gale_shapley_algorithm/numeric/lattice.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
enumerate_stable_matchings
¶
enumerate_stable_matchings(men_rank: NDArray[integer], women_rank: NDArray[integer], method: Literal['rotation', 'brute'] = 'rotation', max_n: int = _DEFAULT_MAX_N_BRUTE, batch_size: int = _DEFAULT_BATCH_SIZE) -> NDArray[int16]
Return every stable matching of the instance.
Parameters:
-
(men_rank¶NDArray[integer]) –(n, n)men's rank matrix. -
(women_rank¶NDArray[integer]) –(n, n)women's rank matrix. -
(method¶Literal['rotation', 'brute'], default:'rotation') –"rotation"(default) uses the Gusfield-Irving rotation algorithm and scales to large n;"brute"uses vectorized permutation enumeration and is capped atmax_n. -
(max_n¶int, default:_DEFAULT_MAX_N_BRUTE) –only consulted when
method="brute". -
(batch_size¶int, default:_DEFAULT_BATCH_SIZE) –only consulted when
method="brute".
Returns:
-
NDArray[int16]–(|L|, n)int16 array of men-indexed stable matchings.
Raises:
-
ValueError–if the rank matrices are not same-shape square permutation matrices, or
methodis unknown, or brute-force is requested withn > max_n.
Source code in src/gale_shapley_algorithm/numeric/lattice.py
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | |
exposed_rotations
¶
exposed_rotations(men_rank: NDArray[integer], women_rank: NDArray[integer], matching: NDArray[integer]) -> list[NDArray[int16]]
Return the list of rotations currently exposed at matching.
Each rotation is an (r, 2) int16 array; row i is [m_i, w_{i+1}],
where w_{i+1} is the partner m_i acquires if the rotation is eliminated.
Applying the rotation amounts to assigning new_matching[m_i] = w_{i+1}
cyclically.
At the men-optimal matching every rotation exposed here corresponds to a distinct one-step move down the lattice; at the women-optimal matching no rotations are exposed (you have reached the infimum).
Parameters:
-
(men_rank¶NDArray[integer]) –(n, n)men's rank matrix. -
(women_rank¶NDArray[integer]) –(n, n)women's rank matrix. -
(matching¶NDArray[integer]) –(n,)men-indexed stable matching.
Returns:
-
list[NDArray[int16]]–List of rotations; may be empty if no rotation is exposed.
Raises:
-
ValueError–if the rank matrices are not same-shape square permutation matrices.
Source code in src/gale_shapley_algorithm/numeric/lattice.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |