稳定匹配问题
来源:互联网 发布:mac上打开flac 编辑:程序博客网 时间:2024/06/05 07:52
第一个算法问题:稳定匹配
1962年, David Gale和Lloyd Shapley两人提出一个稳定匹配问题。n个男人和n个女人匹配结婚,每个男人和每个女人都有一个自己的优先表,然后进行如下,算法最后得到一个稳定匹配。
算法的伪码描述:
1、从男人中选出一个自由的且未向所有女人求过婚的m(其实两者限制前面即可),然后m按照他的优先表进行求婚。
2、令w是m可选优先级最高的,然后向她求婚。如果,m目前没有男友,那么(m,w)就约会。如果m有男友m1,则比较m与m1在w得优先表上的排名进行选择。
3、重复1、2直至所有人都已经找到了自己的伴侣。
代码如下:
假设是7男7女的匹配问题。
#include<bits/stdc++.h>
using namespace std;
#define NUM 7
#define IS -1 //如果某女士w单身,IS为-1
bool oldvsnew(int lady[][NUM],int i,int j,int k){//i表示现任,j表示备选
for(int l=0;l<NUM;l++){
if(lady[k][l]==i)
return false; //不换
else if(lady[k][l]==j)
return true; //换
}
}
void pipei(queue<int>&manq,int pos,int man[][NUM],int lady[][NUM],int manc[],int mans[],int ladyi[]){
int ladyper=man[pos][mans[pos]];
if(ladyi[ladyper]==-1){
ladyi[ladyper]=pos;
manc[pos]=ladyper;
}
else{
bool f=oldvsnew(lady,ladyi[ladyper],pos,ladyper);
if(f){
mans[ladyi[ladyper]]++;
manq.push(ladyi[ladyper]);
ladyi[ladyper]=pos;
manc[pos]=ladyper;
}
else{
mans[pos]++;
manq.push(pos);
}
}
}
int main(){
int man[NUM][NUM]={{6,5,3,0,4,1,2},{0,3,6,5,2,4,1},{5,4,2,0,3,1,6},{2,6,4,3,0,1,5},{3,5,4,6,0,2,1},{1,3,5,4,0,2,6},{1,6,5,3,2,0,4}};
int lady[NUM][NUM]={{2,6,4,3,0,1,5},{3,5,4,6,0,2,1},{1,3,5,4,0,2,6},{1,6,5,3,2,0,4},{5,4,2,0,3,1,6},{6,5,3,0,4,1,2},{0,3,6,5,2,4,1}};
int manc[NUM]={0};//记录男士的选择
int mans[NUM]={0};//男士优先表进行到第几位
int ladyi[NUM]={-1,-1,-1,-1,-1,-1,-1};//记录是否单身
queue<int> manq;//还处于单身的男士
for(int i=0;i<NUM;i++)
pipei(manq,i,man,lady,manc,mans,ladyi);
while(!manq.empty()){
int t=manq.front();
manq.pop();
pipei(manq,t,man,lady,manc,mans,ladyi);
}
for(int i=1;i<=NUM;i++)
cout<<"Man"<<i<<"choose"<<manc[i-1]+1<<endl;
return 0;
}
using namespace std;
#define NUM 7
#define IS -1 //如果某女士w单身,IS为-1
bool oldvsnew(int lady[][NUM],int i,int j,int k){//i表示现任,j表示备选
for(int l=0;l<NUM;l++){
if(lady[k][l]==i)
return false; //不换
else if(lady[k][l]==j)
return true; //换
}
}
void pipei(queue<int>&manq,int pos,int man[][NUM],int lady[][NUM],int manc[],int mans[],int ladyi[]){
int ladyper=man[pos][mans[pos]];
if(ladyi[ladyper]==-1){
ladyi[ladyper]=pos;
manc[pos]=ladyper;
}
else{
bool f=oldvsnew(lady,ladyi[ladyper],pos,ladyper);
if(f){
mans[ladyi[ladyper]]++;
manq.push(ladyi[ladyper]);
ladyi[ladyper]=pos;
manc[pos]=ladyper;
}
else{
mans[pos]++;
manq.push(pos);
}
}
}
int main(){
int man[NUM][NUM]={{6,5,3,0,4,1,2},{0,3,6,5,2,4,1},{5,4,2,0,3,1,6},{2,6,4,3,0,1,5},{3,5,4,6,0,2,1},{1,3,5,4,0,2,6},{1,6,5,3,2,0,4}};
int lady[NUM][NUM]={{2,6,4,3,0,1,5},{3,5,4,6,0,2,1},{1,3,5,4,0,2,6},{1,6,5,3,2,0,4},{5,4,2,0,3,1,6},{6,5,3,0,4,1,2},{0,3,6,5,2,4,1}};
int manc[NUM]={0};//记录男士的选择
int mans[NUM]={0};//男士优先表进行到第几位
int ladyi[NUM]={-1,-1,-1,-1,-1,-1,-1};//记录是否单身
queue<int> manq;//还处于单身的男士
for(int i=0;i<NUM;i++)
pipei(manq,i,man,lady,manc,mans,ladyi);
while(!manq.empty()){
int t=manq.front();
manq.pop();
pipei(manq,t,man,lady,manc,mans,ladyi);
}
for(int i=1;i<=NUM;i++)
cout<<"Man"<<i<<"choose"<<manc[i-1]+1<<endl;
return 0;
}
很容易证明其正确性。
1、女人一旦约会就不会再单身,且其选择越来越好
2、男人的选择会越来越差
3、男人单身时一定还有女人没有求过婚(反证法很容易证明)
4、算法最差会在n2时间结束(每一次匹配都会产生的配对是非递减的且最多n2)
5、算法结束后会生成完全匹配,且是稳定的(反证)
算法注意:
无论自由的男人是怎么形式的选择顺序,会产生相同的匹配。(反证)也就是说,无论是用队列还是栈等等储存自由男人结果一样。
算法对女人而言是不公平的,当然也可以从女人选择男人就是对男人不公平。
0 0
- 稳定匹配问题
- 稳定匹配问题
- 稳定匹配问题
- 稳定匹配问题
- 稳定匹配问题
- 稳定匹配问题(一)
- Stable Matching Problem稳定匹配问题-----稳定婚姻算法
- Stable Matching Problem稳定匹配问题-----稳定婚姻算法
- 稳定匹配问题——稳定婚姻算法设计
- 男女稳定匹配问题——贪心
- 稳定匹配问题Stable Match Problem -- 稳定婚姻问题 Stable Marriage Problem
- 稳定婚姻匹配问题 EOJ 162 The Stable Marriage Problem
- 稳定匹配问题与GS算法(单身狗脱单秘籍)
- 稳定婚姻匹配(转)
- poj3487稳定婚姻匹配
- 算法-稳定匹配
- Stable Matching稳定匹配
- COMP2907 W1 稳定匹配
- 20170314,开启菜鸡进化之旅。
- Caffe 网络结构可视化
- JAVA实现大数据量导出excel
- TensorFlow(GPU) 安装
- opengl之glScalef()函数
- 稳定匹配问题
- html5基础
- Xenomai native API
- Linux系统调用------追踪系统调用的执行过程
- 778799
- 九度OJ--1440
- VPN工作原理介绍
- MySQL中针对大数据量常用技术:查询优化,数据转移
- Win10怎么修改hosts