稳定匹配问题
稳定匹配问题(stable matching)是一个常见的问题,GS算法是解决稳定匹配问题的一个优秀的算法。下面,我将以男女配对的例子来介绍稳定匹配问题并阐述GS算法的具体步骤。GS算法,全称Gale-Shapley算法。学习完稳定匹配问题和整个算法流程之后,我觉得它还可以起另外一个别名,Get-rid-of-Single算法,单身狗脱单算法。
问题描述
有n只男性单身狗的集合M = {m1, m2, …, mn}和n只女性单身狗的集合W = {w1, w2, …, wn}。假设每只男性单身狗对n只女性单身狗的喜好程度都不同,每只女性单身狗对n只男性单身狗亦如是。男单身狗mi(1 <= i <= n)有一张属于自己的关于对面n只女单身狗的排序表,mi把他最爱慕的女性放在第一位,第二爱慕的女性放在第二位,以此类推,排名越靠前女性表示mi越爱慕的女性。同样地,女单身狗wi(1 <= i <= n)也有一张属于自己的关于对面n只男单身狗的排序表,排名越靠前的男性越受wi的喜爱。每只单身狗都希望与自己最喜爱的对象结为侠侣,浪迹江湖。现在,有一个名唤月老的NPC在为这2*n只单身狗牵红线,月老收集了这些单身狗各自的排序表,并根据他们的排序表来牵红线让这些单身狗结成n对侠侣,使得这n对侠侣达成一个稳定匹配,和谐地浪迹江湖。
【稳定匹配】假设有两对伴侣(m1, w1)、(m2, w2),在m1的排序表中w2的排名比w1高,也就是说,m1喜欢w2比喜欢他现任w1要多一点。此时,若w2正好喜欢m1比喜欢她现任m2要多一点,那么m1和w2就很有可能背叛他们目前各自的侠侣关系重新与更喜欢的对象结为侠侣,剩下被甩的w1和m2继续沦落为单身狗。上面这种情况我们称为不稳定因素,要是一个匹配之中没有任何不稳定因素,那么这个匹配称为稳定匹配。再举个例子,同样是(m1, w1)、(m2, w2),m1更喜欢w2,但是w2不喜欢m1。此时,这个匹配是稳定的。因为m1和w2并非相互之间都更喜欢对方,因此他们不会”私奔”,不会打破现有的匹配关系。这样一个匹配,虽然m1无法得到自己最喜欢的w2,但这个匹配的关系是和谐稳定的。因此,我们定义稳定匹配的概念如下:给定的一组匹配结果里面,n对侠侣之间任何两对侠侣都不会存在有人想”私奔”的不稳定因素。
输入输出
输入: 每个男单身狗对n个女单身狗的排序表,每个女单身狗对n各男单身狗的排序表
输出: n对满足稳定匹配的伴侣
算法基本思想
初始,每个人都是单身狗,分别根据自己对异性的排序表开始找对象。假设一只男性单身狗mi选择了他的排序表上排名最高的女性w,并且向她示爱。这个时候就可能存在下面3种情况:
- 【1】w也是单身狗,于是他们两个结为侠侣,成功脱单
- 【2】w已经和某男性mj脱单,但是w更喜欢mi,于是w把mj甩了,重新和mi结为侠侣。mi成功挖到墙脚,换mj变成单身狗
- 【3】w已经和某男性mj脱单,而且w不喜欢mi,于是mi挖墙脚失败,为了脱单只能继续寻找排名表上下一个喜欢的女性示爱
对于每个单身狗都重复上述的过程,不断地去”骚扰”排名表上的女性,找到还没脱单的就一起脱单,找到脱单的就挖墙脚,挖不动就找下一个喜欢的对象继续重复上述过程。这就是”伟大”的单身狗脱单(GS)算法。
算法的伪代码如下所示:
初始化所有M和W集合中元素为单身狗
初始化侠侣集合S为空集
While 存在男单身狗mi
令w是mi的排名表中mi还未示爱的女性中排名最高的女性
If w也是单身狗 then
(mi, w)组成侠侣,加入侠侣集合S
Else w已经和mj脱单