1、標題:java
數字化婚姻配對嘗試ios
2、題目:c++
創建一個模型,來模擬推導社會男女擇偶過程。編程
爲了模型簡化,一我的的特性指標有三個,這裏假設爲財富、樣貌、品格,每一個指標都可取值1-100之間任意數字。一樣也對這3項指標有本身的需求。這3個需求值取值範圍都在1-98間,固然三者的和必須爲100.因此任意一我的能夠用如下數組來表述:windows
G(A、B、C、A一、B一、C1)G表明男,M表明女。數組
舉例G11(80、50、40、十、30、60),表示男11號,擁有財富80、樣貌50、品格40,對異性品格的偏好爲:財富在意程度百分之十、樣貌在意程度百分之30、品格在意程度百分之60。數據結構
一樣爲了模型簡化,假設信息是徹底對稱的,便是說,每一個人都能一眼就能看清楚任意一我的的財富、樣貌、品格。app
仍是爲了模型簡化,我建模所用樣本爲男女各100個,即男女人數相同。dom
每一個人對異性的滿意度將以下定義:每一個偏好指標與異性的對應的稟賦指標相乘,三個指標的乘積再相加,即他(她)對某個異性的滿意度。編程語言
舉例G11(80、50、40、十、30、60)對M(50、60、80、40、十、50)的滿意度爲:
(10*50+30*60+60*80)= 7100分
相對的 MM 對 GG的滿意度則爲:
(40*80+10*50+50*40) = 5700分
好了,配對活動開始,設計的配對法則以下:
一、100個男方,順序,輪流從0號到99號女方中挑選本身最滿意的一位,而後向她發出配對邀請。
二、接受邀請最多的女方開始行動,對這些邀請的男性中,選擇最滿意的一位。
三、那麼這兩位配對成功,剔除出樣本,剩下的99對繼續這樣配對。
四、循環該配對法則,直到最後一對男女配對成功。
3、初賽階段要求:
一、編程語言爲java,C++或C語言任意一種;運行環境windows。
二、能讓用戶輸入本身的參數以及對各項數值的偏好,而後隨機生成100位男性100位女性(包括用戶在內。若是用爲男性則爲99男100女),數值所有隨機但需知足題設限制。按照上述規則給出一個匹配結果呈現給用戶。
三、若採用c/c++,要輸出可執行程序;若採用java,給出jar和bat。
四、在匹配時,若是發現有多個滿意度相同的對象,要求自身三個屬性(財富,外貌,品格)總和大的優先,若是再相同則id小的優先。若是有2位女士的選票相同,優先級規則同上。請把主角的id置爲最小值,以便在前2個條件相同狀況下,主角能夠優先選擇。
五、程序讀取指定的配置文件,獲取樣本,而後根據指定的輸入,輸出結果。同時會給出一組源數據和標準答案給學生自測。最後再讓學生根據不一樣的,指定的輸入,給出考試答案。
請點擊下載配置文件附件。附件中,male.txt,female.txt,players.txt 分別是男士樣本、女士樣本和主角樣本各 100位。 男女樣本中,每行都表明一位男士或女士的基本屬性,從左到右依次是ID, 樣貌,品格,財富 , 指望樣貌,指望品格,指望財富,沒有加入性別,須要在解析時手動添加,每一個txt文本的性別都是同樣的,請注意。另外,主角樣本中沒有ID屬性,換成了性別屬性,其中 0表示女性,1表示男性,其他屬性依次爲樣貌,品格,財富,指望樣貌 ,指望品格,指望財富。建議把主角的id都設置爲 -1,以便知足優先選擇的條件。
給出標準答案2組,用於考生自測:
1號主角(文本第一行),選擇的對象屬性爲(6,18,82,87,3,10)
2號主角(文本第二行),選擇的對象屬性爲(27,74,22,22,58,20)
同時要求考生輸出9號主角(0,72,55,53,8,87,5),19號主角(0,11,4,63,22,60,18),47號主角(1,19,8,21,1,53,46),83號主角(1,23,11,17,58,31,11),99號主角(1,26,66,1,78,11,11)以及100號主角(0,68,28,19,43,11,46)的選擇結果。
4、初賽階段審覈標準及評價細則
1. 功能分(40分)
若是學生最後答案錯誤,則該項得0分
若是答案正確,得40分
2. 代碼質量分(30分)
可讀性,整潔性,健壯性,可擴展性,封裝性
3. 用戶體驗(10分)
界面美觀,操做方便,有必要的信息提示
4. 代碼文檔質量(10分)
代碼清晰,易讀,註釋完整
5. 單元測試(10分)
關鍵函數或容易出錯部分應該有單元測試保證
#include <iostream> #include <fstream> #include <ostream> #include <vector> #include <algorithm> #include <ctime> #include <cstdlib> using namespace std; int M = 100; //表示匹配對數 //將人用類Person表示 struct Person{ int sex; int id; int fortune; int appearance; int character; int wFortune; int wAppearance; int wCharacter; int matchID; //匹配id號 int satisfyID; //當爲男性是指最滿意的對方id號,女性是指被邀請的數目 bool match; //是否成功,true表示已配對,false表示沒有 Person(int s=0, int i=-2, int f=0, int a=0, int c=0, int wf=0, int wa=0, int wc=0, int mi=0, int si=0, bool m=false): sex(s),id(i),fortune(f),appearance(a),character(c), wFortune(wf),wAppearance(wa),wCharacter(wc),matchID(mi),satisfyID(si),match(m){} }; //爲了在匹配時能惟一肯定滿意度順序,定義了一個輔助類SatDegree用於重載">"運算符 struct SatDegree{ int satD; //對對方的滿意度 int sum3; //對方三個屬性的總和 int id; //對方的id號 SatDegree(int sd = 0, int s3 = 0, int i = -2):satD(sd), sum3(s3), id(i){} }; // 數據結構,男性、女性都按id+1依次存儲,至關於hash表 vector<Person> male(M+1);//男性數組 vector<Person> female(M+1);//女性數組 //測試 vector<vector<int> > satm2fM(M+1,vector<int>(M+1,0)); vector<vector<int> > satf2mM(M+1,vector<int>(M+1,0)); vector<vector<int> > invitedM(M+1,vector<int>(2,0)); //重載">"號,當滿意度相等時,其屬性總和大的較大,但都相等時,id號小的大 bool operator >(const SatDegree& sd1, const SatDegree& sd2) { if (sd1.satD > sd2.satD) return true; else if (sd1.satD == sd2.satD) if (sd1.sum3 > sd2.sum3) return true; else if (sd1.sum3 == sd2.sum3) if (sd1.id <= sd2.id) //"=="號是考慮到本身同本身比較的狀況 return true; else return false; else return false; else return false; } ostream& operator<<(ostream& os, const Person& p) { return os << p.fortune << ',' << p.appearance << ',' << p.character << ',' << p.wFortune << ',' << p.wAppearance << ',' << p.wCharacter; } istream& operator>>(istream& is, Person& p) { char comma; return is >> p.id >> comma >> p.fortune >> comma >> p.appearance >> comma >> p.character >> comma >> p.wFortune >> comma >> p.wAppearance >> comma >> p.wCharacter; } int sum3(Person p) { return p.fortune+p.appearance+p.character; } SatDegree satisfy(Person p1,Person p2)//不一樣性別的p1對p2的滿意度 { SatDegree SD; SD.satD = p1.wFortune*p2.fortune+p1.wAppearance*p2.appearance+p1.wCharacter*p2.character; SD.sum3 = p2.fortune+p2.appearance+p2.character; SD.id = p2.id; return SD; } void matching()//匹配過程 { int i = 0, j = 0, k = 0, l = 0, minID = M-1, //最小的未匹配的id號 satM2FID = -2, //男性最滿意的女性的id satF2MID = -2, //女性最滿意的男性的id invitedN = 0, //女性的被邀請數臨時變量 matchedFID = -1, noMatchNo = M; //匹配成功的女性id號及配對數 SatDegree m2f, f2m,//男性對女性的滿意度、女性對男性的滿意度 satFD, satMD; //男性對女性的滿意度及女性對男性的滿意度的臨時變量 //vector<int> atemp(M,-1), btemp(M,-1); for ( ; noMatchNo > 0; --noMatchNo) { //測試 //cout << "匹配第" << noMatchNo << "隊狀況:" << endl; for (i = 0; i<= M; ++i) //依次尋找未匹配男性i的最滿意id號及得到對應的女性邀請數目 { if (!male[i].match && male[i].id >= -1) //male[0]存儲的是主角或者空,空時不處理 { for (j = 0; j <= M; ++j) { if (female[j].id < -1)//female[0]存儲的是主角或者空,空時不處理 continue; m2f = satisfy(male[i],female[j]); satm2fM[i][j] = m2f.satD; if (m2f > satFD && !female[j].match) { satM2FID = j-1; //id號是hash表序號-1 satFD = m2f; } //測試: //cout << "男性id=" << i-1 << ",女性id=" << j-1 << ",對女性的滿意度" << m2f.satD << endl << endl; } ++female[satM2FID+1].satisfyID; //對應女性的被邀請數目加1 male[i].satisfyID = satM2FID; satFD.satD = 0; satFD.sum3 = 0; satFD.id = -2; //重置臨時的男對女滿意度 //測試: //if (noMatchNo == M) // cout << "男性id=" << i-1 << ",最喜歡的女性id=" << satM2FID << endl; } } //測試 //cout << endl << "尋找邀請數最多的女性:" << endl; for (k = 0; k <= M; ++k) //尋找邀請數最多的女性id { if (female[k].id < -1)//female[0]存儲的是主角或者空,空時不處理 continue; if (!female[k].match) //k的id不小於matchedFID if ((female[k].satisfyID > invitedN) ||//k的選票大於matchedID的 ((female[k].satisfyID == invitedN) && //k的選票等於matchedID的 (sum3(female[k]) > sum3(female[matchedFID+1]))))//k的屬性和大於matchedID的 { invitedN = female[k].satisfyID; matchedFID = k-1; } } invitedM[M-noMatchNo][0] = matchedFID; invitedM[M-noMatchNo][1] = invitedN; //測試 //cout << "邀請數最多的女性id=" << matchedFID << ",邀請數" << invitedN << endl // << endl << "尋找匹配的男性:" << endl; invitedN = 0; //被邀請數臨時變量重置爲0 for (l = 0; l <= M; ++l) //尋找匹配的男性 { if (male[l].id < -1) //male[0]存儲的是主角或者空,空時不處理 continue; f2m = satisfy(female[matchedFID+1],male[l]);satf2mM[matchedFID+1][l] = f2m.satD; if (male[l].satisfyID == matchedFID && !male[l].match && f2m > satMD) { satF2MID = l-1; satMD = f2m; } } //測試 //cout << "匹配男性id=" << satF2MID << ",滿意度" << satMD.satD << endl; male[satF2MID+1].match = true; male[satF2MID+1].matchID = matchedFID; satMD = 0;satMD.sum3 = 0;satMD.id = -2;//重置臨時的女對男滿意度 //測試 //atemp[satF2MID] = satF2MID; btemp[matchedFID] = matchedFID; //cout << noMatchNo << "," << satF2MID << "," << matchedFID << endl; minID = M; for (k = 0; k <= M; ++k)//刪除未匹配的女性的邀請數且將matchedFID重置爲未匹配女性中的最小id號 { if (female[k].id < -1)//female[0]存儲的是主角或者空,空時不處理 continue; if (!female[k].match && k !=matchedFID+1 && female[k].satisfyID <= female[matchedFID+1].satisfyID) { female[k].satisfyID = 0; if ((k-1) < minID) minID = k-1; } } female[matchedFID+1].match = true; //刪除匹配的女性 female[matchedFID+1].matchID = satF2MID; matchedFID = minID; } } int random(int x) { return rand()%x; } //隨機初始化一我的的屬性(ID除外) Person randPerson() { Person p; p.fortune = random(M)+1; p.appearance = random(M)+1; p.character = random(M)+1; p.wFortune = random(M-2)+1; p.wAppearance = random(M-p.wFortune)+1; p.wCharacter = M-p.wFortune-p.wAppearance; return p; } //隨機生成數據、初始化並將其保存到對應的hash表中 void generateData(Person user) { vector<int> randSort1(M), randSort2(M); Person p1, p2; int i = 0; ofstream ofs1, ofs2; //任意排列0-M之間的數 for (i = 0; i<M; ++i) { randSort1[i] = i; randSort2[i] = i; } random_shuffle(randSort1.begin(),randSort1.end()); random_shuffle(randSort2.begin(),randSort2.end()); //隨機生成男性和女性數據 ofs1.open("male1.txt",ios_base::out); ofs2.open("female1.txt",ios_base::out); for (i = 0; i<M; ++i) { p1 = randPerson(); p1.sex = 1;p1.id = randSort1[i]; if (1 == user.sex && 0 == randSort1[i]) //用戶是男性則將其替換爲生成的0號id數據 p1 = user; male[p1.id+1] = p1; ofs1 << p1.id << "," << p1 << endl; p2 = randPerson(); p2.sex = 0;p2.id = randSort2[i]; if (1 == user.sex && 0 == randSort2[i]) //用戶是女性則將其替換爲生成的0號id數據 p1 = user; female[p2.id+1] = p2; ofs2 << p2.id << "," << p2 << endl; } ofs1.close(); ofs2.close(); } //讀入文本數據並初始化以及進行測試 void readData() { Person p1, p2; ifstream ifs1, ifs2; ifs1.open("male.txt",ios_base::in); ifs2.open("female.txt",ios_base::in); while((ifs1 >> p1) && (ifs2 >> p2)) { male[p1.id+1] = p1; female[p2.id+1] = p2; } ifs1.close(); ifs2.close(); } //將結果保存到文本文件中 void result() { int i = 0, j = 0; ofstream ofs1, ofs2, ofs3, ofs4; ofs1.open("satm2fM.txt",ios_base::out); //保存男對女的滿意度矩陣 ofs2.open("satf2mM.txt",ios_base::out); //保存女對男的滿意度矩陣 ofs3.open("matched.txt",ios_base::out); //保存匹配結果 ofs4.open("invitedM.txt",ios_base::out);//保存女性被邀請的最多的id號及次數 for (i = 0; i <=M; ++i) { for (j = 0; j <= M; ++j) { ofs1 << satm2fM[i][j] <<","; ofs2 << satf2mM[i][j] <<","; } ofs1 << endl << endl; ofs2 << endl << endl; } for (i = 0; i <= M; ++i) { ofs3 << i << ":" << male[i].id <<"," << male[i].matchID << endl; ofs4 << i << ":" << invitedM[i][0] <<"," << invitedM[i][1] << endl; } ofs1.close(); ofs2.close(); ofs3.close(); ofs4.close(); } //程序開始 void startProg() { char ch, //用於接收用戶選項:是想測試仍是直接計算 E = 'n', //用於接收用戶輸入:是否退出程序 comma; int line = 0; //指定讀入的行 Person user; ifstream ifs; cout << "===========數字化婚姻配對嘗試仿真程序===========" << endl; cout << "主角的信息包括:性別,樣貌,品格,財富,指望樣貌,指望品格,指望財富:" << endl << "輸入時請按該要求依次輸入主角信息!" << endl << "示例1:1,80,5,29,25,62,13;示例2:0,1,99,78,84,14,2" << endl; cout << "您是想測試用例仍是本身輸入數據進行計算?(測試輸入T/t,計算輸入C/c)" << endl; cin >> ch; if ('T' == ch || 't' == ch)//測試 { ifs.open("players.txt",ios_base::in); ifs.seekg(0,ifs.end); int line_lenght = ifs.tellg()/M; //計算players.txt文件每一行的長度 while (E != 'Y' && E != 'y') { readData(); cout << "請輸入所給用戶示例文件players.txt中主角所在的行數:"; cin >> line; ifs.seekg((line-1)*line_lenght,ifs.beg); ifs >> user.sex >> comma >> user.fortune >> comma >> user.appearance >> comma >> user.character >> comma >> user.wFortune >> comma >> user.wAppearance >> comma >> user.wCharacter; user.id = -1; cout << line << "號主角的信息爲:" << endl; cout << user << endl; if (1 == user.sex) //主角是男性 { male[0] = user; matching(); cout << "與主角匹配的屬性值爲:" << female[male[0].matchID+1] << endl; } else//主角是女性 { female[0] = user; matching(); cout << "與主角匹配的屬性值爲:" << male[female[0].matchID+1] << endl; } result(); cout << "是否結束?(是Y/y)或(否N/n):"; cin >> E; } ifs.close(); } else if ('C' == ch || 'c' == ch) //計算 { while (E != 'Y' && E != 'y') { cout << "請輸入主角的屬性值:"; cin >> user.sex >> comma >> user.fortune >> comma >> user.appearance >> comma >> user.character >> comma >> user.wFortune >> comma >> user.wAppearance >> comma >> user.wCharacter; user.id = 0; generateData(user);//生成數據 matching(); if (1 == user.sex) //主角是男性 cout << "與主角匹配的屬性值爲:" << female[male[user.id+1].matchID+1] << endl; if (0 == user.sex) //主角是男性 cout << "與主角匹配的屬性值爲:" << male[female[user.id+1].matchID+1] << endl; result(); cout << "是否結束:是Y/y或否N/n:"; cin >> E; } } else cout << "error!" << endl; } int main() { srand((int)time(0)); startProg(); return 0; }