数字化婚姻配对尝试

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

为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值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、循环该配对法则,直到最后一对男女配对成功。


ps:在匹配时,如果发现有多个满意度相同的对象,要求自身三个属性(财富,外貌,品格)总和大的优先,如果再相同则id小的优先。如果有2位女士的选票相同,优先级规则同上。请把主角的id置为最小值,以便在前2个条件相同情况下,主角可以优先选择。

male.txt,female.txt,players.txt 分别是男士样本、女士样本和主角样本各 100位。 男女样本中,每行都代表一位男士或女士的基本属性,从左到右依次是ID, 样貌,品格,财富 , 期望样貌,期望品格,期望财富,没有加入性别,需要在解析时手动添加,每个txt文本的性别都是一样的,请注意。另外,主角样本中没有ID属性,换成了性别属性,其中 0表示女性,1表示男性,其余属性依次为样貌,品格,财富,期望样貌 ,期望品格,期望财富。建议把主角的id都设置为 -1,以便满足优先选择的条件。


#include <iostream>
#include <assert.h>
#include<vector>
#include<iterator>
using namespace std;

class Person
{
public:
	Person(int id,int a,int b,int c,int d,int e,int f)
		:mid(id),ma(a),mb(b),mc(c),md(d),me(e),mf(f){}

	int mid;
	int ma,mb,mc,md,me,mf;
};

class Male;
class Female:public Person
{
public:
	Female(int id,int a,int b,int c,int d,int e,int f)
		:Person(id,a,b,c,d,e,f){}

	void addInvite(int maleid)
	{
		maleId.push_back(maleid);
	}
	int matchMale(vector<Male> &maleVec);
	vector<int>& getmaleId()
	{
		return maleId;
	}
private:
	vector<int> maleId;
	friend class Male;
};

class Male:public Person
{
public:
	Male(int id,int a,int b,int c,int d,int e,int f)
		:Person(id,a,b,c,d,e,f){}
	void sendInvite(vector<Female> &femaleVec,int index)
	{
		femaleVec[index].addInvite(mid); 
	}
};

int Female::matchMale(vector<Male> &maleVec)
{
	int satisfaction = 0;
	int satisfaction_cur = 0;
	int index = 0;

	for (vector<int>::iterator id_it = maleId.begin();id_it != maleId.end();++id_it)
	{
		int j = 0;
		for (vector<Male>::iterator male_it = maleVec.begin();male_it != maleVec.end();++male_it,j++)
		{
			if (maleVec[j].mid == *id_it)
			{
				satisfaction_cur = md * maleVec[j].ma + me * maleVec[j].mb + mf * maleVec[j].mc;
				if (satisfaction_cur > satisfaction )
				{
					satisfaction = satisfaction_cur;
					index = j;
				}
				else if(satisfaction_cur == satisfaction )
				{
					int synthesize_cur = maleVec[j].ma + maleVec[j].mb + maleVec[j].mc;
					int synthesize_old = maleVec[index].ma + maleVec[index].mb + maleVec[index].mc;
					if (synthesize_cur > synthesize_old)
					{
						index = j;
					}
					else if (synthesize_cur == synthesize_old)
					{
						if (maleVec[j].mid < maleVec[index].mid)
						{
							index = j;
						}
					}
				}
			}

		}

	}
	return index;
}

class Player:public Person
{
public:
	Player(int id,int a,int b,int c,int d,int e,int f,int sex)
		:Person(id,a,b,c,d,e,f),msex(sex){}
	int getSex()
	{ 
		return msex;
	}
	Female makeFemale()
	{
		Female female(mid,ma,mb,mc,md,me,mf);
		return female;
	}
	Male makeMale()
	{
		Male male(mid,ma,mb,mc,md,me,mf);
		return male;
	}
private:
	//0 female //1 male
	int msex;
};

class CMatch
{
public:
	void loadMalesdata()
	{
		int id,a,b,c,d,e,f;
		FILE *fp = fopen("d:\\male.txt","r");
		assert(fp != NULL);

		for (int i=0;i<100;++i)
		{
			fscanf(fp,"%d,%d,%d,%d,%d,%d,%d",&id,&a,&b,&c,&d,&e,&f);
			Male male(id,a,b,c,d,e,f);
			maleVec.push_back(male);
		}
		fclose(fp);
	}
	void loadFemalesdata()
	{
		int id,a,b,c,d,e,f;
		FILE *fp = fopen("d:\\female.txt","r");
		assert(fp != NULL);

		for (int i=0;i<100;++i)
		{
			fscanf(fp,"%d,%d,%d,%d,%d,%d,%d",&id,&a,&b,&c,&d,&e,&f);
			Female female(id,a,b,c,d,e,f);
			femaleVec.push_back(female);
		}
		fclose(fp);
	}
	void loadPlayersdata()
	{
		int sex,a,b,c,d,e,f;
		FILE *fp = fopen("d:\\players.txt","r");
		assert(fp != NULL);

		for (int i=0;i<100;++i)
		{
			fscanf(fp,"%d,%d,%d,%d,%d,%d,%d",&sex,&a,&b,&c,&d,&e,&f);
			Player player(-1,a,b,c,d,e,f,sex);
			playerVec.push_back(player);
		}
		fclose(fp);
	}

