Setting:

  • Two groups, say hospitals and students, each of size
  • Each hospital has a ranking of the students
  • Each student has a ranking of the hospitals
  • Assumption : The list of preferences are strict and complete

THE STABLE MATCHING problem asks to find a stable matching, if one exists. Gale-Shapely algorithm for complete lists:

  • There is always a stable matching! (where everyone is allocated)
  • time algorithm to find a stable matching
  • STABLE MATCHING
1. Initially all hospitals and students are free
2. while there is a hospital which is free and hasn’t made an offer to every student do
3.     Choose such a hospital h
4.     Let s be highest ranked student to which h hasn’t made an offer yet
5.     if s is free then
6.         (s, h) are matched
7.     else
8.         s is currently matched to some hospital h'
9.         if s prefers h' to h then
10.            h remains free
11.        else
12.            s prefers h to their current match h'
13.            (s, h) get matched and h' becomes free
14.        end if
15.    end if
16. end while
#include <bits/stdc++.h>
using namespace std;
 
int main() {
    int n;
    cin >> n;
 
    // hospitalPref[h][i] = i-th preferred student of hospital h
    vector<vector<int>> hospitalPref(n, vector<int>(n));
 
    // studentPref[s][i] = i-th preferred hospital of student s
    vector<vector<int>> studentPref(n, vector<int>(n));
 
    for (int h = 0; h < n; ++h)
        for (int i = 0; i < n; ++i)
            cin >> hospitalPref[h][i];
 
    for (int s = 0; s < n; ++s)
        for (int i = 0; i < n; ++i)
            cin >> studentPref[s][i];
 
    // rank[s][h] = how much student s likes hospital h (lower = better)
    vector<vector<int>> rank(n, vector<int>(n));
    for (int s = 0; s < n; ++s)
        for (int i = 0; i < n; ++i)
            rank[s][studentPref[s][i]] = i;
 
    vector<int> studentMatch(n, -1);   // which hospital student s is matched to
    vector<int> hospitalMatch(n, -1);  // which student hospital h is matched to
    vector<int> nextOffer(n, 0);       // next student index to propose to
 
    queue<int> freeHospitals;
    for (int h = 0; h < n; ++h)
        freeHospitals.push(h);
 
    // ---- Gale-Shapley ----
    while (!freeHospitals.empty()) {
        int h = freeHospitals.front();
        freeHospitals.pop();
 
        int s = hospitalPref[h][nextOffer[h]++];
        
        if (studentMatch[s] == -1) {
            // s is free
            studentMatch[s] = h;
            hospitalMatch[h] = s;
        } else {
            int h2 = studentMatch[s];
            // check preference
            if (rank[s][h] < rank[s][h2]) {
                // s prefers h
                studentMatch[s] = h;
                hospitalMatch[h] = s;
 
                hospitalMatch[h2] = -1;
                freeHospitals.push(h2);
            } else {
                // s rejects h
                freeHospitals.push(h);
            }
        }
    }
 
    // Output result
    cout << "Matches (hospital -> student):\n";
    for (int h = 0; h < n; ++h)
        cout << h << " -> " << hospitalMatch[h] << "\n";
}
 

Running time is clearly , but correctness is not obvious at all!

Correctness of Gale-Shapley Algorithm

  • Students keep getting better offers as the algorithm progresses
  • The sequence of offers made by Hospitals keep getting worse for them

If a hospital is free, then there is a student to whom they have not yet made an offer.
So all hospitals and students are matched!

Theorem

Gale-Shapley returns a stable matching

  • Suppose not, and there is an unstable pair and
  • Let and be allocation done by Gale-Shapley
    • There prefers over , and prefers over
  • Last offer made by hospital was to student
  • Question : Did make an offer to student before making to ?
  • If NO, then prefers to . Contradiction
  • If YES, then was rejected by in favour of some other hospital. As the student offers keep getting better and since it follows that prefers its final offer to .

Surprising Property of Gale-Shapley algorithm

Gale Shapley always returns the SAME stable matching

For each hospital , let

  1. Let
  2. is the lowest ranked (in preference list of ) hospital from

Theorem

Gale-Shapley always returns the matching which matches s to for each student

  • Again : Not clear why this is even a matching, forget being stable!