Algorithm Search⌘K

Proofs: Gale-Shapley algorithm

These are the human proofs of Gale-Shapley algorithm, at full length.

Gale-Shapley runs in O(n + m) time full

This proof shows: time.worst.

Let n=∣P∣+∣R∣n = |P| + |R| and let mm be the total length of all preference lists. Agents are indices, and each array access, comparison and stack operation costs O(1)O(1) on the word RAM.

Preprocessing, line L1. For each entry rr at position ii on the list of pp, append the pair (p,i)(p, i) to a bucket of rr: O(n+m)O(n + m). Then for each receiver rr, write mark[q]←\text{mark}[q] \leftarrow the position of qq on the list of rr for each qq on that list, read mark[p]\text{mark}[p] for each pair (p,i)(p, i) in the bucket of rr and store it at entry ii of the list of pp (or −1-1 if pp is not on the list of rr), and reset the marks. Each list entry is touched a constant number of times, so this costs O(n+m)O(n + m) and gives rankr(p)\text{rank}_r(p) at the moment of the proposal in O(1)O(1).

The main loop. By the termination argument of the correctness proof, there are at most ∣P∣+m|P| + m passes, and each pass costs O(1)O(1): a pop, one test on next[p]\text{next}[p], one list access, one rank comparison and at most one push. Line L12 costs O(n)O(n). The total time is O(n+m)O(n + m).

Complete lists. Let ∣P∣=∣R∣=k|P| = |R| = k with complete lists, so m=2k2m = 2k^2 and the bound is O(k2)O(k^2). The number of proposals is at most k2−k+1k^2 - k + 1. Suppose pp proposes to the last receiver rr on its list. Then pp has been rejected by the other k−1k - 1 receivers, and each of them holds someone from then on, by Claim 2 of the correctness proof. If rr had received a proposal before, all kk receivers would hold proposers, so all kk proposers would be held, while pp is free; so this is the first proposal to rr. After it all kk receivers hold a proposer, so FF becomes empty and the run ends. Hence at most one proposer makes kk proposals, and the others make at most k−1k - 1 each: in total at most (k−1)2+k=k2−k+1(k - 1)^2 + k = k^2 - k + 1.

Space. The lists, the rank entries, the buckets, the arrays next\text{next}, holder\text{holder} and mark\text{mark}, and a stack of at most ∣P∣|P| entries take Θ(n+m)\Theta(n + m) space. ■\blacksquare

Gale-Shapley returns the proposer-optimal stable matching full

This proof shows: correctness, termination.

Fix an input: proposers PP, receivers RR, and strict lists without repeats. A pair prpr is acceptable if rr is on the list of pp and pp is on the list of rr. Write r>pr′r >_p r' if pp ranks rr above r′r', and p>rp′p >_r p' similarly. Say that pp proposes to rr when line L7 runs with these values, and that rr rejects pp when line L8 or L11 pushes pp after its proposal to rr, or when line L10 pushes pp as the old holder of rr.

Claim 1 (states). At the start of each pass of line L4, every proposer is in exactly one of three states: on the stack FF once, held by exactly one receiver, or done, popped in line L6 with its list exhausted. Every holder relation holder[r]=p\text{holder}[r] = p is an acceptable pair. Proof. Initially all proposers are on FF and nothing is held. A pass pops pp from FF; line L6 makes it done; line L8 or L11 puts it back on FF; line L9 makes it held by rr, which held nobody; line L10 makes it held by rr and moves the old holder of rr from held to FF. Lines L9 and L10 run only after line L8 has checked that pp is on the list of rr, and rr is on the list of pp by line L7. □\square

Claim 2 (receivers trade up). Once holder[r]≠NIL\text{holder}[r] \ne \text{NIL}, it stays so, and each new value is ranked higher by rr than the previous one. Proof. Only lines L9 and L10 change holder[r]\text{holder}[r]; line L9 needs it to be NIL, and line L10 needs rankr(p)<rankr(holder[r])\text{rank}_r(p) < \text{rank}_r(\text{holder}[r]). □\square

