婚姻稳定匹配问题

婚姻稳定匹配问题

通过算法实现,有小小的设计以便程序更加有趣,与大家分享但是请大家尊重代码中的设计,如需转载请务必声明原创,谢谢。

算法

GS稳定匹配算法

稳定婚姻匹配问题可以由GS稳定匹配算法(盖尔-沙普利算法)来解决。
GS稳定匹配算法也称作“延迟接受算法”,是美国数学家David Gale和Lloyd Shapley在1962年提出的寻找稳定婚姻的一种方法。

特点

算法的特点在于,只要男士和女士人数相等,并且心中都有自己的排名情况,无论需要配对的总人数多少,都可以得到一个稳定的婚姻。

问题描述

婚介中心登记了N位男士与N位女士的信息,每位男士按照他对女士的喜爱程度做了排名,每位女士按照她对男士的喜爱程度做了排名。我们将男士和女士进行配对,使得最后每一对的婚姻都是稳定的。
在这里插入图片描述
稳定的含义

稳定的含义:
如果男生1更喜欢女生2,但是他和女生1结婚了。同时男生2更喜欢女生1,但是他和女生2结婚了,这样的婚姻是不稳定的,会出现男生1和女生2或男生2和女生1私奔的情况。

主要步骤

主要思路就是使男士先拥有主动权,优先追求心中排位第一的女士。
在判断女士是否已经有对象之后,如果没有,女士就先接受男士,两人配对成功。如果该女士有对象就判断其现任与追求者在女士心中的排位,如果现任较高,则男士被拒绝需要再次追求心中排位第二的女士并重复以上过程。如果追求者排位较高,则女士和现任分手,与追求者配对。现任恢复单身并再次追求心中下一排位女士,同样重复以上过程。
直至所有男士女士配对成功,循环结束,任务完成即已达到稳定匹配。

