Stable Matching (Gale Sharpley Algorithm)

以下为数据生成函数,生成boys_rankings.txt 和 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;
}

以下为Gale_Sharpley算法实现:

/******************************************************
*   Projects : Implementation of Gale_Shapley algorithm
*   Author   : du zhenlin(johnsondu)
*   studentID: 201428013229100
*   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 ID
map<string, int> boy;
// STL map, map girl's name to integer ID
map<string, int> girl;
// STL map, map corresponding boy's integer id to original string name
map<int, string> boyName;
// STL map, map corresponding girl's integer id to original string name
map<int, string> girlName;
// boy's preference ranking list
int boysRankings[MAXN][MAXN];
// girl's preference ranking list
int girlsRankings[MAXN][MAXN];
// the partner that boy matched. if no, marked as -1
int boysPartner[MAXN];
// the partner that girl matched. if no, marked as -1
int 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;
}
时间: 2025-02-01 12:44:45

Stable Matching (Gale Sharpley Algorithm)的相关文章

Stable Matching Problem

The Stable Matching Problem originated, in part, in 1962, when David Gale and Lloyd Shapley, two mathematical economists, asked the question: Could one design a college admissions process, or a job recruiting process, that was self-enforcing? What di

稳定匹配 - Stable Matching

这篇文章将会对稳定匹配算法进行介绍及Python代码的实现,第一部分会针对稳定匹配的Gale-Shapley算法进行解析,第二部分就是用Python对该算法进行实现. 一.稳定匹配算法原理 1.1 介绍 稳定匹配(Stable Matching)问题就是假设现在有N个男生和N个女生跳舞选择伴侣,然后最开始的时候男.女生按照下面情况对彼此进行排序选择舞伴(见图1): 每个男生都对女生按照最喜欢到最不喜欢进行排序: 同样的,女生也是按照最喜欢的到最不喜欢对男生进行排序. 算法目标:每个男都找到唯一一

Maximum Cardinality Bipartite Matching: Augmenting Path Algorithm

http://www.csie.ntnu.edu.tw/~u91029/Matching.html 1 int nx,ny; 2 int mx[N],my[N]; 3 bool vy[N]; 4 bool g[N][N]; 5 6 int decode(int x,int y) {return x*15+y;} 7 8 bool dfs(int x) 9 { 10 for(int y=0;y<ny;++y) 11 if(g[x][y] && !vy[y]) 12 { 13 vy[y]

【算法】恋爱中的博弈论(stable matching)(附带源码)

思路源自知乎:恋爱中有那些博弈?,主要是@尼克余 的回答.感谢他.然后原文有些描述不清楚的,我直接就按照我的理解补充上去了. 注:本文采用C#实现 首先假设一个虚拟世界,这个世界中分别有N个男生,N个女生,男生与女生数量完全一样,男生女生都有一个心仪对象列表,不同的人的心仪对象列表都是随机的,在心仪对象列表排名越前面,说明对于他(她)来说越喜欢.男生能向女生表白,女生不能向男生表白,女生能接受或者拒绝男生的表白. 男生首先会向对他最喜欢的女生表白,然后是次喜欢的,依次下去表白.而女生则通过对表白

Stable Matching 稳定匹配 婚姻算法 shapley 算法

作者:jostree  转载请注明出处 http://www.cnblogs.com/jostree/p/4051286.html 稳定匹配问题:有N男N女,每个人对于异性都一个排名,先需要得到一种稳定的匹配,即不会出现一个匹配中的人与另一个匹配中的异性对对方的排名均高于目前配对的人的排名. shapley算法: 每次取出一个单身男生,让他向没有拒绝过她的女生中其排名最高人表白,若该女生没有对象则配对成功,否则与其当前的对象排名进行对比,如果当前对象排名较高,则拒绝表白男生,否则dump掉目前对

XShell 无法匹配的outgoing encryption算法 ,No matching outgoing encryption algorithm found

在链接的属性(SSH -> 安全性) 的加密算法列表中选择 aes256-ctr, mac加密列表中选择hmac-sha2-256,保存即可 To enable hmac-sha2-256 and aes256-ctr go to the SSH > Security page in the session properties. Click the Edit button for Encryption and MAC. Make sure everything is selected for

Algorithm | Sort

Bubble sort Bubble sort, sometimes incorrectly referred to as sinking sort, is a simple sorting algorithm that works by repeatedly stepping through the list to be sorted, comparing each pair of adjacent items and swapping them if they are in the wron

[Stanford Algorithms: Design and Analysis, Part 2]

Specific topics in Part 2 include: greedy algorithms (scheduling, minimum spanning trees, clustering, Huffman codes), dynamic programming (knapsack, sequence alignment, optimal search trees, shortest paths), NP-completeness and what it means for the

用匈牙利算法求二分图的最大匹配

转载大神的!! 什么是二分图,什么是二分图的最大匹配,这些定义我就不讲了,网上随便都找得到.二分图的最大匹配有两种求法,第一种是最大流(我在此假设读者已有网络流的知识):第二种就是我现在要讲的匈牙利算法.这个算法说白了就是最大流的算法,但是它跟据二分图匹配这个问题的特点,把最大流算法做了简化,提高了效率.匈牙利算法其实很简单,但是网上搜不到什么说得清楚的文章.所以我决定要写一下. 最大流算法的核心问题就是找增广路径(augment path).匈牙利算法也不例外,它的基本模式就是: 初始时最大匹