数字化婚姻配对尝试问题(C++实现)
问题描述:
一、标题:
数字化婚姻配对尝试
二、题目:
建立一个模型,来模拟推导社会男女择偶过程。
为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值1-100之间任意数字。同样也对这3项指标有自己的需求。这3个需求值取值范围都在1-98间,当然三者的和必须为100.所以任意一个人可以用以下数组来表述:
G(A、B、C、A1、B1、C1)G代表男,M代表女。
举例G11(80、50、40、10、30、60),表示男11号,拥有财富80、样貌50、品格40,对异性品格的偏好为:财富在乎程度百分之10、样貌在乎程度百分之30、品格在乎程度百分之60。
同样为了模型简化,假设信息是完全对称的,即是说,每个人都能一眼就能看清楚任意一个人的财富、样貌、品格。
还是为了模型简化,我建模所用样本为男女各100个,即男女人数相同。
每个人对异性的满意度将如下定义:每个偏好指标与异性的对应的禀赋指标相乘,三个指标的乘积再相加,即他(她)对某个异性的满意度。
举例G11(80、50、40、10、30、60)对M(50、60、80、40、10、50)的满意度为:
(10*50+30*60+60*80)= 7100分
相对的 MM 对 GG的满意度则为:
(40*80+10*50+50*40) = 5700分
好了,配对活动开始,设计的配对法则如下:
1、100个男方,顺序,轮流从0号到99号女方中挑选自己最满意的一位,然后向她发出配对邀请。
2、接受邀请最多的女方开始行动,对这些邀请的男性中,选择最满意的一位。
3、那么这两位配对成功,剔除出样本,剩下的99对继续这样配对。
4、循环该配对法则,直到最后一对男女配对成功。
在匹配时,如果发现有多个满意度相同的对象,要求自身三个属性(财富,外貌,品格)总和大的优先,如果再相同则id小的优先。如果有2位女士的选票相同,优先级规则同上。请把主角的id置为最小值,以便在前2个条件相同情况下,主角可以优先选择。
附件中,male.txt,female.txt,players.txt 分别是男士样本、女士样本和主角样本各 100位。 男女样本中,每行都代表一位男士或女士的基本属性,从左到右依次是ID, 样貌,品格,财富 , 期望样貌,期望品格,期望财富,没有加入性别,需要在解析时手动添加,每个txt文本的性别都是一样的,请注意。另外,主角样本中没有ID属性,换成了性别属性,其中 0表示女性,1表示男性,其余属性依次为样貌,品格,财富,期望样貌 ,期望品格,期望财富。建议把主角的id都设置为 -1,以便满足优先选择的条件。
设计思路:
1、设计一个个体基类(Person),其包含属性(ID, 样貌,品格,财富 , 期望样貌,期望品格,期望财富);
2、基类基础上派生出男士类(Male)、女士类(Female)和主角类(Players),主角类中需要增加属性性别(msex)并设计一个配对类(Pairing),该类中封装了此问题的核心配对操作;
3、从文件中依次读取数据,放入相应的vector容器中;
4、所有的男生向女生发出配对邀请;
5、找出收到邀请最多的男生,进行反配对选择;
6、输出配对结果。
代码实现:
#include<iostream>
#include<vector>
#include<iterator>
using namespace std;
//个体类
class Person
{
public:
//构造函数
Person(int id,int w,int f,int p,int pw,int pf,int pp):
mid(id)
,mwealth(w)
,mface(f)
,mpersonality(p)
,mper_wealth(pw)
,mper_face(pf)
,mper_personality(pp)
{}
int getid(){return mid;}
int getwealth(){return mwealth;}
int getface(){return mface;}
int getpersonality(){return mpersonality;}
int getper_wealth(){return mper_wealth;}
int getper_face(){return mper_face;}
int getper_personality(){return mper_personality;}
private:
int mid; //id
int mwealth; //财富
int mface; //样貌
int mpersonality; //品格
int mper_wealth; //需求财富
int mper_face; //需求样貌
int mper_personality;//需求品格
friend class Male;
friend class Female;
};
//男生类
class Male:public Person //派生类
{
public:
Male(int id,int w,int f,int p,int pw,int pf,int pp)
:Person(id,w,f,p,pw,pf,pp){}
//修改id
void setid(int id)
{
Person::mid = id;
}
private:
friend class Pairing; //声明友元类
};
//女生类
class Female:public Person //派生类
{
public:
//构造函数
Female(int id,int w,int f,int p,int pw,int pf,int pp)
:Person(id,w,f,p,pw,pf,pp){}
//修改id
void setId(int id)
{
Person::mid = id;
}
private:
vector<int> loveMaleId; //存储男生id,该男生对自己发送邀请
friend class Pairing;
};
//主角类
class Players:public Person
{
public:
Players(int id,int w,int f,int p,int pw,int pf,int pp,int sex)
:Person(id,w,f,p,pw,pf,pp),msex(sex){}
int getSex(){return msex;}
//类型转换函数 Players === > Female
Female makeFemale(Players &players)
{
Female female(players.getid(),players.getwealth(),players.getface(),players.getpersonality()
,players.getper_wealth(),players.getper_face(),players.getper_personality());
return female;
}
//类型转换函数 Players === > Male
Male makeMale(Players &players)
{
Male male(players.getid(),players.getwealth(),players.getface(),players.getpersonality()
,players.getper_wealth(),players.getper_face(),players.getper_personality());
return male;
}
private:
int msex; //表示性别
};
const int MAXPLAYERS = 100; //限定最大配对次数
class Pairing //配对类
{
public:
//初始化mmale
void filetommale()
{
char *path = "E:\\male.txt";
int id,w,f,p,pw,pf,pp;
FILE *fp = fopen(path,"r");
if(NULL == fp)
{
printf("Do not open the file\n");
exit(EXIT_FAILURE);
}
for(int i = 0;i < 100;i++)
{
fscanf(fp,"%d,%d,%d,%d,%d,%d,%d",&id,&w,&f,&p,&pw,&pf,&pp);
Male male(id,w,f,p,pw,pf,pp);
mmale.push_back(male);
}
fclose(fp);
}
//初始化female
void filetomfemale()
{
char *path = "E:\\female.txt";
int id,w,f,p,pw,pf,pp;
FILE *fp = fopen(path,"r");
if(NULL == fp)
{
printf("Do not open the file\n");
exit(EXIT_FAILURE);
}
for(int i = 0;i < 100;i++)
{
fscanf(fp,"%d,%d,%d,%d,%d,%d,%d",&id,&w,&f,&p,&pw,&pf,&pp);
Female female(id,w,f,p,pw,pf,pp);
mfemale.push_back(female);
}
fclose(fp);
}
//初始化players
void filetomplayers()
{
char *path = "E:\\players.txt";
int id,w,f,p,pw,pf,pp,sex;
FILE *fp = fopen(path,"r");
if(NULL == fp)
{
printf("Do not open the file\n");
exit(EXIT_FAILURE);
}
for(int i = 0;i < 100;i++)
{
fscanf(fp,"%d,%d,%d,%d,%d,%d,%d",&sex,&w,&f,&p,&pw,&pf,&pp);
Players players(-1,w,f,p,pw,pf,pp,sex);
mplayers.push_back(players);
}
fclose(fp);
}
//所有男生对女生发送邀请
void maletofemale(vector<Male> male,vector<Female>& female)
{
//外层循环,遍历男生
int i = 0;
auto it_male = male.begin();
for(;it_male != male.end();++it_male,i++)
{
//剔除配对失败的男生
if(it_male->getid() == -2){continue;}
int satisfaction = 0;//计算出满意度,并找出最心仪的
int maxSatisfaction = 0; //假定最心仪的
int index = 0; //记录最心仪女生在容器中的位置
//内层循环,找出该男生最心仪的女生,并向其发出邀请
int j = 0;
vector<Female>::iterator it_female = female.begin();
for(;it_female != mfemale.end();++it_female,j++)
{
//剔除配对失败的女生
if(it_female->getid() == -2){continue;}
satisfaction = it_male->getper_wealth() * it_female->getwealth()
+ it_male->getper_face() * it_female->getface()
+ it_male->getper_personality() * it_female->getpersonality();
if(satisfaction > maxSatisfaction) //满意度比较
{
maxSatisfaction = satisfaction;
index = j;
}
else if(satisfaction == maxSatisfaction) //满意度一样的话
{
int curSatisfactionNum = it_female->getwealth()
+ it_female->getface() + it_female->getpersonality();
int oldSatisfactionNum = female[index].getwealth()
+ female[index].getface() + female[index].getpersonality();
if(curSatisfactionNum > oldSatisfactionNum) //比较自身值
{
index = j;
}
else if(curSatisfactionNum == oldSatisfactionNum) //自身值一样
{
if(it_female->getid() < female[index].getid()) //比较id
{
index = j;
}
}
}
}
//将该男生id传入女生
female[index].loveMaleId.push_back(it_male->getid());
}
}
//找到邀请最多的女生
int inviteMax()
{
int maxPeople = 0; //表示收到最多邀请的个数
int femaleIndex = 0; //记录收到最多男生邀请的女生在容器中的位置
//遍历容器,找出那个女生收到男生的邀请最多
int i = 0;
vector<Female>::iterator it_female = mfemale.begin();
for(;it_female != mfemale.end();++it_female,i++)
{
if(it_female->loveMaleId.size() > maxPeople) //比较邀请人数
{
maxPeople = it_female->loveMaleId.size();
femaleIndex = i;
}
else if(it_female->loveMaleId.size() == maxPeople) //邀请人数一样
{
int curFemaleNum = it_female->getwealth() + it_female->getface() + it_female->getpersonality();
int oldFemaleNum = mfemale[femaleIndex].getwealth()
+ mfemale[femaleIndex].getface() + mfemale[femaleIndex].getpersonality();
if(curFemaleNum > oldFemaleNum) //比较自身值
{
femaleIndex = i;
}
else if(curFemaleNum == oldFemaleNum) //自身值一样
{
if(it_female->getid() < mfemale[femaleIndex].getid()) //比较id
{
femaleIndex = i;
}
}
}
}
return femaleIndex; //返回获取最多邀请的女生在容器中的位置
}
//女生挑选自己最心仪的一位男生,返回心意男生在容器中的位置
int femaleselectunique(vector<Female> &female)
{
//记录那个女生进行配对,注意idIndex表示配对女生在容器中的位置
int idIndex = inviteMax();
//此时已经知道那个女生收到的男生邀请是最多的
//接下来在这些男生中找到女生最心仪的一个男生
//遍历女生收到邀请的男生id,找出最心仪的一个
int satisfaction = 0; //表示满意程度
int maxSatisfaction = 0; //表示最满意的
int maleIndex = 0;
//外层循环向女生提出过邀请的男生
auto it1 = mfemale[idIndex].loveMaleId.begin();
for(;it1 != mfemale[idIndex].loveMaleId.end();++it1)
{
//内存循环找出对应男生id的全部信息
int j = 0;
vector<Male>::iterator it_male = mmale.begin();
for (;it_male != mmale.end();++it_male,++j)
{
if(it_male->getid() == *it1)
{
satisfaction = mfemale[idIndex].getper_wealth() * it_male->getwealth()
+ mfemale[idIndex].getper_face() * it_male->getface()
+ mfemale[idIndex].getper_personality() * it_male->getpersonality();
if(satisfaction > maxSatisfaction)
{
maxSatisfaction = satisfaction;
maleIndex = j;
}
else if(satisfaction == maxSatisfaction) //满意度比较
{
int curSatisfactionNum = it_male->getwealth() + it_male->getface() + it_male->getpersonality();
int oldSatisfactionNum = mmale[maleIndex].getwealth() + mmale[maleIndex].getface() + mmale[maleIndex].getpersonality();
if(curSatisfactionNum > oldSatisfactionNum) //自身比较
{
maleIndex = j;
}
else if(curSatisfactionNum == oldSatisfactionNum)
{
if(it_male->getid() < mmale[maleIndex].getid()) //id比较
{
maleIndex = j;
}
}
}
}
}
}
return maleIndex; //返回的是心仪男生最容器中的位置
}
//配对失败,将其余的男生重新分配到容器里-----仅仅是向配对失败女生发出过邀请的那一部分男生
void clearvector(vector<Female> &female,int mfemale)
{
vector<int> otherMaleId = female[mfemale].loveMaleId;
female[mfemale].loveMaleId.clear();
vector<Male> otherMale;
//外层循环其他男生
vector<int>::iterator it = otherMaleId.begin();
for(;it != otherMaleId.end();++it)
{
//内存循环找出对应男生的全部信息
vector<Male>::iterator it_male = mmale.begin();
int i = 0;
for(;it_male != mmale.end();++it_male,++i)
{
if(mmale[i].getid() == *it)
{
otherMale.push_back(mmale[i]); //将该男生对象插入
}
}
}
maletofemale(otherMale,female); //将剩余的男生重新分配
}
//输出配对情况
void show()
{
//获取主角数据
filetomplayers();
//定义一个计数器
int count = 0;
while(count < MAXPLAYERS)
{
filetommale(); //获取男生数据
filetomfemale(); //获取女生数据
//添加主角
if(mplayers[count].getSex(http://www.my516.com) == 0)
{
mfemale.push_back(mplayers[count].makeFemale(mplayers[count]));
}
else
{
mmale.push_back(mplayers[count].makeMale(mplayers[count]));
}
//此时已经将数据主角插入进去
//下面进行配对
//所有男生向女生发送邀请
maletofemale(mmale,mfemale);
int count_index = 0; //定义一个计数器
while(count_index < MAXPLAYERS)
{
//哪一个女生进行配对
int femaleId = inviteMax();
//女生选择自己最心仪的一个男生
int maleId = femaleselectunique(mfemale);
//检查是不是主角
if(mmale[maleId].getid() == -1 || mfemale[femaleId].getid() == -1)
{
cout<< "第" << count + 1 << "组player加入:" << mmale[maleId].getid() << ":" << mfemale[femaleId].getid() << endl;
break;
}
else
{
//修改男生id
mmale[maleId].setid(-2);
//修改女生id
mfemale[femaleId].setId(-2);
//去除选择该女生的男生
clearvector(mfemale,femaleId);
}
count_index++;
}
if(count_index == 100)
{
cout<< "第" << count + 1 << "组player加入:" << " " << ":" << " " << endl;
}
count++;
mmale.clear(); //清空
mfemale.clear(); //清空
}
}
private:
vector<Male> mmale;
vector<Female> mfemale;
vector<Players> mplayers;
};
int main()
{
Pairing a;
a.show();
return 0;
}
运行结果:
第1组player加入:-1:28
第2组player加入:33:-1
第3组player加入:4:-1
第4组player加入:11:-1
第5组player加入:46:-1
第6组player加入:65:-1
第7组player加入:-1:39
第8组player加入:-1:41
第9组player加入:49:-1
第10组player加入:-1:80
第11组player加入:-1:36
第12组player加入:-1:23
第13组player加入:-1:29
第14组player加入:-1:86
第15组player加入:36:-1
第16组player加入:-1:98
第17组player加入:-1:11
第18组player加入:-1:76
第19组player加入:20:-1
第20组player加入:-1:47
第21组player加入:-1:77
第22组player加入:41:-1
第23组player加入:-1:20
第24组player加入:57:-1
第25组player加入:-1:45
第26组player加入:-1:39
第27组player加入:-1:36
第28组player加入:-1:9
第29组player加入:-1:22
第30组player加入:79:-1
第31组player加入:-1:45
第32组player加入:-1:86
第33组player加入:22:-1
第34组player加入:-1:34
第35组player加入:45:-1
第36组player加入:97:-1
第37组player加入:67:-1
第38组player加入:-1:13
第39组player加入:-1:39
第40组player加入:-1:60
第41组player加入:-1:15
第42组player加入:56:-1
第43组player加入:-1:97
第44组player加入:26:-1
第45组player加入:71:-1
第46组player加入:-1:27
第47组player加入: :
第48组player加入:85:-1
第49组player加入:-1:97
第50组player加入:-1:46
第51组player加入:-1:49
第52组player加入:4:-1
第53组player加入:-1:35
第54组player加入:27:-1
第55组player加入:65:-1
第56组player加入:77:-1
第57组player加入:-1:73
第58组player加入:-1:94
第59组player加入:-1:83
第60组player加入:52:-1
第61组player加入:48:-1
第62组player加入:-1:53
第63组player加入:2:-1
第64组player加入:-1:12
第65组player加入:-1:78
第66组player加入:-1:84
第67组player加入:-1:69
第68组player加入:97:-1
第69组player加入:26:-1
第70组player加入:-1:97
第71组player加入:71:-1
第72组player加入:-1:78
第73组player加入:1:-1
第74组player加入:-1:28
第75组player加入:55:-1
第76组player加入:-1:28
第77组player加入:-1:10
第78组player加入:-1:81
第79组player加入:-1:87
第80组player加入:74:-1
第81组player加入:-1:63
第82组player加入:33:-1
第83组player加入: :
第84组player加入:79:-1
第85组player加入:66:-1
第86组player加入:9:-1
第87组player加入:66:-1
第88组player加入:-1:58
第89组player加入:37:-1
第90组player加入:14:-1
第91组player加入:-1:21
第92组player加入:54:-1
第93组player加入:-1:78
第94组player加入:77:-1
第95组player加入:78:-1
第96组player加入:-1:94
第97组player加入:53:-1
第98组player加入:-1:56
第99组player加入:-1:45
第100组player加入:14:-
---------------------
数字化婚姻配对尝试问题(C++实现)的更多相关文章
- POJ3487[稳定婚姻]
The Stable Marriage Problem Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2974 Accepted ...
- 沉淀,再出发:结合案例看python
沉淀,再出发:结合案例看python 一.前言 关于python,如果不经过大型程序开发的洗礼,我们很难说自己已经懂得了python了,因此,我们需要通过稍微结构化的编程来学习python. 二.一个 ...
- 【稳定婚姻问题】【HDU1435】【Stable Match】
2015/7/1 19:48 题意:给一个带权二分图 求稳定匹配 稳定的意义是对于某2个匹配,比如,( a ---- 1) ,(b----2) , 如果 (a,2)<(a,1) 且(2,a)& ...
- 稳定婚姻问题和Gale-Shapley算法(转)
什么是算法?每当有人问作者这样的问题时,他总会引用这个例子:假如你是一个媒人,有若干个单身男子登门求助,还有同样多的单身女子也前来征婚.如果你已经知道这些女孩儿在每个男孩儿心目中的排名,以及男孩儿们在 ...
- HDU 1522 Marriage is Stable 【稳定婚姻匹配】(模板题)
<题目链接> 题目大意: 给你N个男生和N个女生,并且给出所有男生和女生对其它所有异性的喜欢程度,喜欢程度越高的两个异性越容易配对,现在求出它们之间的稳定匹配. 解题分析: 稳定婚姻问题的 ...
- 洛谷P2507 [SCOI2008]配对
题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...
- UVA 1175 Ladies' Choice 稳定婚姻问题
题目链接: 题目 Ladies' Choice Time Limit: 6000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu 问题 ...
- 洛谷 P1407 [国家集训队]稳定婚姻 解题报告
P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...
- 基于Deep Learning的中文分词尝试
http://h2ex.com/1282 现有分词介绍 自然语言处理(NLP,Natural Language Processing)是一个信息时代最重要的技术之一,简单来讲,就是让计算机能够理解人类 ...
随机推荐
- Handling bundles in activities and fragments
Bundle is a useful data holder, which maps String values to various Parcelable types. So basicall ...
- JavaScript使用正則表達式
2.0 简单介绍 正則表達式是能够用来查找与给定模式匹配的文本的搜索模式.比如,在上一章中,我们在一个较长的字符串中查找子字符串Cookbook: var testValue = "This ...
- HBase行锁原理及实现
请带着例如以下问题阅读本文. 1.什么是行锁? 2.HBase行锁的原理是什么? 3.HBase行锁是怎样实现的? 4.HBase行锁是怎样应用的? 一.什么是行锁? 我们知道.数据库中存在事务的概念 ...
- 将分布式-队列的实现交给redis
import requestsimport reimport timefrom redis import Redisimport threading REDIS_HOST, REDIS_PORT, P ...
- 超级有用的git reset --hard和git revert命令
很多时候,git新手容易误操作,比如,在levelIISZ-1.4.dev分支下,运行了git pull idc cpp-1.0的结果,这样做麻烦很大,经常导致maven项目格式不正确,这个时候,可以 ...
- Kaggle "Microsoft Malware Classification Challenge"——就是沙箱恶意文件识别,有 Opcode n-gram特征 ASM文件图像纹理特征 还有基于图聚类方法
使用图聚类方法:Malware Classification using Graph Clustering 见 https://github.com/rahulp0491/Malware-Classi ...
- JSP-Runoob:JSP 动做元素
ylbtech-JSP-Runoob:JSP 动做元素 1.返回顶部 1. JSP 动作元素 与JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用.JSP动作元素是用XML语法写成的. 利用J ...
- hibernate字段名和属性
字段名和属性名相同 Annotation:默认为@Basic 注意:如果在成员属性没有加入任何注解,则默认在前面加入了@Basic Xml中不用写column 字段名和属性名不同 Annotation ...
- maven的pom.xml文件错误
来自:http://www.cnblogs.com/shihujiang/p/3492864.html
- 等价表达式 2005年NOIP全国联赛提高组(栈模拟)
P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...