	void maleCalculate(vector<Male> &maleVec)
	{
		int satisfaction = 0;
		int satisfaction_cur = 0;
		int index = 0;//记录被邀请女性的索引

		int male_index=0;
		for (vector<Male>::iterator male_it = maleVec.begin();male_it != maleVec.end();++male_it,male_index++)
		{
			satisfaction = 0;
			satisfaction_cur = 0;
			index = 0;//记录被邀请女性的索引

			if (male_it->mid == -2)
			{
				continue;
			}

			int i=0;
			for (vector<Female>::iterator female_it = femaleVec.begin();female_it != femaleVec.end();++female_it,i++)
			{
				if (female_it->mid == -2)
				{
					continue;
				}
				satisfaction_cur = male_it->md * female_it->ma + male_it->me * female_it->mb + male_it->mf * female_it->mc;
				if (satisfaction_cur > satisfaction )
				{
					satisfaction = satisfaction_cur;
					index = i;
				}
				else if(satisfaction_cur == satisfaction )
				{
					int synthesize_cur = female_it->ma + female_it->mb + female_it->mc;
					int synthesize_old= femaleVec[index].ma + femaleVec[index].mb + femaleVec[index].mc;
					if (synthesize_cur > synthesize_old)
					{
						index = i;
					}
					else if (synthesize_cur == synthesize_old)
					{
						if (female_it->mid < femaleVec[index].mid)
						{
							index = i;
						}
					}
				}
			}
			maleVec[male_index].sendInvite(femaleVec,index);
		}
	}
	void failmaleCalculate(int f_index)
	{
		vector<int> fail_idVec = femaleVec[f_index].getmaleId();
		femaleVec[f_index].getmaleId().clear();
		vector<Male> fail_maleVec;
		for (vector<int>::iterator id_it = fail_idVec.begin();id_it != fail_idVec.end();++id_it)
		{
			int j = 0;
			for (vector<Male>::iterator male_it = maleVec.begin();male_it != maleVec.end();++male_it,j++)
			{
				if (maleVec[j].mid == *id_it)
				{
					fail_maleVec.push_back(maleVec[j]);
				}
			}
		}
		maleCalculate(fail_maleVec);
	}

	int inviteMax()
	{
		int index = 0;
		int len = 0;
		int len_cur = 0;
		int i = 0;
		for (vector<Female>::iterator female_it = femaleVec.begin();female_it != femaleVec.end();++female_it,i++)
		{
			len_cur = femaleVec[i].getmaleId().size();
			if (len_cur > len )
			{
				len = len_cur;
				index = i;
			}
			else if (len_cur == len)
			{
				int synthesize_cur = femaleVec[i].ma+femaleVec[i].mb+femaleVec[i].mc;
				int synthesize_old = femaleVec[index].ma+femaleVec[index].mb+femaleVec[index].mc;
				if (synthesize_cur > synthesize_old  )
				{
					index = i;
				}
				else if (synthesize_cur == synthesize_old )
				{
					if (femaleVec[i].mid < femaleVec[index].mid)
					{
						index = i;
					}
				}
			}
		}
		return index;
	}

	void beginMatch()
	{
		loadPlayersdata();
		int index = 0;
		while (index < 100)
		{
			loadFemalesdata();
			loadMalesdata();

			if (playerVec[index].getSex() == 0)
			{
				femaleVec.push_back(playerVec[index].makeFemale());
			}
			else
			{
				maleVec.push_back(playerVec[index].makeMale());
			}
	
			//所有男向女发送邀请
			maleCalculate(maleVec);

			//最多选择女性选择一个男性
			int count = 0;
			while(count < 100)
			{
				int f_index = inviteMax();
				int m_index = femaleVec[f_index].matchMale(maleVec);

				//男女是否为主角
				if (femaleVec[f_index].mid == -1  || maleVec[m_index].mid == -1)
				{
					cout<<"第"<<index+1<<"组player加入:"<<maleVec[m_index].mid<<":"<<femaleVec[f_index].mid<<endl;
					break;
				}
				else
				{
					//cout<<maleVec[m_index].mid<<":"<<femaleVec[f_index].mid<<endl;
					femaleVec[f_index].mid = -2;
					maleVec[m_index].mid = -2;
					//配对失败的其他男性重新选择
					failmaleCalculate(f_index);
				}
				count++;
			}
			if(count == 100)
			{
				cout<<"第"<<index+1<<"组player加入:"<<endl;
			}
			
			index++;
			maleVec.clear();
			femaleVec.clear();
		}
	}

private:
	vector<Male> maleVec;
	vector<Female> femaleVec;
	vector<Player> playerVec;
};

int main ()
{
	CMatch match;
	match.beginMatch();

	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:-1
请按任意键继续. . .



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值