본문으로 건너뛰기
김신건의 로그

안정 결혼 문제 (Stable Marriage)

· 수정 · 📖 약 2분 · 854자/단어 #algorithm #game #stable-marriage
stable marriage, 안정 결혼, Gale-Shapley, GS algorithm

정의

안정 결혼 문제 (Stable Marriage Problem) 는 N 명의 남성과 N 명의 여성이 각자 선호도 목록을 가지고 있을 때, 모든 쌍이 안정적 (stable) 인 매칭을 찾는 문제. Gale-Shapley 알고리즘 (1962, Nobel 2012) 은 O(N^2) 에 항상 안정 매칭을 찾는다. 안정적 = 어떤 (m, w) 도 현재 자신의 짝보다 상대를 더 선호하지 않는 상태.

문제 상황과 동기

  • naive: 모든 매칭 N! 가지를 검사 -> O(N!), N=10 에도 불가능.
  • 핵심 통찰: 제안 (proposal) 과정을 통해 불안정 쌍을 반복 제거. proposer 쪽이 최적의 결과를 얻는다.
  • Gale-Shapley: 매 라운드 미매칭 proposer 가 가장 선호하는 상대에게 제안. reject 되면 다음 선호로. 최대 N^2 라운드 이내 종료.

실제 활용: 전국 레지던트 매칭 (NRMP), 학교 배정, 장기 매칭.

시각화

핵심 아이디어

invariant: proposer 의 매칭은 단조 하락 (점점 덜 선호하는 쪽으로). receiver 의 매칭은 단조 상승 (점점 더 선호하는 쪽으로).

프로세스:

  1. 모든 남성이 첫 번째 선호 여성에게 제안
  2. 여성은 가장 선호하는 제안자와 약혼 (나머지 reject)
  3. reject 된 남성은 다음 선호 여성에게 제안
  4. 여성은 현재 약혼자와 새 제안자 중 더 선호하는 쪽 선택
  5. 모두 매칭될 때까지 반복 -> 최대 O(N^2) 라운드

알고리즘

Gale-Shapley(M, W, menPref, womenPref):
    womanMatch[1..N] = -1
    manNext[1..N] = 1
    freeMen = queue of all men

    while freeMen not empty:
        m = freeMen.pop()
        w = menPref[m][manNext[m]++]
        if womanMatch[w] == -1:
            womanMatch[w] = m
        else:
            m2 = womanMatch[w]
            if womenPref[w][m] < womenPref[w][m2]:
                womanMatch[w] = m
                freeMen.push(m2)
            else:
                freeMen.push(m)

    return womanMatch  (or manMatch from it)

구현

// Gale-Shapley O(N^2) stable matching
#include <bits/stdc++.h>
using namespace std;
int main() {
  int N; cin >> N;
  vector<vector<int>> menPref(N, vector<int>(N));
  vector<vector<int>> womenPref(N, vector<int>(N));
  for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
          cin >> menPref[i][j];
  for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
          cin >> womenPref[i][j];
  // 여성의 선호도 순위 lookup table
  vector<vector<int>> rank(N, vector<int>(N));
  for (int w = 0; w < N; w++)
      for (int r = 0; r < N; r++)
          rank[w][womenPref[w][r]] = r;
  vector<int> matchW(N, -1), nxt(N, 0);
  queue<int> q;
  for (int m = 0; m < N; m++) q.push(m);
  while (!q.empty()) {
      int m = q.front(); q.pop();
      int w = menPref[m][nxt[m]++];
      if (matchW[w] == -1) {
          matchW[w] = m;
      } else {
          int m2 = matchW[w];
          if (rank[w][m] < rank[w][m2]) {
              matchW[w] = m;
              q.push(m2);
          } else {
              q.push(m);
          }
      }
  }
  vector<int> matchM(N);
  for (int w = 0; w < N; w++) matchM[matchW[w]] = w;
  for (int m = 0; m < N; m++)
      cout << m << " " << matchM[m] << "\n";
  return 0;
}
stdin
4
0 1 2 3
1 2 3 0
2 3 0 1
3 0 1 2
0 1 2 3
1 2 3 0
2 3 0 1
3 0 1 2
결과
0 0
1 1
2 2
3 3

복잡도

항목
시간 (최악)O(N^2)
시간 (평균)O(N^2)
공간O(N^2) (선호도 저장)
안정성항상 안정 매칭 보장

변형 / 활용

  • Proposer-optimal / Receiver-pessimal: proposer 가 최적, receiver 가 최악의 안정 매칭. 역할을 바꾸면 반대 결과.
  • Stable Roommate: 1-set 안정 매칭. 항상 해가 존재하지 않음 (odd cycle 조건).
  • SM with Ties / Incomplete lists: 선호도에 동점 또는 불완전 목록. NP-hard 변형 존재.
  • 병원 레지던트 매칭 (NRMP): 미국 의사 매칭에 Gale-Shapley 변형 사용.
  • 양방향 시장: 학교 배정, 장기 매칭, 공공 서비스 배치.

함정

1. 전략적 조작

proposer 가 진정한 선호도를 숨기면 더 유리한 결과를 얻을 수 있음 (전략적 제안). receiver 는 전략적 조작이 어려움 (receiver-pessimal 속성).

2. Stable matching 의 유일성

안정 매칭이 유일하지 않음. Gale-Shapley 는 proposer-optimal 을 찾으며, receiver-pessimal 과 다른 해가 존재할 수 있음.

3. 자료구조 선택

여성의 순위 lookup table 없이 매번 womenPref[w] 를 선형 탐색하면 O(N^3). 반드시 rank[w][m] table 을 precompute.

BOJ 연습 문제

번호제목정답률링크
BOJ 1348주차장(수집 안 됨)kokoa-lab
BOJ 1671상어의 저녁식사(수집 안 됨)kokoa-lab
BOJ 2188축사 배정(수집 안 됨)kokoa-lab

참고

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기