在计算机科学和经济学中,稳定婚姻算法(Stable Marriage Problem)是一个经典问题。它由 David Gale 和 Lloyd Shapley 在 1962 年提出,用于解决两个相等数量群体之间的配对问题,使得没有两个人会更愿意彼此配对而不是当前的伴侣。这种算法也被称为 延迟接受算法(Gale-Shapley Algorithm),广泛应用于大学招生、医院住院医师匹配等领域。

假设我们有 n 位男士和 n 位女士。每位男士对所有女士有一个偏好排序,每位女士也对所有男士有偏好排序。一个配对方案是稳定的,当且仅当不存在一对男女(m, w),他们不是彼此的当前伴侣,但都更喜欢对方胜过当前伴侣。这样的配对称为“不稳定对”,而我们的目标就是避免这种情况。
Gale-Shapley 算法采用“求婚-拒绝”机制:
该算法保证在有限步内结束,并且结果是男士最优、女士最劣的稳定匹配(即每位男士在所有可能的稳定匹配中获得最好的可能伴侣)。
下面我们用 C语言实现这个算法。我们将使用以下数据结构:
menPref:男士偏好矩阵(menPref[i][j] 表示第 i 位男士第 j 喜欢的女士)womenPref:女士偏好矩阵(womenPref[i][j] 表示第 i 位女士第 j 喜欢的男士)womenRank:为加速查找,将女士偏好转换为排名(womenRank[w][m] 表示女士 w 对男士 m 的偏好排名,越小越喜欢)nextProposal:记录每位男士下一次要向谁求婚(索引)currentPartner:记录每位女士当前的临时伴侣freeMen:用队列管理当前自由的男士#include <stdio.h>#include <stdlib.h>#define MAX 100int main() { int n; printf("请输入人数 n: "); scanf("%d", &n); int menPref[MAX][MAX]; int womenPref[MAX][MAX]; int womenRank[MAX][MAX]; int nextProposal[MAX] = {0}; int currentPartner[MAX]; int freeMen[MAX]; int freeCount = n; // 输入男士偏好 printf("\n输入 %d 位男士的偏好(每行 n 个数字,表示女士编号 0~%d):\n", n, n - 1); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%d", &menPref[i][j]); } } // 输入女士偏好 printf("\n输入 %d 位女士的偏好(每行 n 个数字,表示男士编号 0~%d):\n", n, n - 1); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%d", &womenPref[i][j]); } } // 构建女士的排名表:womenRank[w][m] = 男士 m 在女士 w 心中的排名(0 最喜欢) for (int w = 0; w < n; w++) { for (int rank = 0; rank < n; rank++) { int man = womenPref[w][rank]; womenRank[w][man] = rank; } } // 初始化所有女士无伴侣,用 -1 表示 for (int i = 0; i < n; i++) { currentPartner[i] = -1; freeMen[i] = i; // 所有男士初始自由 } // 主循环:只要还有自由男士 while (freeCount > 0) { int man = freeMen[freeCount - 1]; // 取出一个自由男士 freeCount--; // 他向下一个未求婚的女士求婚 int woman = menPref[man][nextProposal[man]]; nextProposal[man]++; if (currentPartner[woman] == -1) { // 女士当前单身,接受求婚 currentPartner[woman] = man; } else { int currentMan = currentPartner[woman]; // 比较当前伴侣和新追求者 if (womenRank[woman][man] < womenRank[woman][currentMan]) { // 女士更喜欢新追求者 currentPartner[woman] = man; // 原伴侣变回自由 freeMen[freeCount] = currentMan; freeCount++; } else { // 女士拒绝,男士继续自由 freeMen[freeCount] = man; freeCount++; } } } // 输出结果 printf("\n稳定婚姻配对结果:\n"); for (int w = 0; w < n; w++) { printf("男士 %d 与 女士 %d 配对\n", currentPartner[w], w); } return 0;}
假设 n = 3,输入如下:
男士偏好:
0: 0 1 2
1: 1 0 2
2: 0 1 2
女士偏好:
0: 1 0 2
1: 0 1 2
2: 0 1 2
程序将输出稳定配对,例如:
男士 1 与 女士 0 配对
男士 0 与 女士 1 配对
男士 2 与 女士 2 配对
稳定婚姻算法不仅是理论上的优美解法,更是现实世界配对算法的基础。例如美国的“国家住院医师匹配计划”(NRMP)就基于此算法改进而来。理解它有助于掌握算法设计中的贪心策略、稳定性概念以及实际应用价值。
通过本教程,你已经学会了:
无论你是算法初学者还是准备面试的程序员,掌握稳定婚姻算法、C语言实现、延迟接受算法和配对算法这四个关键词所代表的知识,都将为你打下坚实基础。
本文由主机测评网于2025-12-17发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025129139.html