Claim 3 (proposals are remembered). If pp has proposed to rr and prpr is acceptable, then from that moment on rr holds pp or a proposer p′p' with p′>rpp' >_r p. Proof. Right after the proposal, rr holds pp (lines L9, L10) or a proposer it prefers to pp (line L11). By Claim 2, the holder of rr only improves later. □\square

Claim 4 (proposals in order). Each proposer proposes to the receivers on its list in the order of the list, each at most once. Proof. Line L7 takes the entry at position next[p]\text{next}[p] and increments it, and nothing else changes next[p]\text{next}[p]. □\square

Termination. Each pass of the loop pops one entry of FF. Entries are pushed once initially for each proposer, and afterwards only in lines L8, L10 and L11, at most once per proposal. By Claim 4 there are at most mm proposals, where mm is the total length of the lists of PP. So there are at most ∣P∣+m|P| + m passes.

The output is a stable matching. At the end FF is empty, so by Claim 1 every proposer is held by exactly one receiver or is done, and each receiver holds at most one proposer. So the pairs returned in line L12 form a matching MM of acceptable pairs. Let prpr be an acceptable pair not in MM, and suppose pp is single in MM or r>pM(p)r >_p M(p). If pp is single, it is done and has proposed to every receiver on its list, including rr. If pp is matched, M(p)M(p) is the receiver of its last proposal, which comes after rr on its list, so by Claim 4 pp proposed to rr before. In both cases Claim 3 says that rr holds at the end a proposer p′≠pp' \ne p with p′>rpp' >_r p. So rr is not single and prefers its partner, and prpr does not block MM.

Claim 5 (no stable partner rejects). Call rr a stable partner of pp if prpr belongs to some stable matching. In every run, no proposer is rejected by one of its stable partners. Proof. Suppose not, and consider the first rejection in the run of some pp by a stable partner rr; let SS be a stable matching with pr∈Spr \in S. The pair is acceptable, so the rejection happens in line L10 or L11, and at that moment rr holds or takes a proposer p′p' with p′>rpp' >_r p, and p′p' has proposed to rr. By Claim 4, p′p' has proposed to, and been rejected by, every receiver it ranks above rr, and all these rejections happened earlier. By the choice of the first rejection, none of these receivers is a stable partner of p′p', so S(p′)S(p') is not one of them. Also S(p′)≠rS(p') \ne r because S(r)=p≠p′S(r) = p \ne p'. So in SS the proposer p′p' is single or has a partner it ranks below rr; and rr has partner pp, which it ranks below p′p'. The pair p′rp'r is acceptable, because p′p' proposed to rr and rr preferred p′p' to an acceptable proposer, so p′p' is on its list. Hence p′rp'r blocks SS, a contradiction. □\square

Proposer-optimality. For each pp, let best(p)\text{best}(p) be the stable partner of pp that pp ranks highest, if one exists. By Claim 5 and Claim 4, pp is never rejected by best(p)\text{best}(p), so it never proposes beyond best(p)\text{best}(p), and its final partner, if any, is best(p)\text{best}(p) or ranked higher. The output MM is stable, so M(p)M(p), if it exists, is a stable partner of pp, hence ranked at most as high as best(p)\text{best}(p). So M(p)=best(p)M(p) = \text{best}(p). If pp has no stable partner, then M(p)M(p) cannot exist, and pp is single. So MM is determined by the input alone, whatever the order of the stack.

Receiver-pessimality. Let SS be stable and rr a receiver with M(r)=pM(r) = p. If rr is single in SS or p>rS(r)p >_r S(r), then since S(p)≠rS(p) \ne r and r=best(p)r = \text{best}(p), the proposer pp is single in SS or ranks rr above S(p)S(p), so the acceptable pair prpr blocks SS, a contradiction. Hence every receiver matched in MM has in SS a partner it ranks at least as high as M(r)M(r). ■\blacksquare

Back to Gale-Shapley algorithm