Task: Stable marriage problem







Python: import copy

guyprefers = {
 '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']}
galprefers = {
 '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']}

guys = sorted(guyprefers.keys())
gals = sorted(galprefers.keys())


def check(engaged):
    inverseengaged = dict((v,k) for k,v in engaged.items())
    for she, he in engaged.items():
        shelikes = galprefers[she]
        shelikesbetter = shelikes[:shelikes.index(he)]
        helikes = guyprefers[he]
        helikesbetter = helikes[:helikes.index(she)]
        for guy in shelikesbetter:
            guysgirl = inverseengaged[guy]
            guylikes = guyprefers[guy]
            if guylikes.index(guysgirl) > guylikes.index(she):
                print("%s and %s like each other better than "
                      "their present partners: %s and %s, respectively"
                      % (she, guy, he, guysgirl))
                return False
        for gal in helikesbetter:
            girlsguy = engaged[gal]
            gallikes = galprefers[gal]
            if gallikes.index(girlsguy) > gallikes.index(he):
                print("%s and %s like each other better than "
                      "their present partners: %s and %s, respectively"
                      % (he, gal, she, girlsguy))
                return False
    return True

def matchmaker():
    guysfree = guys[:]
    engaged  = {}
    guyprefers2 = copy.deepcopy(guyprefers)
    galprefers2 = copy.deepcopy(galprefers)
    while guysfree:
        guy = guysfree.pop(0)
        guyslist = guyprefers2[guy]
        gal = guyslist.pop(0)
        fiance = engaged.get(gal)
        if not fiance:
            
            engaged[gal] = guy
            print("  %s and %s" % (guy, gal))
        else:
            
            galslist = galprefers2[gal]
            if galslist.index(fiance) > galslist.index(guy):
                
                engaged[gal] = guy
                print("  %s dumped %s for %s" % (gal, fiance, guy))
                if guyprefers2[fiance]:
                    
                    guysfree.append(fiance)
            else:
                
                if guyslist:
                    
                    guysfree.append(guy)
    return engaged


print('\nEngagements:')
engaged = matchmaker()

print('\nCouples:')
print('  ' + ',\n  '.join('%s is engaged to %s' % couple
                          for couple in sorted(engaged.items())))
print()
print('Engagement stability check PASSED'
      if check(engaged) else 'Engagement stability check FAILED')

print('\n\nSwapping two fiances to introduce an error')
engaged[gals[0]], engaged[gals[1]] = engaged[gals[1]], engaged[gals[0]]
for gal in gals[:2]:
    print('  %s is now engaged to %s' % (gal, engaged[gal]))
print()
print('Engagement stability check PASSED'
      if check(engaged) else 'Engagement stability check FAILED')





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;