男女稳定匹配问题——贪心
今天上课研究生学长讲了一个问题,男女稳定匹配问题,作为一只单身狗觉得这个问题很有意思,下课就试着自己写了下代码。
现有n个男生与n个女生,一男一女配对,要求:
配对的男生与女生互相都是称心的、中意的,且配偶中任一个人都不能有其他彼此更中意的异性。即若给定(A,B)和(C,D)分别是两对配偶,若A和D彼此的喜欢程度都大于自己的配偶(A对D的喜欢程度胜于对B,并且D对A的喜欢程度也胜于对C,这样就会出现A与D私奔的情况),这样是不存在的,也就是说,除了自己的配偶之外,没有更适合的人了。
选择方式:
男生选择自己喜欢的女生并向其告白(有可能多个男生对一个女),女生从对自己告白的男生里面挑选自己最中意的男生作为配偶,被拒绝的男生对其他(排除拒绝自己的女生)女生按照喜欢度排序,并向最喜欢的那个女生告白,所有女生从对自己告白的男生里面挑出最喜欢的一位作为配偶(包括上一步已经选过男生的女生,女生选择时也要考虑上一个选择的男生的喜欢程度是否高于这一次对自己告白的男生)。循环上面的步骤,直到所有男生与女生都配对成功。
这样说比较绕口,用图解描述一下吧。
假设现在有3个男生(A,B,C)与3个女生(1,2,3)。
喜欢程度排序:
第一次男生选取时,挑选自己最中意的女生,A—2, B—1, C—1, 向女生告白。
女生从这些向自己告白的男生中选取自己喜欢程度较高的男生,1—C, 2—A,1女生有两个男生向其告白(B和C),而1女生更喜欢C,所以选择C男生。
B男生被拒绝,在自己的喜欢程度排序中将1排除。
第二次男生选取,A与C已经被选,只剩下B男生,B选择2(因为1女生已经拒绝了B,所以排除1之后最中意的女生是2)。女生2原来选择的B男生,但是在A和B之间,女生更喜欢B,所以拒绝A,选择B。
男生A伤心地从排序中删除了2。
第三次选取,只剩下A还没有配偶,A按照排序选择3,3没有更多的选择,就与A作为配偶。
这样就完成了选取步骤。
可见该步骤是以男生为主体,按照男生的排序做选择,而女生按照排序从某几个男生中挑选。也就是说,在选择时,男生是主动的,女生是被动的,男生可以按照自己喜欢的程度挑选女生,而女生可能会挑选到排序末位的男生。从上面的结果可以看到,女生3的配偶A在排序中是最后一位。
所以说,这样的选择方式男生比较有益。
说是通过这种方法得到的匹配结果是稳定的,即配偶中不会出现私奔情况。确实也是这样,女生3最喜欢男生C,但是男生C根本不会搭理女生3,因为排在了末尾,同理B。
以下是伪代码
while(男生还有自由的,没有配偶的)
{//男生boy,中意女生girl;if(girl没有配偶){W与m配对;M设为不自由}else{ //女生girl的现任配偶是boy’if(boy’比boy喜欢程度强){boy的排序中删除女生girl;}else{boy与girl配对;boy’设为自由,从排序中删除女生girl;}}
}
光说没有用,写了下代码。
给男生和女生分别设立结构体,
struct BOYS
{int Blike[10]; //喜欢程度排序,女生的下标int free; //是否已经有配偶,是否是自由的int point; //排序中作为下标,指示男生目前最中意的人int soul; //男生配偶的下标
};struct GIRLS
{int Glike[10];int soul; //女生配偶的下标
};
那么伪代码可以进行修改:
for(int i 所有男生)
{if(男生[i].free==0)Continue;//男生中意女生valueif(女生[value].soul==0){男生[i].soul=value;女生[value].soul=i;男生[i].free=0;}else{ //女生现任配偶与现在告白男生i之间做比较//a==1说明现任男友排前,0则告白男生排前int a = compared(女生[value].soul, i, value);if(a==1){男生[i].point++; //指向下一个中意女生}else if(a==0){//更新前任值男生[女生[value].soul].free=1; 男生[女生[value].soul].point++;//男生i与女生value配偶男生[i].soul=value;女生[value].soul=i;男生[i].free=0;}}
}
配对的核心代码
void couple()
{for(int i=1;i<=n;i++){if(boys[i].free==0) continue;int value = boys[i].Blike[boys[i].point];if(girls[value].soul==0){boys[i].soul=value;boys[i].free=0;girls[value].soul=i;//printf("%d %d\n",i,boys[i].soul);}else{int a = Compared(girls[value].soul,i,value); //1,0if(a==1){boys[i].point++;}else if(a==0){//更新前男友值boys[girls[value].soul].free=1;boys[girls[value].soul].point++;//printf("boy soul from %d %d",girls[value].soul,value);//配对boys[i].soul=value;girls[value].soul=i;boys[i].free=0;//printf(" to %d %d\n",i,boys[i].soul);}}}
}
Compared函数代码
int Compared(int a,int b,int value) //比较男生a和b哪一个在排序中靠前
{int i;for(i=1;i<=n;i++){if(girls[value].Glike[i]==a)return 1;if(girls[value].Glike[i]==b)return 0;}return -1;
}
假设现有6个男生6个女生,先输入每个男生的喜欢程度排序,再输入每个女生的。
6
2 6 5 1 3 4
3 6 5 1 2 4
4 5 3 2 1 6
1 2 3 4 6 5
3 2 1 6 5 4
2 3 1 5 6 4
2 1 3 5 6 4
4 3 2 6 5 1
3 4 1 5 6 2
6 5 4 3 2 1
4 6 1 3 5 2
1 3 4 6 2 5
最终配对结果:1—6, 2—5, 3—4, 4—1, 5—3, 6—2 (先男生后女生)
男女稳定匹配问题——贪心相关推荐
- 男女稳定匹配问题 stable matching
离散数学课(CSCI 2110)上,讲到一个有趣的问题. 假设有五个男生,五个女生,每个人都在自己心中对五个异性有一定的preference排序,比如: 以上的排序表解读为:男生1最中意女生C,次中意 ...
- 稳定匹配 5分钟看懂GS算法 附有常考常见例题及解析
文章目录 Stable Match 稳定匹配(GS算法) 1. 什么是稳定匹配 2. 为什么叫做稳定匹配 3. 稳定匹配的基本思想 4. 算法的伪代码 5. 为什么这个算法可以产生一个稳定的匹配? 1 ...
- 稳定伴侣问题c语言步骤,稳定匹配问题
这是 Algorithm Design 一书开篇介绍的一个很有意思的问题 问题描述 有n个男人和n个女人(n>=2),每个男人对所有女人有一个好感度排名,每个女人对所有男人也有一个好感度排名.将 ...
- 稳定匹配问题(脱单就靠这波了)
稳定匹配问题之三国 首先,我们先看看问题: 有n个男人和n个女人(n>=2),每个男人对所有女人有一个好感度排名,每个女人对所有男人也有一个好感度排名.将男女两两配对,得到n对男女,称之为一个完 ...
- 稳定匹配问题——稳定婚姻算法设计
图片源自:美剧<How I met your mother> **** 本代码带有详细的注释,并在控制台输出时详细地说明了算法的过程,非常有助于新手理解稳定匹配问题和稳定婚姻算法的设计思路 ...
- 稳定匹配婚姻 c++版GS算法
问题描述 给出一个 n 个男性的集合 M和 n 个女性的集合 W,找到一个"稳定"匹配. 每位男性根据对女性的心仪程度从高至低进行排名: 每位女性根据对男性的心仪程度从高至低进行排 ...
- 稳定匹配(解决婚姻问题)
婚姻问题 现在有N位男生和N位女生,每个男生都对N个女生的喜欢程度做了排序,每个女生都对N个男生的喜欢程度做了排序,现在需要确定一个稳定的约会状态. 稳定的定义:如果男生i和女生a牵手,但男生i对女生 ...
- 2017蓝桥杯 对局匹配(贪心)
历届试题 对局匹配 时间限制:1.0s 内存限制:256.0MB 问题描述 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在 ...
- 【蓝桥杯】历届试题 对局匹配(贪心)
历届试题 对局匹配 问题描述 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配 ...
最新文章
- Linux上实现ssh免密码登陆远程服务器
- linux 脚本 lang,golang可以编写shell脚本吗
- 必须重视数据中心的规划设计
- 關於BigDecimal的比較
- 如何在OpenJDK中使用ECC
- 第十章触发器的创建与管理
- Speed Reading(POJ-3619 )
- 战队不显示名字了_年仅17岁的新人选手!峡谷之巅1200分!被16家战队哄抢
- python mobilenetssd android_MobileNetV2-SSDLite运行
- string类型的数字字符串直接转换成int型方法
- 机器学习经典损失函数复习:交叉熵(Cross Entropy)和KL散度
- Python高级特性:Python迭代、生成器、列表生成式
- 手动剿灭Word宏病毒
- HFSS - 半波偶极子天线的设计与仿真
- jQuery添加、删除元素
- win10改计算机用户名,简单几步解决win10电脑用户名改不了的问题
- 【高级篇 / SDWAN】(7.0) ❀ 08. 访问指定网站最快的宽带优先上网 ❀ FortiGate 防火墙
- 关于倾斜摄影测量技术,你了解多少?
- 复习C语言随笔 十四
- 从外包辞职10000小时后,我走进了字节跳动····
热门文章
- MySQL的explain analyze增强功能
- MultipartFile上传图片
- LeetCode 452 射气球问题
- 医学图像分割 基于深度学习的肝脏肿瘤分割 实战(一)
- 10461: 整理抽屉
- 室内定位解决方案的应用及原理,室内定位方案技术精湛-新导智能
- python接口自动化11-流量回放神器:mitmproxy(上)
- 学术不端网查重靠谱吗_学术不端网安全吗?查重过程是怎样的?
- java 读取文件 效率_Java 逐行读取文本文件的几种方式以及效率对比
- Java根据txt文件数据得到list_java中如何将一个txt文件中的数字读取到一个ArrayList集合中?...