Stable Matching (Gale Sharpley Algorithm), galesharpley
Generate boys_rankings.txt and girls_rankings.txt
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <sstream>#include <algorithm>#include <vector>#include <ctime>#include <fstream>using namespace std;vector<string> gen_boys(int number){ vector<string> result; for(int i = 0; i < number; i++){ string boy = "B"; string s; stringstream ss; ss << i; ss >> s; boy.append(s); result.push_back(boy); } return result;}vector<string> gen_girls(int number){ vector<string> result; for(int i = 0; i < number; i++){ string boy = "G"; string s; stringstream ss; ss << i; ss >> s; boy.append(s); result.push_back(boy); } return result;}vector<string> gen_ranking(vector<string> candidate){ random_shuffle(candidate.begin(), candidate.end()); return candidate;}void write_rankings(vector<string> people, vector<vector<string> > rankings, string out_file){ ofstream ofs(out_file.c_str()); if(ofs.fail()){ cerr << "Error: " << out_file << endl; return; } for(int i = 0; i < people.size(); i++){ ofs << people[i] << ":"; for(int j = 0; j < rankings[i].size(); j++){ ofs << " " << rankings.at(i).at(j); } ofs << endl; } ofs.close();}int main(int argc, char ** argv){ srand(time(NULL)); int n = 200; vector<string> boys = gen_boys(n); vector<string> girls = gen_girls(n); vector<vector<string> > boys_rankings; vector<vector<string> > girls_rankings; for(int i = 0; i < n; i++){ boys_rankings.push_back(gen_ranking(girls)); girls_rankings.push_back(gen_ranking(boys)); } write_rankings(boys, boys_rankings, "boys_rankings.txt"); write_rankings(girls, girls_rankings, "girls_rankings.txt"); return 1;}
The following is the implementation of the Gale_Sharpley algorithm:
/******************************************************* Projects : Implementation of Gale_Shapley algorithm* Author : johnsondu* Time : 2014-10-20 21:18*******************************************************/#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <fstream>#include <map>#include <vector>#include <cstring>#include <string>using namespace std;// The max size of the number of the boy.const int MAXN = 1000;// STL map, map boy's name to integer IDmap<string, int> boy;// STL map, map girl's name to integer IDmap<string, int> girl;// STL map, map corresponding boy's integer id to original string namemap<int, string> boyName;// STL map, map corresponding girl's integer id to original string namemap<int, string> girlName;// boy's preference ranking listint boysRankings[MAXN][MAXN];// girl's preference ranking listint girlsRankings[MAXN][MAXN];// the partner that boy matched. if no, marked as -1int boysPartner[MAXN];// the partner that girl matched. if no, marked as -1int girlsPartner[MAXN];/******************************************************** function description:* let every boy and girl have it's own integer identity.* key variable: <string, int>(map string name to integer* id), <int, string>(map integer id to original string* name)********************************************************/void SerialNumber(int &n){ ifstream in1("boys_rankings.txt"); ifstream in2("girls_rankings.txt"); string str; int idb = 0; // boy's id int idg = 0; // girl's id while(getline(in1, str)){ string name = ""; int i = 0; // get boys's name while(str[i] != ':') name += str[i ++]; // map string to int. boy[name] = idb ; boyName[idb] = name; idb ++; // get the number of boys. n ++; } while(getline(in2, str)){ string name = ""; int i = 0; // get boys's name while(str[i] != ':') name += str[i ++]; // map string to int. girl[name] = idg; girlName[idg] = name; idg ++; } return;}/********************************************** function description:* Rereading two files, and get corresponding* preference list of boys and girls. Save it* in two dimension array: girlsRankings and* boysRankings.*******************************************/void GetRankings(const int n){ ifstream in1("boys_rankings.txt"); ifstream in2("girls_rankings.txt"); string str; // boy's id. int id = 0; while(getline(in1, str)){ string gname; int i = 0; int cnt = 0; while(str[i] != ' ') i ++; if(str[i] == ' ') i ++; for(; i < str.size();) { gname = ""; while(str[i] != ' ' && i < str.size()) { gname += str[i]; i ++; } boysRankings[id][cnt ++] = girl[gname]; if(str[i] == ' ') i ++; } id ++; } // girls id; id = 0; while(getline(in2, str)){ string bname; // string size index. int i = 0; // the rankings in the girl's list. int cnt = 0; // prefix guarantee while(str[i] != ' ') i ++; if(str[i] == ' ') i ++; for(; i < str.size();) { bname = ""; while(str[i] != ' ' && i < str.size()) { bname += str[i]; i ++; } girlsRankings[id][cnt ++] = boy[bname]; if(str[i] == ' ') i ++; } id ++; } return ;}/************************************** function description:* set status for boys and girls,* marked -1, no partner.**************************************/void InitStatus(const int n){ for(int i = 0; i < n; i ++) { boysPartner[i] = -1; girlsPartner[i] = -1; }}/***************************************** function description:* when one boy propose to one girl, and* that girl already have a partner, this* function is used for get ratings of* two boys in that girl's preference list.*****************************************/int GetId(int boyId, int gId, const int n){ for(int i = 0; i < n; i ++) { if(girlsRankings[gId][i] == boyId) return i; } return -1;}/***************************************** function description:* once a man have dumped by a girl, set* his status to no partner, and set his* preference list of that girl as -1,* stand for have been proposed before.*****************************************/void SetStatus(int boyId, int girlId, const int n){ boysPartner[boyId] = -1; for(int i = 0; i < n; i ++) if(boysRankings[boyId][i] == girlId){ boysRankings[boyId][i] = -1; return; }}/***************************************** function description:* Implementation of Gale_Shapley algorithm*****************************************/void StableMatch(const int n){ InitStatus(n); while(true) { bool flag = false; bool endOfFor = false; // guarantee all the boys have a partner. for(int i = 0; i < n; i ++){ if(boysPartner[i] == -1 || girlsPartner[i] == -1) { flag = true; break; } } if(!flag) break; // for boy who have no partner. for(int i = 0; i < n; i ++) { if(boysPartner[i] == -1){ for(int j = 0; j < n; j ++){ // Since in the list of preference, j had rejected before. if(boysRankings[i][j] == -1) continue; // if j have no partner, then accept. if(girlsPartner[boysRankings[i][j]] == -1){ boysPartner[i] = boysRankings[i][j]; girlsPartner[boysRankings[i][j]] = i; endOfFor = true; break; } else{ // judge whether match is stable or not int useId = GetId(girlsPartner[boysRankings[i][j]], boysRankings[i][j], n); int curId = GetId(i, boysRankings[i][j], n); // if not stable if(curId < useId){ // girl's partner's list, set -1 to mean the girl have rejected. SetStatus(girlsPartner[boysRankings[i][j]], boysRankings[i][j], n); boysPartner[i] = boysRankings[i][j]; girlsPartner[boysRankings[i][j]] = i; endOfFor = true; break; } } } } // find a partner, break out of the loop. if(endOfFor) break; } }}/***************************************** function description:* print out result.*****************************************/void Print(const int n){ freopen("result.txt", "w", stdout); cout << "The Matching Results are follows:" << endl; for(int i = 0; i < n; i ++){ cout << boyName[i] << "--" << girlName[boysPartner[i]] << " " << endl; }}/***************************************** function description:* Main function*****************************************/int main(){ int n = 0; // let every boy and girl have it's own identity. // and get integer ranking array list. SerialNumber(n); // get rankings.S GetRankings(n); // Stable match StableMatch(n); // Print solution Print(n); return 0;}