(算法)稳定婚姻匹配

题目:

婚介所登记了N位男孩和N位女孩,每个男孩都对N个女孩的喜欢程度做了排序,每个女孩都对N个男孩的喜欢程度做了排序,你作为月老,能否给出稳定的牵手方案?

稳定的定义:如果男孩i和女孩a牵手,但男孩i对女孩b更喜欢,而女孩b的男朋友j拼不过男孩i,则没有力量阻碍男孩i和女孩b的私奔,这即是不稳定的。

思路:

1962 年,美国数学家 David Gale 和 Lloyd Shapley 发明了一种寻找稳定婚姻的策略。不管男女各有多少人,不管他们各自的偏好如何,应用这种策略后总能得到一个稳定的婚姻搭配。换句话说,他们证明了稳定的婚姻搭配总是存在的。有趣的是,这种策略反映了现实生活中的很多真实情况。

算法中采用了男生主动追求女孩的形式。

算法步骤描述:

第一轮,每个男人都选择自己名单上排在首位的女人,并向她表白。这种时候会出现两种情况:

 (1)该女士还没有被男生追求过,则该女士接受该男生的请求。

 (2)若该女生已经接受过其他男生的追求,那么该女生会将该男士与她的现任男友进行比较,若更喜欢她的男友,那么拒绝这个人的追求,否则,抛弃其男友

第一轮结束后,有些男人已经有女朋友了,有些男人仍然是单身。

在第二轮追女行动中,每个单身男都从所有还没拒绝过他的女孩中选出自己最中意的那一个,并向她表白,不管她现在是否是单身。这种时候还是会遇到上面所说的两种情况,还是同样的解决方案。直到所有人都不再是单身。

怎么证明这个算法肯定能够得到稳定的婚姻?

(1)随着轮数的增加,总有一个时候所有人都能配上对。因为男生根据自己心目中的排名依次对女士进行表白,假如有一个人没有配上对,那么这个人必定是向所有的女孩进行表白了。但是女孩只要被表白过一次,就不可能是单身,也就是说此时所有的女生都不是单身的,这与有一个人没有配上对是相悖的。所以假设不成立。该算法一定会使得所有人都能够配对成功。

(2)随着轮数的增加,男士追求的对象越来越糟,而女士的男友则可能变得越来越好。假设男A和女1各有各自的对象,但是比起现在的对象,男A更喜欢女1,所以,在此之前男A肯定已经跟女1表白过的,并且女1拒绝了男A,也就是女1有了比男A更好的男友,不会出现私奔的情况……。

代码:

#include<iostream>
using namespace std;

const int N=4;

void GaleShapley(const int (&man)[N][N],const int (&woman)[N][N],int (&match)[N]){
    int wm[N][N];    // wm[i][j]: rank from girl i to boy j
    int choose[N];    // choose[i]: current boyfriend of girl i
    int manIndex[N]; //    manIndex[i]: how many girls that have rejected boy i
    int i,j;
    int w,m;
    for(i=0;i<N;i++){
        match[i]=-1;
        choose[i]=-1;
        manIndex[i]=0;
        for(j=0;j<N;j++)
            wm[i][woman[i][j]]=j;
    }

    bool bSingle=false;
    while(!bSingle){
        bSingle=true;
        for(i=0;i<N;i++){
            if(match[i]!=-1) // boy i already have a girlfriend
                continue;
            bSingle=false;
            j=manIndex[i]++; // the jth girl that boy i like most
            w=man[i][j];
            m=choose[w];    // current girl w‘s boyfriend
            if(m==-1 || wm[w][i]<wm[w][m]){ // if girl w prefer boy i
                match[i]=w;
                choose[w]=i;
                if(m!=-1)
                    match[m]=-1;
            }
        }
    }
}

void Print(const int (&match)[N],int N){
    for(int i=0;i<N;i++)
        cout<<"Boy "<<i<<" matches "<<"Girl "<<match[i]<<endl;
    cout<<endl;
}

int main(){
    int man[N][N]={
        {2,3,1,0},
        {2,1,3,0},
        {0,2,3,1},
        {1,3,2,0},
    };
    int woman[N][N]={
        {0,3,2,1},
        {0,1,2,3},
        {0,2,3,1},
        {1,0,3,2},
    };

    int match[N];
    GaleShapley(man,woman,match);
    Print(match,N);

    return 0;
}
时间: 2024-12-21 23:09:49

(算法)稳定婚姻匹配的相关文章

简单的稳定婚姻匹配

一.相关的定义 1.有一个男士集合和一个女士集合.每个男士都有一个优先级列表,把女士按潜在结婚对象进行优先级排序. 同样的,女士也有一个对潜在结婚对象的优先级列表. 婚姻匹配: 一个婚姻匹配M是一个包含n个(m,w)对的集合,每一对的成员都按照一对一的模式从两个不相交的n元素集合Y和X中选出.也就是说,Y中的每个男士m都只和X中的一位女士w配对,反正亦然.相当于一个二分图中,边来连接可能结婚的对象,两边的顶点代表X和Y,婚姻匹配也是图中的一个完美匹配. 婚姻的稳定:如果在匹配M中,,男士m和女士

