数字化婚姻配对尝试

    xiaoxiao2021-03-25  120

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

    为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值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 请按任意键继续. . .

    转载请注明原文地址: https://ju.6miu.com/read-8722.html

    最新回复(0)