婚姻匹配问题

本文介绍了盖尔-沙普利算法,用于寻找稳定的婚姻匹配。每个参与者根据好感度对异性进行排序,算法通过多轮匹配确保没有受阻对存在。男士首先发起表白,女士在现有和新追求者中选择更喜欢的一方。最终实现所有人稳定配对的婚姻状态。
摘要由CSDN通过智能技术生成

婚姻匹配问题


前言

盖尔-沙普利算法(Gale-Shapley)
简称“GS算法”,也称为延迟接受算法。是盖尔和沙普利为了寻找一个稳定匹配而设计出的市场机制。


一、问题描述

一共有N位男士和N位女士,每个人都要选择结婚对象。如果有两对夫妻M1 F2,M2 F1。M1心目中更喜欢F1,但是他和F2结婚了,M2心目中更喜欢F2,但是命运却让他和F1结婚了,显然这样的婚姻是不稳定的。根据个人对异性的排名情况匹配对象,使得每对情侣在结婚后婚姻状况稳定,从而保证不会出现出轨的状况。

二、算法思路

1.匹配模式

一个婚姻匹配M是一个包含n个(m, w)对的集合,每一对的成员都按照一对一的模式从两个不相交的n元素集合Y和X中选出。
也就是说, Y中的每个男士m都只和X中的一位女士w配对,反正亦然。如果在匹配M中,男士m和女士w没有匹配,但他们都更倾向对方,而不是M中彼此的伴侣,那么(m, w)称为受阻对,如果婚姻匹配存在受阻对,那么我们说婚姻是不稳定的,如果不存在,则婚姻是稳定的。

2.匹配流程

男女双方根据好感度排序:
1)第一轮
每个男士选择排名首位的女性并向她表白。
此时女士可能有三种情况:① 没有人向她表白;② 只有一个人向她表白 ③ 不止有一个人向她表白
在情况 ① 下,女士等待下一轮
在情况 ② 下,接受追求者表白,暂时达成恋爱关系
在情况 ③ 下,按照好感度排名选择追求者最,并暂时和他在一起
第一轮结束后,仍有男士单身。
2)第二轮
单身的男士从还没拒绝过自己的女士中按照好感度做出选择,不管她是否单身。
与第一轮相同,女士们需要选出自己最中意的那个,并达成恋爱关系。如果这个女士已经有男朋友了,当她遇到了更好的追求者时拒绝掉现在的男友,选择新的追求者。
此时,那些已经有了女友的人可能重新单身。
3)以后的每一轮
以第一、二轮为例,在以后的每一轮,单身男士继续追求其列表中的下一个女士,女士则从包括现男友在内的所有追求者中选择最好的一个。

这样一轮一轮的继续下去,直到某个时候所有人都不再单身,下一轮将不会再有新的表白发生。

三、关键代码

代码如下(示例):

int boyper[num][num];//定义一个数组存放女生在男生心中的排位 
	int girlper[num][num];//定义一个数组存放男生在女生心中的排位 
	for (int i = 0; i < num; i++){
   		printf("男生%d心中的女生排行:",i+1); 
       for (int j = 0; j < num; j++){
       		scanf("%d",&boyper[i][j]);
       }
    }
    for (int i = 0; i < num; i++){
   		printf("女生%d心中的男生排行:",i+1); 
        for (int j = 0; j < num; j++){
        	scanf("%d",&girlper[i][j]);
       }
    }


    while(finish_or_not(num, boygf)==false){//有男生存在没对象 
       for (int i=0;i<num;i++){//按序号遍历所有男生看看谁没有 
           if (boygf[i]==0){//如果某男士没有对象
           		printf("男生%d没有对象,可追求女生!\n",i+1); 
              //优先追求偏好高的女生 
               int boychase = boyper[i][boyml[i]];//存储当前男生还未追求的最高偏好女性的号即是哪个女生 (boychase)
               //判断这个女生有没有现任 
               int boychasebf = girlbf[boychase-1];//存储当前追求的女士的对象(boychasebf)(号)    数组位置=号-1 (boychase-1)
               printf("男生%d准备追偏好的女生%d\n",i+1,boychase);//i+1号 
               if (boychasebf!=0){//如果为0就是没男朋友为其他数字就是男朋友是哪个 
               		printf("被追求女生的现任是%d\n", boychasebf);
               		//判断是否稳定 
               if (current_male_is_better(num, girlper[boychase-1],boychasebf, i+1)){ //数组,被追求的女性的偏好,当前对象,追求男的号 
                   printf("被追求女生更喜欢现任!\n");//false 
               }
               else{//如果该男生比该男生准备追求的女士的现任在心目中更好 ture
                   boygf[boychasebf-1]=0;//女孩现任变成单身 
                   boygf[i] =boychase;//该男士的对象变成准备追求的女士 
                  girlbf[boychase-1]=i+1;//女士的对象变成该男士
                   printf("男生%d横刀夺爱和女生%d在一起了!\n",i+1,boychase);
               }
			   }
               else{
               		printf("被追求的女生是单身\n"); 
                  boygf[i] =boychase;//该男士的对象变成准备追求的女士 
                  girlbf[boychase-1]=i+1;//女士的对象变成该男士
                    printf("男生%d和女生%d在一起了!\n",i+1,boychase);
               }
              boyml[i]++;//该男生的偏好移动,这个女生已经追过 
                }
           }
       }


总结

在本次实验中,while循环和for嵌套,先插入了一个索引用来存放男性女性所对应各自心中的排名矩阵,然后从第一个位置开始逐个选取对象,并记录男士(女士)各自的选取过的索引,将未选取过的索引项即没有匹配的人放入队列中,以便于利用for循环进行遍历队列,在while循环中遍历索引,为男士选取未匹配的女士,否则便在女性中选取最优的男性与之配对,则男士也成为了未匹配人选,如此反复对比进行循环匹配。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值