问题描述:
一、标题:

数字化婚姻配对尝试

二、题目:

建立一个模型,来模拟推导社会男女择偶过程。

为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值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++实现)的更多相关文章

  1. POJ3487[稳定婚姻]

    The Stable Marriage Problem Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2974 Accepted ...

  2. 沉淀,再出发:结合案例看python

    沉淀,再出发:结合案例看python 一.前言 关于python,如果不经过大型程序开发的洗礼,我们很难说自己已经懂得了python了,因此,我们需要通过稍微结构化的编程来学习python. 二.一个 ...

  3. 【稳定婚姻问题】【HDU1435】【Stable Match】

    2015/7/1 19:48 题意:给一个带权二分图  求稳定匹配 稳定的意义是对于某2个匹配,比如,( a ---- 1) ,(b----2) , 如果 (a,2)<(a,1) 且(2,a)& ...

  4. 稳定婚姻问题和Gale-Shapley算法(转)

    什么是算法?每当有人问作者这样的问题时,他总会引用这个例子:假如你是一个媒人,有若干个单身男子登门求助,还有同样多的单身女子也前来征婚.如果你已经知道这些女孩儿在每个男孩儿心目中的排名,以及男孩儿们在 ...

  5. HDU 1522 Marriage is Stable 【稳定婚姻匹配】(模板题)

    <题目链接> 题目大意: 给你N个男生和N个女生,并且给出所有男生和女生对其它所有异性的喜欢程度,喜欢程度越高的两个异性越容易配对,现在求出它们之间的稳定匹配. 解题分析: 稳定婚姻问题的 ...

  6. 洛谷P2507 [SCOI2008]配对

    题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...

  7. UVA 1175 Ladies' Choice 稳定婚姻问题

    题目链接: 题目 Ladies' Choice Time Limit: 6000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu 问题 ...

  8. 洛谷 P1407 [国家集训队]稳定婚姻 解题报告

    P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...

  9. 基于Deep Learning的中文分词尝试

    http://h2ex.com/1282 现有分词介绍 自然语言处理(NLP,Natural Language Processing)是一个信息时代最重要的技术之一,简单来讲,就是让计算机能够理解人类 ...

随机推荐

  1. CocoaPods pod instal慢、卡住解决方法

    CocoaPods pod install慢.卡住解决方法 近期使用CocoaPods来加入第三方类库,不管是运行pod install还是pod update都卡在了Analyzing depend ...

  2. ZOJ2599:Graduated Lexicographical Ordering(很经典的数位DP)

    Consider integer numbers from 1 to n. Let us call the sum of digits of an integer number its weight. ...

  3. VS中多项目联合开发技巧

    1.  新建目录,将它设定为 本次project的工作目录,新建一个Code Files目录 2.  在Code Files目录里.新建一个Win32控制台程序(总控程序),再新建其他的项目比方项目A ...

  4. ios method swizzling

      阅读器 iOS开发iOS   本文由TracyYih[博客]翻译自NSHipster的文章Method Swizzling.   在上周associated objects一文中,我们开始探索Ob ...

  5. Android获取全部存储卡挂载路径

    近期因项目需求.须要在存储卡查找文件,经測试发现部分手机挂载路径查找不到,这里分享一个有效的方法. /** * 获取全部存储卡挂载路径 * @return */ public static List& ...

  6. Ubuntu 12.04 LTS 无法进入桌面环境

    今天开机后,在登陆的时候,进入了登陆界面(选择用户,输入密码的那个界面),输入正确的密码后屏幕跳转了一下,但是很快又回到了登陆界面.然后我就尝试以guest [访客]的身份登陆,发现进入了桌面系统. ...

  7. bzoj 4003 [JLOI2015]城池攻占 —— 左偏树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4003 其实蛮简单的,首先一个城市只会被其子树中的骑士经过,启发我们 dfs 序用可并堆合并子 ...

  8. 68. 对Extjs中store的多种操作

    转自:https://www.cnblogs.com/exmyth/archive/2013/05/16/3082045.html 先来个声明,看着不错,贴过来的,没都测试过. Store.getCo ...

  9. Sqlserver日期操作

    Sqlserver日期操作 select GETDATE() as '当前日期', DateName(year,GetDate()) as '年', DateName(month,GetDate()) ...

  10. scrapy xpath中提取多个class值

    xpath中没有提供对class的原生查找方法.但是 stackoverflow 看到了一个很有才的回答: This selector should work but will be more eff ...