题意:男女各n人,进行婚配,对于每个人来说,所有异性都存在优先次序,即最喜欢某人,其次喜欢某人...输出一个稳定婚配方案。所谓稳定,就是指未结婚的一对异性,彼此喜欢对方的程度都胜过自己的另一半,那么这对异性就有私奔的可能性。
这里明显也是一个匹配问题,与最佳二分完美匹配所不同的是,二分匹配重在求最佳权值,而这里求的是满足彼此的要求。这里用到了Gale-Shapley算法。
算法学习:http://wenku.baidu.com/view/964a503843323968011c92c3.html
http://wenku.baidu.com/view/7aa841f2fab069dc502201cb.html
前者描述详细,值得一看;后者虽然描述不够清晰,但给出了优劣势的证明,并且对第一篇文章倒数第三段提到的“欺诈与博弈”给出了具体样例,可以借鉴。
先把代码贴出来,其实就是贪心的思路,模拟一下这种操作方式,O(n2)的复杂度,已经是输入复杂度了,不能再省了。
uva挂了,所以不保证code的正确性。
#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;
#define Clear(f, nr) memset(f, nr, sizeof(f))
const int SIZE = ;
const int INF = << ;
int n;
int men[SIZE][SIZE], wmen[SIZE][SIZE];
int menChs[SIZE]; //女生的选择
int que[SIZE * SIZE];
bool vis[SIZE][SIZE];
void StableMarriage()
{
int front = , rear = ;
Clear(menChs, -);
Clear(vis, );
for(int i = ; i <= n; i ++)
que[rear ++] = i; while(front < rear) {
int tmp = que[front ++];
for(int i = ; i <= n; i ++) {
if(!vis[tmp][wmen[tmp][i]]) {
vis[tmp][wmen[tmp][i]] = ;
if(menChs[wmen[tmp][i]] == -) {
menChs[wmen[tmp][i]] = tmp;
break; //忘加一个break改了一个小时
}
else {
int mark = menChs[wmen[tmp][i]];
if(men[wmen[tmp][i]][mark] < men[wmen[tmp][i]][tmp]) {
menChs[wmen[tmp][i]] = tmp;
que[rear ++] = mark;
break;
}
}
}
}
} return ;
}
void Print()
{
for(int j = ; j <= n; j ++)
for(int i = ; i <= n; i ++)
if(menChs[i] == j)
cout << i << endl;
}
int main()
{
int T, x;
cin >> T;
int gg = ;
while(T --) {
if(gg ++) puts("");
cin >> n;
for(int i = ; i <= n; i ++)
for(int j = ; j <= n; j ++)
cin >> wmen[i][j]; //女生记邻接表
for(int i = ; i <= n; i ++)
for(int j = ; j <= n; j ++) {
cin >> x;
men[i][x] = n - j; //男生记邻接阵 权值
}
StableMarriage();
Print();
}
}
同样还是用自己的话描述一下:
一、首先给出算法:依据优先次序,男生在第一轮分别向自己最喜欢的女生求婚,女生对于求婚,总是从中选择最理想的人选。一轮结束后,男生的结果是求婚成功或者被拒。第二轮,单身们继续追求真爱,向各自喜好的排在第二的人求婚(不管对方是否有男伴),女生同样是选择最理想的人选。这一轮结束后,男生的结果是求婚成功、被拒,又或是被其他男人抢走女伴,重新沦为单身。第三轮...直到不存在单身男子为止。
二、为什么这样就能得到“稳定”的方案呢?
在算法运行结束后,对于一对(x,y),男生x是按优先次序,从高到低向女生求婚,之前的女生都拒绝了他,才会与y成婚。假设仍存在不稳定,那么相比于y,会使男生x私奔的只有那些拒绝了x的女生,由算法可知,女生拒绝x的理由是她们有更优的人选,所以女生们没有理由跟x私奔,假设失败。所以Gale-Shapley算法一定能得到稳定方案。
三、进一步讨论:优势问题。看似对男生残酷(不断地表白)的选择方式,其实最终得到的方案,是在稳定前提下,男生的最优方案。相对应的,对女生而言是最差的方案。
“男生最优”其实不难理解,因为男生x是按优先顺序表白的,比成婚对象y更理想的女生都拒绝了x,理由是有了比x更好的x'。若是对男生而言,还存在更优方案,那么只能去“强迫”拒绝了x的女生y',组成(x,y')。可是对于x'而言,被x替换掉以后只能找不如y'的女生成婚了,不稳定也就出现了:(x',y')会私奔。所以不会有更优方案,原方案就是“男生最优”。
“女生最劣”不好理解,不过可以仿照上述分析。对于女生而言,若还有更劣势的情况,只能是女生y还可能和不如x的男生x'成婚,组成(x',y),这里注意,那么x在被拒之后,只能去追求不如y的女生,不稳定也就出现了:(x,y)会私奔,所以不会有更劣方案,原方案已经是“女生最劣”。
另一种抽象的解释:已知在稳定条件下,对于男生、女生,方案的优劣都有上下界。在方案未定之前,整个系统是不稳定的(仍有单身,说明跟别人抢老婆失败了= =)。男生逐渐降低自己的要求(逼近上界),主动出击,寻求最理想的真爱;女生被动接受,在选择她的众多男生中选择最佳(逼近下界)。当系统稳定(单身消失),男女生的选择分别是在稳定条件下的最优、最劣。(注意,女生最后的组合(x,y),虽然x不一定是最差的,但是比x好的都被其他女生抢走了,没能向y表白)
优劣只是相对而言,交换顺序,就是女生主动、男生被动,最终方案就是“男生最劣”、“女生最优”。
四、“欺诈与博弈”
既然“女生最劣”,是不是可以有更优解呢?这就要欺诈。
男 女
1:BADC A:1234
2:ABCD B:2143
3:BCAD C:3241
4:ADBC D:4231
原本按照G-S算法,第一轮结束的结果是:(2,A),(1,B),3、4分别被B,A拒绝了;最终结果是(2,A)(1,B)(3,C)(4,D)。若A,B提前了解了每个人的优先序列,进行欺诈,在第一轮选择(4,A),(3,B),虽然A,B暂时配偶不理想,但是最终结果:(1,A)(2,B)(3,C)(4,D)对于女生而言是最优解。
五、局限
G-S算法的基础,是将数据分为两个集合(数量不一样,就不能依照“单身消失”这一条件结束,而应该判断全部单身男子是否访问完各自的优先序列),由一个集合主动,另一个被动。若集合数>2,就不存在绝对的主动、被动:x选择y,可能y去选择z。例如寝室分配,2n个人分n个寝室,每个人对其他(2n-1)人有喜恶,就不能用G-S算法解决。(想想看,若是在婚配问题上,就是说每个男生的优先序列上除了女生,还混进了(n-1)个男生...)事实上,它本身很可能不存在稳定方案,具体看第一篇文章的倒数第二段。
六、拓展
G-S算法中,后者“S”所表示的Shapley在2012年获得诺贝尔经济学奖,以下是相关介绍,主要研究算法部分。
http://wenku.baidu.com/view/da999a2c4b35eefdc8d33354.html
从第四页的“(二)稳定配置理论”开始(前面的经济术语恶心死了),介绍了两种合作博弈的算法:Gale-Sharpley算法和顶端交易循环算法。其中G-S算法除了“存在性”,“最优性”外,还介绍了“唯一性”:当且仅当男人的最优匹配和女人的最优匹配一致时,稳定条件下只包含唯一解。
G-S算法用于解决“双边市场”的问题(男女各有所需),对于“单边市场”,即只有一侧存在需求(想象一下女生不会拒绝的情况),要用到“顶端交易循环算法”,例2中有详细介绍。(通俗来讲,都用到贪心的思想)
首先明确“单边市场”下的稳定指的是什么:n个人选择n件物品,A选1,B选2,不会同时存在A更喜欢2,B更喜欢1,否则他们就可以交换(交易),即不稳定。
给出算法:首先随意分配n件物品到n个人手中,随意选一个人,找到其优先序列中的第一件物品,观察该物品现在在谁手上,两个人之间构成有向边(纯粹是为了好表达才用有向边描述),重复建边过程,必然会产生一个环,环上的人通过彼此交换物品,可以实现每个人都获得最想要的物品。至此,一轮结束,环上的人及其物品不再考虑,其余人优先序列上去除这些物品。重复操作,直到所有人退出。
为什么能成环就不用解释了,注意如果自己手上拿着的就是最想要的物品,构成自环,同样退出考虑范围。
为什么这样就稳定呢?
沿着算法的思路,第一轮退出的人不存在不稳定的可能,他们拿到了最理想的物品,没有人可以和他们交换。那么对于第一轮留下的全部人而言,第二轮退出的人不存在不稳定的可能,这些人要么拿到最理想的物品,要么拿到次理想的物品(最理想的物品被第一轮的人拿走了),第二轮留下的人不存在与这些人交换的可能。以此类推,方案稳定。
例3、例4、例5都挺有意思,不过我认为真正要注意的不仅仅是分配的方法,还有判断不稳定的条件,什么是真正的公平我们不能一概而论,但如何能在某一方面实现相对公平才是要讨论的。就比如例4中提到的,五家合起来修路,若还不如两家合起来划算,为何还要五家一起。(例4让我又想到了电梯付费,是一个道理)
还有一点疑问,就是文章中“罗斯对NRMP的重新设计,确保已婚医生夫妇也能实现稳定的匹配”。究竟是怎样的?是不是把夫妇二人缩成一个点就可以了?