#include <stdio.h> 
#include <iostream>
using namespace std;
bool finish_or_not(int, int *);
bool current_male_is_better(int num, int *male_rank_in_female, int current, int chasing);
int main(){
	printf("\n");
	printf("┌——————幸福的开端——————-┐\n");
	printf("     欢迎来到“量身定做”婚介中心\n"); 
	printf("      千里姻缘一线牵,珍惜这段缘\n"); 
    printf("│                                   │\n");
    printf("└—————————————————-┘\n");
    printf("\n");
	int num = 2;int i,j;
	//有几对需要配对
	printf("请输入需要配对的对数:");
	scanf("%d",&num);
	int female_rank_in_male[num][num];//女士在男士心中的排位 
	int male_rank_in_female[num][num];//男士在女士心中的排位 
	for (int i = 0; i < num; i++){
   		printf("男士%d心中的女士排行:",i+1); 
       for (int j = 0; j < num; j++){
       		scanf("%d",&female_rank_in_male[i][j]);
       }
    }
    for (int i = 0; i < num; i++){
   		printf("女士%d心中的男士排行:",i+1); 
        for (int j = 0; j < num; j++){
        	scanf("%d",& male_rank_in_female[i][j]);
       }
    }
    //测试数组 
  // int female_rank_in_male[5][5] = { { 2, 1, 4, 5, 3 }, { 4, 2, 1, 3, 5 }, { 2, 5, 3, 4, 1 }, { 1, 4, 3, 2, 5 }, { 2, 4, 1, 5, 3 } };
   //int male_rank_in_female[5][5] = { { 5, 1, 2, 4, 3 }, { 3, 2, 4, 1, 5 }, { 2, 3, 4, 5, 1 }, { 1, 5, 4, 3, 2 }, { 4, 2, 5, 3, 1 } };
   //男士和女士目前已配对的对象
   int *date_of_male = new int[num];
   int *date_of_female = new int[num];
   for (int i = 0; i < num; i++){
       date_of_male[i] = 0;
       date_of_female[i] = 0;
   }
   //男士追求过的女士的数量
   int *num_of_chased_female = new int[num];
   for (int i = 0; i < num; i++){
       num_of_chased_female[i] = 0;
   }
   do{//如果有男士没有对象
       for (int i = 0; i < num; i++){//按序号遍历所有男士 
      		printf("检查男士%d是否有对象\n",i+1);
           if (date_of_male[i] == 0){//如果某男士没有对象
           		printf("男士%d没有对象,可追求心仪的女士!\n",i+1); 
               //该男士准备追求的女士(该男士优先表中还没追求过的排名最高的女士)
               int female_to_chase = female_rank_in_male[i][num_of_chased_female[i]];
               //判断该男士准备追求的女士是否有现任
               int date_of_female_to_chase = date_of_female[female_to_chase - 1];
               printf("男士%d准备追女士%d\n",i+1,female_to_chase);
               if (date_of_female_to_chase != 0){
               		printf("女士的现任是%d\n", date_of_female_to_chase );
               }
               else{
               		printf("女士现在是单身哦~\n"); 
               }
               if (date_of_female_to_chase == 0){//如果该男士准备追求的女士没有现任
                   date_of_male[i] = female_to_chase;//该男士的对象变成准备追求的女士 
                   date_of_female[female_to_chase - 1] = i + 1;//女士的对象变成该男士 
                   printf("这样子的话,男士%d和女士%d在一起咯!\n",i+1,female_to_chase);
               }
			   //如果该男士准备追求的女士的现任在女士心目中比该男士更好,则什么也不做 
               else if (current_male_is_better(num, male_rank_in_female[female_to_chase - 1], date_of_female_to_chase, i + 1)){  
                   printf("所以!男士 %d 被女士 %d拒绝了!\n" ,i+1,female_to_chase);
               }
               else{//如果该男士比该男士准备追求的女士的现任在妹子心目中更好
                   date_of_male[date_of_female_to_chase - 1] = 0;//该男士准备追求的女士的现任回到单身状态
                   date_of_male[i] = female_to_chase;//该男士的对象变成准备追求的女士 
                   date_of_female[female_to_chase - 1] = i + 1;//女士的对象变成该男士
                   printf("所以,男生%d和妹子%d在一起了!\n",i+1,female_to_chase);
                   printf("与此同时,不幸的是,男生 %d 变成单身狗了~~~\n",date_of_female_to_chase); 
               }

               num_of_chased_female[i]++;//该男生追求过的妹子数量加1
                }
           else{
           		printf("男士%d已经跟女士%d在一起了呢~~下一个吧~~~\n",i+1,date_of_male[i]);
           }
       }
   } while (finish_or_not(num, date_of_male) == false);
   printf("\n");
   printf("┌——————幸福的结局——————-┐\n");
   printf("│                                   │\n");
   for (int i=0; i<num;i++){
   		printf("            男士%d - 女士%d       \n",i+1,date_of_male[i]);
   }
   printf("│                                   │\n");
   printf("└—————————————————-┘\n");
   delete[] date_of_male;
   delete[] date_of_female;
   delete[] num_of_chased_female;
   system("pause");//清空缓存 
   return 0;
}
bool finish_or_not(int num, int *date_of_male){

   for (int i = 0; i < num; i++){
       if (date_of_male[i] == 0){//判断是否全部完成配对 
       	printf("还有单身狗......再来~~\n");
           return false;
       }
   }
   printf("耶!稳定配对完成!已全部脱离单身狗行列!!!\n");
   return true;
}
//比较某女士现在的对象和追求者哪个在她心目中排行更高
//数组参数是一维(是一位女士的优先表而不是所有女士的优先表)
bool current_male_is_better(int num, int *male_rank_in_female, int current, int chasing){
   int rank_of_current, rank_of_chasing;//现任排行与追求者排行 
   for (int i = 0; i < num; i++){
       if (male_rank_in_female[i] == current){
           rank_of_current = i+1;
       }
       if (male_rank_in_female[i] == chasing){
           rank_of_chasing = i+1;
       }
   }
   printf("在女士心目中现任排名是: %d,而追求者排名则是: %d\n",rank_of_current,rank_of_chasing);
   if (rank_of_current < rank_of_chasing)
       return true;
   else
       return false;
}

测试

简单最优完全配对测试

如果恰巧男士i的首选为女士i;女士i的首选为男士i,则属于最优情况,即完全配对。
在这里插入图片描述
简单不完全配对测试

测试目的为检验整个算法的每个步骤是否出错,即最初不是最优,则需要判断被追求女士的现任与追求者的排位并进行被淘汰的那个男士再次追求心中下一排行的女士。由于只有两对,因此较为简单。
在这里插入图片描述
复杂不完全配对测试

在对数比较少的简单测试之后,增加对数,提升复杂性。以下展示的为5对情况下的,无论增加为多少对,在系统可承受范围内都可实现。
在这里插入图片描述在这里插入图片描述

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值