HDU 1522 Marriage is Stable 【稳定婚姻匹配】(模板题)

<题目链接> 题目大意: 给你N个男生和N个女生,并且给出所有男生和女生对其它所有异性的喜欢程度,喜欢程度越高的两个异性越容易配对,现在求出它们之间的稳定匹配. 解题分析: 稳定婚姻问题的模板题,需要用到Gale_Shapley算法,GS算法讲解  >>> 这个算法还是很直观的. 1 #include <iostream> 2 #include <cstring> 3 #include <stack> 4 #include <stri

HDU1914 稳定婚姻匹配

The Stable Marriage Problem Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 758    Accepted Submission(s): 389 Problem Description The stable marriage problem consists of matching members of two

稳定婚姻匹配问题

一.问题 有N男N女,每个人都按照他对异性的喜欢程度排名.现在需要写出一个算法安排这N个男的.N个女的结婚,要求两个人的婚姻应该是稳定的. 何为稳定? 有两对夫妻M1 F2,M2 F1.M1心目中更喜欢F1,但是他和F2结婚了,M2心目中更喜欢F2,但是命运却让他和F1结婚了,显然这样的婚姻是不稳定的, 随时都可能发生M1和F1私奔或者M2和F2私奔的情况.所以在做出匹配选择的时候(也就是结婚的时候),我们需要做出稳定的选择,以防这种情况的发生. 二.算法步骤描述: 第一轮,每个男人都选择自己名

稳定婚姻问题和Gale-Shapley算法(转)

什么是算法?每当有人问作者这样的问题时,他总会引用这个例子:假如你是一个媒人,有若干个单身男子登门求助,还有同样多的单身女子也前来征婚.如果你已经知道这些女孩儿在每个男孩儿心目中的排名,以及男孩儿们在每个女孩儿心中的排名,你应该怎样为他们牵线配对呢? 最好的配对方案当然是,每个人的另一半正好都是自己的“第一选择”.这虽然很完美,但绝大多数情况下都不可能实现.比方说,男1号最喜欢的是女1号,而女1号的最爱不是男1号,这两个人的最佳选择就不可能被同时满足.如果好几个男孩儿最喜欢的都是同一个女孩儿,这

UVA 1175 Ladies&#39; Choice 女士的选择(稳定婚姻问题,GS算法)

题意: 给出每个男的心目中的女神排序,给出每个女的心目中的男神排序,即两个n*n的矩阵,一旦任意两个非舞伴的男女同学觉得对方都比现任舞伴要好,他们就会抛弃舞伴而在一起.为了杜绝这种现象,求每个男的最后所搭配的女伴是谁. 思路: 怎么感觉题意有点问题,输出的是第i行的男人所搭配的女人,即输出的是女人! 每个男人依次选择最喜欢的女人求婚,若同一个女的没人抢,则临时抢亲成功,若需要抢,明显女的都是喜欢挑长腿oba啦,矮冬瓜自动加入单身狗队列继续求婚!当单身狗所求的女神已订婚,只要女神更爱单身狗,没有什

UVA 1175 - Ladies&#39; Choice(稳定婚姻问题)

UVA 1175 - Ladies' Choice 题目链接 题意:给定n个男人,n个女人,每个人心中对异性都有一个排序,从左往右是最喜欢到最不喜欢,然后现在要求一个稳定匹配,使得n对男女中,不存在男人对其他女人好感度大于配偶且女人对其他男人好感度大于配偶 思路:稳定婚姻问题,算法过程如下: 男人不断求婚,从最喜欢到最不喜欢,女人每次在求婚人中,选择一个最喜欢的配对,然后抛弃现在的配对,这个过程可以用一个队列存放求婚男人,这样直到队列为空,也就匹配完毕了 代码: #include <cstdio

UOJ.41.[清华集训2014]矩阵变换(稳定婚姻)

题目链接 稳定婚姻问题:有n个男生n个女生,每个男/女生对每个女/男生有一个不同的喜爱程度.给每个人选择配偶. 若不存在 x,y未匹配,且x喜欢y胜过喜欢x当前的配偶,y喜欢x也胜过y当前的配偶 的完备匹配,则称这是一个稳定匹配. 稳定匹配一定存在,且存在一个\(O(n^2)\)的算法: 任选一个未匹配的男生x,按x的喜爱程度从大到小枚举每个女生,若当前女生没有配偶或喜欢x胜过喜欢当前配偶,则与x匹配.直到所有男生都匹配. 这一题我们用行表示男生,n个数表示女生.喜爱程度为:行更喜欢靠前的数,数

【bzoj2140】: 稳定婚姻 图论-tarjan

[bzoj2140]: 稳定婚姻 哎..都是模板题.. 一眼看过去 哇 二分图哎 然后发现好像并不能匈牙利算法 自己xjb画两张图,发现二分图左向右连配偶的边,然后右向左连交往过的边 然后如果Bi Gi在同一个强连通分量里面就一定可以在Bi Gi离婚以后再增广一次 最开始用map维护一下名字就好了 1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include &l