博客
关于我
婚姻稳定匹配问题
阅读量:346 次
发布时间:2019-03-04

本文共 5669 字,大约阅读时间需要 18 分钟。

婚姻稳定匹配问题

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

算法

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对情况下的,无论增加为多少对,在系统可承受范围内都可实现。
在这里插入图片描述在这里插入图片描述

你可能感兴趣的文章
Edge浏览器:你的的内核我的芯
查看>>
git命令升级版用法
查看>>
sed常用命令
查看>>
checksec未完待续~
查看>>
python pexpect
查看>>
inode索引节点的概念
查看>>
create-react-app第一步
查看>>
testng测试工具简介
查看>>
怎么去利用已有的数据做分析?
查看>>
某易游戏经典吃豆豆动画404页面源码
查看>>
专升本——英语视频学习
查看>>
Future education software
查看>>
不知道考研各科课程那个老师的课好?怎么选择安排?在哪找课程课本资料?看这里
查看>>
考研高数一_高数二_高数三考试大纲
查看>>
【考研高数-高等数学-基础】第四章 不定积分
查看>>
【考研英语-基础-简单句】简单句的核心变化_谓语情态
查看>>
17级软件技术二班刘鑫磊安卓学期总结
查看>>
配置Log4j详细版
查看>>
数据结构 第五章 二叉树-1
查看>>
[Easy] 58. Length of Last Word
查看>>