博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数字化婚姻配对尝试
阅读量:3940 次
发布时间:2019-05-24

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

文章目录

一、标题:

数字化婚姻配对尝试

二、题目:

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

为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值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)的满意度为:

(1050+3060+60*80)= 7100分

相对的 MM 对 GG的满意度则为:

(4080+1050+50*40) = 5700分

好了,配对活动开始,设计的配对法则如下:

1、100个男方,顺序,轮流从0号到99号女方中挑选自己最满意的一位,然后向她发出配对邀请。

2、接受邀请最多的女方开始行动,对这些邀请的男性中,选择最满意的一位。

3、那么这两位配对成功,剔除出样本,剩下的99对继续这样配对。

4、循环该配对法则,直到最后一对男女配对成功。

三、代码实现

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define THREADS 4struct Node{ Node(int id = 0,int su = 0,int sa = 0):ID(id),sum(su) ,satisfaction(sa) { } int ID; int sum; int satisfaction;};struct Node2{ Node2(int id = 0,int su = 0,int c = 0):ID(id),sum(su) ,count(c) { } int ID; int sum; int count;};class comp{ public: bool operator()(const Node &left, const Node &right) { if(left.satisfaction > right.satisfaction) { return true; } else if(left.satisfaction == right.satisfaction) { if(left.sum > right.sum) { return true; } else if(left.sum == right.sum && left.ID < right.ID) { return true; } } return false; }};struct people{ people(int id = 0,int w = 0, int a = 0, int c = 0, int s_w = 0, int s_a = 0, int s_c = 0) :ID(id),wealth(w),appearance(a),chararter(c), s_wealth(s_w),s_appearance(s_a),s_chararter(s_c) { } int ID; //对象的编号 int wealth; //财富 int appearance; //样貌 int chararter; //品格 int s_wealth; //期望配偶财富 int s_appearance; //期望配偶样貌 int s_chararter; //期望配偶品格 //对于男性,记录对所有女性的满意度 //对于女性,记录选择她的男性的满意度 set
recode;};class comp2{ public: bool operator()(const Node2 &left, const Node2 &right) { if(left.count > right.count) { return true; } else if(left.count == right.count) { if(left.sum > right.sum) { return true; } else if(left.sum == right.sum && left.ID < right.ID) { return true; } } return false; }};class man{ public: //计算所有女性在男性心里的满意度,并添加 void countMaleSatisfaction(unordered_map
::iterator &it_male ,unordered_map
&female ) { auto it_female = female.begin(); for(; it_female != female.end(); ++it_female) { int sum = it_female->second.wealth + it_female->second.appearance + it_female->second.chararter; int satisfaction = it_male->second.s_wealth * it_female->second.wealth + it_male->second.s_appearance * it_female->second.appearance + it_male->second.s_chararter * it_female->second.chararter; //加入对女性的满意度 it_male->second.recode.insert(Node(it_female->first,sum,satisfaction)); } } //计算男性在女性心理的满意度并添加 void countFemaleSatisfaction(unordered_map
::iterator &it_male ,unordered_map
&female) { int id = it_male->second.recode.begin()->ID; auto it = female.find(id); if(it == female.end()) { return ; } int sum = it->second.wealth + it->second.appearance + it->second.chararter; int satisfaction = it->second.s_wealth * it_male->second.wealth + it->second.s_chararter * it_male->second.chararter + it->second.s_appearance * it_male->second.appearance; //加入对男性的满意度 it->second.recode.insert(Node(it_male->first,sum,satisfaction)); } //计算满意度 void countSatisfaction() { //计算每个女性在男性心里的满意度 int size = _male.size(); #pragma omp parallel for num_threads(THREADS) schedule(static,5) for(int i = 0; i < size; ++i) { auto it = _male.find(i); if(it != _male.end()) { countMaleSatisfaction(it,_female); } } //计算选择该女性的男性在该女性心理的满意度 auto it_male = _male.begin(); for(; it_male != _male.end(); ++it_male) { countFemaleSatisfaction(it_male,_female); } auto it_female = _female.begin(); for(; it_female != _female.end(); ++it_female) { int sum = it_female->second.wealth + it_female->second.appearance + it_female->second.chararter; //记录索引 int id = it_female->first; int count = it_female->second.recode.size(); _index.insert(Node2(id, sum, count)); } } //主角如果是男性 void addMaleRole(people &role,unordered_map
&male, unordered_map
&female, multiset
&index) { role.ID = -1; male[-1] = role; auto it_male = male.find(-1); //主角添加对所有女性的满意度 countMaleSatisfaction(it_male,female); //男主选择的女性角色的id int id = it_male->second.recode.begin()->ID; auto it_female = female.find(id); int count = it_female->second.recode.size(); int sum = it_female->second.wealth + it_female->second.appearance + it_female->second.chararter; //添加新的索引 index.insert(Node2(id,sum,count+1)); //删除旧的索引 index.erase(Node2(id,sum,count)); //添加主角选择的女性对主角的满意度 countFemaleSatisfaction(it_male,female); } //主角如果是女性 void addFemaleRole(people &role,unordered_map
&male, unordered_map
&female, multiset
&index) { role.ID = -1; female[-1] = role; auto it_female = female.find(-1); auto it_male = male.begin(); for(; it_male != male.end(); ++it_male) { //记录当前男性所选择的女性的记录 Node tmp = *(it_male->second.recode.begin()); int sum = it_female->second.wealth + it_female->second.appearance + it_female->second.chararter; int satisfaction = it_male->second.s_wealth * it_female->second.wealth + it_male->second.s_appearance * it_female->second.appearance + it_male->second.s_chararter * it_female->second.chararter; //加入对女性的满意度 it_male->second.recode.insert(Node(-1,sum,satisfaction)); //如果当前男性选择了女主角,则把该男性选择的上一个女性的记录删除 if(it_male->second.recode.begin()->ID == -1) { auto it = it_male->second.recode.begin(); ++it; auto it_tmp = female.find(it->ID); it_tmp->second.recode.erase(tmp); int sum = it_tmp->second.wealth + it_tmp->second.appearance + it_tmp->second.chararter; int count = it_tmp->second.recode.size(); index.erase(Node2(it->ID, sum, count+1)); index.insert(Node2(it->ID, sum, count)); } } //添加女主的索引 int sum = role.wealth + role.appearance + role.chararter; int count = female[-1].recode.size(); index.insert(Node2(-1,sum,count)); } //选择阶段 vector
select(unordered_map
&male, unordered_map
&female, multiset
&index) { //存放索引 vector
res; while( 1 ) { //接受请求个数最多的女性 if(index.empty()) { return res; } auto ind = index.begin(); auto it_female = female.find(ind->ID); auto it_male = it_female->second.recode.begin(); //如果主角被选中,返回 if(it_female->second.ID == -1 || it_male->ID == -1) { res.push_back(it_male->ID); res.push_back(it_female->first); return res; } //删除被选择的男性 auto it = male.find(it_male->ID); if(it != male.end()) { male.erase(it); } //删除女性角色 int id = it_female->first; //female.erase(it_female); index.erase(ind); if(female.empty() || male.empty()) { //主角没找到对象 //退出程序 //返回一个空的数组 return res; } //修改选择了被删除女性的男性的请求 auto it_recode = it_female->second.recode.begin(); ++it_recode; for(; it_recode != it_female->second.recode.end(); ++it_recode) { int male_id = it_recode->ID; auto it_male = male.find(male_id); if(it_male != male.end()) { it_male->second.recode.erase(it_male->second.recode.begin()); //如果索引表为空了,则说明所有人匹配结束,此时主角没有找到 if(index.empty()) { break; } int fid = it_male->second.recode.begin()->ID; auto tmp = female.find(fid); while(tmp == female.end() && !it_male->second.recode.empty()) { it_male->second.recode.erase(it_male->second.recode.begin()); fid = it_male->second.recode.begin()->ID; tmp = female.find(fid); } //修改相关女性的索引表的数据 int sum = it_male->second.recode.begin()->sum; int count = female[fid].recode.size(); index.erase(Node2(fid,sum,count)); // countFemaleSatisfaction(it_male,female); //更新索引 index.insert(Node2(fid,sum,count+1)); } } //将已选择过的女性角色删除 female.erase(it_female); } } //统计所有 void countAll() { FILE *fpp = fopen("players.txt","r"); FILE *fpz = fopen("123.txt","w"); int sex; //对象的性别 int wealth; //财富 int appearance; //样貌 int chararter; //品格 int s_wealth; //期望配偶财富 int s_appearance; //期望配偶样貌 int s_chararter; //期望配偶品格 char str[128] = { 0}; vector
pro; while(fgets(str,127,fpp) > 0) { sscanf(str,"%d,%d,%d,%d,%d,%d,%d" ,&sex,&wealth,&appearance,&chararter,&s_wealth,&s_appearance,&s_chararter); pro.push_back(people(sex,wealth,appearance,chararter,s_wealth,s_appearance,s_chararter)); } //写入答案的缓冲区 char buff[128] = { 0}; string str1 = "第%d组player加入:%d:%d\n"; string str2 = "第%d组player加入:\n"; vector
> res; int size = pro.size(); res.resize(size); //设置线程个数 //int thread_count = THREADS; #pragma omp parallel for num_threads(THREADS) for(int i = 0; i < pro.size(); i++) { unordered_map
male = _male; unordered_map
female = _female; multiset
index = _index; //如果是男性 if(pro[i].ID == 1) { addMaleRole(pro[i], male, female, index); } else { //如果是女性 addFemaleRole(pro[i], male, female, index); } res[i] = select(male,female,index); } for(int i = 0; i < size; i++) { if(res[i].size() == 0) { sprintf(buff, str2.c_str(), i+1); } else { sprintf(buff, str1.c_str(), i+1,res[i][0],res[i][1]); } //将缓冲区的内容写入文件 fwrite(buff, strlen(buff), 1, fpz); memset(buff, 0, strlen(buff)); } } static void *staticReadMale(void *arg) { man *p = (man *)arg; p->readMale(); } static void *staticReadFemale(void *arg) { man *p = (man *)arg; p->readFemale(); } void readMale() { FILE *fp = fopen("male.txt","r"); int ID; //对象的编号 int wealth; //财富 int appearance; //样貌 int chararter; //品格 int s_wealth; //期望配偶财富 int s_appearance; //期望配偶样貌 int s_chararter; //期望配偶品格 char str[128] = { 0}; while(fgets(str,127,fp) > 0) { sscanf(str,"%d,%d,%d,%d,%d,%d,%d",&ID,&wealth,&appearance,&chararter,&s_wealth,&s_appearance,&s_chararter); _male[ID] = people(ID,wealth,appearance,chararter,s_wealth,s_appearance,s_chararter); } fclose(fp); } void readFemale() { FILE *fp = fopen("female.txt","r"); int ID; //对象的编号 int wealth; //财富 int appearance; //样貌 int chararter; //品格 int s_wealth; //期望配偶财富 int s_appearance; //期望配偶样貌 int s_chararter; //期望配偶品格 char str[128] = { 0}; while(fgets(str,127,fp) > 0) { sscanf(str,"%d,%d,%d,%d,%d,%d,%d" ,&ID,&wealth,&appearance,&chararter,&s_wealth,&s_appearance,&s_chararter); _female[ID] = people(ID,wealth,appearance,chararter,s_wealth,s_appearance,s_chararter); } fclose(fp); } //初始化所有 void initAll() { pthread_t id[2]; int a; pthread_create(&id[0],NULL,staticReadMale,(void *)this); pthread_create(&id[1],NULL,staticReadFemale,(void *)this); for(int i = 0; i < 2; i++) { pthread_join(id[i],NULL); } } multiset
&getIndex() { return _index; }private: unordered_map
_male; //comp2根据接受请求的个数排序,接受请求个数相同的按id 排序 unordered_map
_female; multiset
_index;};int main(){ man pp; pp.initAll(); pp.countSatisfaction(); pp.countAll(); return 0;}

转载地址:http://ixnwi.baihongyu.com/

你可能感兴趣的文章
ffmpeg 常用 命令随手记
查看>>
av_seek_frame中flags值的意义
查看>>
git 学习笔记
查看>>
C++类中的static的用法
查看>>
vector 释放内存 swap
查看>>
在linux下新增一块硬盘的操作。(包含大于2T的硬盘在linux下挂载操作)
查看>>
在32位系统中使用fseek和lseek或fwrite、write写大文件时,最大只能写2G左右的解决办法
查看>>
整理华为C/C++编码规范
查看>>
C语言中嵌入正则表达式
查看>>
libxml2 指南(中文)
查看>>
虚拟机VMware中实现linux与windows的共享
查看>>
undefined reference问题总结
查看>>
souce insight 3.5 修改背景颜色
查看>>
Linux 关闭/开启图形界面(X-window) 命令
查看>>
debug 打印 开关 设计(for c || C++)
查看>>
vmware中虚拟机和主机ping不通的问题。
查看>>
从“冷却时间”谈产品设计
查看>>
常用shell脚本
查看>>
长网站 转换为 短网址 的原理
查看>>
基于http协议的C语言客户端代码
查看>>