Task: Stable marriage problem


C++: #include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;

const char *men_data[][11] = {
    { "abe",  "abi","eve","cath","ivy","jan","dee","fay","bea","hope","gay" },
    { "bob",  "cath","hope","abi","dee","eve","fay","bea","jan","ivy","gay" },
    { "col",  "hope","eve","abi","dee","bea","fay","ivy","gay","cath","jan" },
    { "dan",  "ivy","fay","dee","gay","hope","eve","jan","bea","cath","abi" },
    { "ed",   "jan","dee","bea","cath","fay","eve","abi","ivy","hope","gay" },
    { "fred", "bea","abi","dee","gay","eve","ivy","cath","jan","hope","fay" },
    { "gav",  "gay","eve","ivy","bea","cath","abi","dee","hope","jan","fay" },
    { "hal",  "abi","eve","hope","fay","ivy","cath","jan","bea","gay","dee" },
    { "ian",  "hope","cath","dee","gay","bea","abi","fay","ivy","jan","eve" },
    { "jon",  "abi","fay","jan","gay","eve","bea","dee","cath","ivy","hope" }
};
 
const char *women_data[][11] = {
    { "abi",  "bob","fred","jon","gav","ian","abe","dan","ed","col","hal" },
    { "bea",  "bob","abe","col","fred","gav","dan","ian","ed","jon","hal" },
    { "cath", "fred","bob","ed","gav","hal","col","ian","abe","dan","jon" },
    { "dee",  "fred","jon","col","abe","ian","hal","gav","dan","bob","ed" },
    { "eve",  "jon","hal","fred","dan","abe","gav","col","ed","ian","bob" },
    { "fay",  "bob","abe","ed","ian","jon","dan","fred","gav","col","hal" },
    { "gay",  "jon","gav","hal","fred","bob","abe","col","ed","dan","ian" },
    { "hope", "gav","jon","bob","abe","ian","dan","hal","ed","col","fred" },
    { "ivy",  "ian","col","hal","gav","fred","bob","abe","ed","jon","dan" },
    { "jan",  "ed","hal","gav","abe","bob","jon","col","ian","fred","dan" }
};

typedef vector<string> PrefList;
typedef map<string, PrefList> PrefMap;
typedef map<string, string> Couples;


bool prefers(const PrefList &prefer, const string &first, const string &second)
{
    for (PrefList::const_iterator it = prefer.begin(); it != prefer.end(); ++it)
    {
        if (*it == first) return true;
        if (*it == second) return false;
    }
    return false; 
}

void check_stability(const Couples &engaged, const PrefMap &men_pref, const PrefMap &women_pref)
{
    cout << "Stablility:\n";
    bool stable = true;
    for (Couples::const_iterator it = engaged.begin(); it != engaged.end(); ++it)
    {
        const string &bride = it->first;
        const string &groom = it->second;
        const PrefList &preflist = men_pref.at(groom);

        for (PrefList::const_iterator it = preflist.begin(); it != preflist.end(); ++it)
        {
            if (*it == bride) 
                break;
            if (prefers(preflist, *it, bride) && 
                prefers(women_pref.at(*it), groom, engaged.at(*it))) 
            {
                cout << "\t" << *it <<
                    " prefers " << groom <<
                    " over " << engaged.at(*it) <<
                    " and " << groom <<
                    " prefers " << *it <<
                    " over " << bride << "\n";
                stable = false;
            }
        }
    }
    if (stable) cout << "\t(all marriages stable)\n";
}

int main()
{
    PrefMap men_pref, women_pref;
    queue<string> bachelors;

    
    for (int i = 0; i < 10; ++i) 
    {
        for (int j = 1; j < 11; ++j) 
        {
              men_pref[  men_data[i][0]].push_back(  men_data[i][j]);
            women_pref[women_data[i][0]].push_back(women_data[i][j]);
        }
        bachelors.push(men_data[i][0]);
    }

    Couples engaged; 

    cout << "Matchmaking:\n";
    while (!bachelors.empty())
    {
        const string &suitor = bachelors.front();
        const PrefList &preflist = men_pref[suitor];

        for (PrefList::const_iterator it = preflist.begin(); it != preflist.end(); ++it)
        {
            const string &bride = *it;

            if (engaged.find(bride) == engaged.end()) 
            {
                cout << "\t" << bride << " and " << suitor << "\n";
                engaged[bride] = suitor; 
                break;
            }

            const string &groom = engaged[bride];

            if (prefers(women_pref[bride], suitor, groom))
            {
                cout << "\t" << bride << " dumped " << groom << " for " << suitor << "\n";
                bachelors.push(groom); 
                engaged[bride] = suitor; 
                break;
            }
        }
        bachelors.pop(); 
    }

    cout << "Engagements:\n";
    for (Couples::const_iterator it = engaged.begin(); it != engaged.end(); ++it)
    {
        cout << "\t" << it->first << " and " << it->second << "\n";
    }

    check_stability(engaged, men_pref, women_pref);

    cout << "Perturb:\n";
    std::swap(engaged["abi"], engaged["bea"]);
    cout << "\tengage abi with " << engaged["abi"] << " and bea with " << engaged["bea"] << "\n";

    check_stability(engaged, men_pref, women_pref);
}










Ada: package Preferences
is

   type Guy_X is (no_guy, abe, bob, col, dan, ed, fred, gav, hal, ian, jon);
   subtype Guy is Guy_X range Guy_X'Succ(Guy_X'First) .. Guy_X'Last;

   type Girl_X is (no_girl, abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan);
   subtype Girl is Girl_X range Girl_X'Succ(Girl_X'First) .. Girl_X'Last;

   type Extended_Rank is range 0 .. 10;
   subtype Rank is Extended_Rank range 1 .. Extended_Rank'Last;

   type His_Rank is array (Rank) of Girl;
   type He_Prefers is array (Guy) of His_Rank;

   Guys_Like : constant He_Prefers := He_Prefers'(
     abe  => His_Rank'(abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay),
     bob  => His_Rank'(cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay),
     col  => His_Rank'(hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan),
     dan  => His_Rank'(ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi),
     ed   => His_Rank'(jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay),
     fred => His_Rank'(bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay),
     gav  => His_Rank'(gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay),
     hal  => His_Rank'(abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee),
     ian  => His_Rank'(hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve),
     jon  => His_Rank'(abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope));

   type Her_Rank is array(Rank) of Guy;
   type She_Prefers is array (Girl) of Her_Rank;

   Girls_Like : constant She_Prefers := She_Prefers'(
     abi  => Her_Rank'(bob, fred, jon, gav, ian, abe, dan, ed, col, hal),
     bea  => Her_Rank'(bob, abe, col, fred, gav, dan, ian, ed, jon, hal),
     cath => Her_Rank'(fred, bob, ed, gav, hal, col, ian, abe, dan, jon),
     dee  => Her_Rank'(fred, jon, col, abe, ian, hal, gav, dan, bob, ed),
     eve  => Her_Rank'(jon, hal, fred, dan, abe, gav, col, ed, ian, bob),
     fay  => Her_Rank'(bob, abe, ed, ian, jon, dan, fred, gav, col, hal),
     gay  => Her_Rank'(jon, gav, hal, fred, bob, abe, col, ed, dan, ian),
     hope => Her_Rank'(gav, jon, bob, abe, ian, dan, hal, ed, col, fred),
     ivy  => Her_Rank'(ian, col, hal, gav, fred, bob, abe, ed, jon, dan),
     jan  => Her_Rank'(ed, hal, gav, abe, bob, jon, col, ian, fred, dan));

end Preferences;