Stable marriage problem: Difference between revisions
Content added Content deleted
(→Tcl: Added implementation) |
|||
Line 44: | Line 44: | ||
# [http://www.cs.columbia.edu/~evs/intro/stable/writeup.html The Stable Marriage Problem]. (Eloquent description and background information). |
# [http://www.cs.columbia.edu/~evs/intro/stable/writeup.html The Stable Marriage Problem]. (Eloquent description and background information). |
||
# [http://sephlietz.com/gale-shapley/ Gale-Shapley Algorithm Demonstration]. |
# [http://sephlietz.com/gale-shapley/ Gale-Shapley Algorithm Demonstration]. |
||
=={{header|D}}== |
|||
D v.2, adapted from the Python and Java versions. |
|||
<lang d>import std.stdio: writeln, writefln; |
|||
import std.array: popFront; |
|||
import std.algorithm: indexOf, swap; |
|||
import std.string: split, splitlines; |
|||
string[string] matchmaker(const string[][string] guyPrefers, |
|||
const string[][string] girlPrefers) { |
|||
string[string] engagedTo; |
|||
string[] freeGuys = guyPrefers.keys; |
|||
while (freeGuys.length) { |
|||
const auto string thisGuy = freeGuys[0]; |
|||
freeGuys.popFront(); |
|||
const auto thisGuyPrefers = guyPrefers[thisGuy]; |
|||
foreach (girl; thisGuyPrefers) { |
|||
if (girl !in engagedTo) { // girl is free |
|||
engagedTo[girl] = thisGuy; |
|||
break; |
|||
} else { |
|||
string otherGuy = engagedTo[girl]; |
|||
const string[] thisGirlPrefers = girlPrefers[girl]; |
|||
if (thisGirlPrefers.indexOf(thisGuy) < thisGirlPrefers.indexOf(otherGuy)) { |
|||
// this girl prefers this guy to the guy she's engagedTo to |
|||
engagedTo[girl] = thisGuy; |
|||
freeGuys ~= otherGuy; |
|||
break; |
|||
} |
|||
// else no change, keep looking for this guy |
|||
} |
|||
} |
|||
} |
|||
return engagedTo; |
|||
} |
|||
bool check(bool doPrint=false)(const string[string] engagedTo, |
|||
const string[][string] guyPrefers, |
|||
const string[][string] galPrefers) { |
|||
enum MSG = "%s likes %s better than %s and %s likes %s better than their current partner"; |
|||
string[string] inverseEngaged; |
|||
foreach (k, v; engagedTo) |
|||
inverseEngaged[v] = k; |
|||
foreach (she, he; engagedTo) { |
|||
const auto sheLikes = galPrefers[she]; |
|||
const auto sheLikesBetter = sheLikes[0 .. sheLikes.indexOf(he)]; |
|||
const auto heLikes = guyPrefers[he]; |
|||
const auto heLikesBetter = heLikes[0 .. heLikes.indexOf(she)]; |
|||
foreach (guy; sheLikesBetter) { |
|||
const auto guysGirl = inverseEngaged[guy]; |
|||
const auto guyLikes = guyPrefers[guy]; |
|||
if (guyLikes.indexOf(guysGirl) > guyLikes.indexOf(she)) { |
|||
static if (doPrint) |
|||
writefln(MSG, she, guy, he, guy, she); |
|||
return false; |
|||
} |
|||
} |
|||
foreach (gal; heLikesBetter) { |
|||
const auto girlsGuy = engagedTo[gal]; |
|||
const auto galLikes = galPrefers[gal]; |
|||
if (galLikes.indexOf(girlsGuy) > galLikes.indexOf(he)) { |
|||
static if (doPrint) |
|||
writefln(MSG, he, gal, she, gal, he); |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
void main() { |
|||
auto guyData = "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"; |
|||
auto galData = "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"; |
|||
string[][string] guyPrefers, galPrefers; |
|||
foreach (line; guyData.splitlines()) |
|||
guyPrefers[split(line)[0]] = split(line)[1..$]; |
|||
foreach (line; galData.splitlines()) |
|||
galPrefers[split(line)[0]] = split(line)[1..$]; |
|||
writeln("Engagements:"); |
|||
auto engagedTo = matchmaker(guyPrefers, galPrefers); |
|||
writeln("\nCouples:"); |
|||
string[] parts; |
|||
foreach (k; engagedTo.keys.sort) |
|||
writefln("%s is engagedTo to %s", k, engagedTo[k]); |
|||
writeln(); |
|||
bool c = check!(true)(engagedTo, guyPrefers, galPrefers); |
|||
writeln("Marriages are ", c ? "stable" : "unstable"); |
|||
writeln("\n\nSwapping two fiances to introduce an error"); |
|||
auto gals = galPrefers.keys.sort; |
|||
swap(engagedTo[gals[0]], engagedTo[gals[1]]); |
|||
foreach (gal; gals[0 .. 2]) |
|||
writefln(" %s is now engagedTo to %s", gal, engagedTo[gal]); |
|||
writeln(); |
|||
c = check!(true)(engagedTo, guyPrefers, galPrefers); |
|||
writeln("Marriages are ", c ? "stable" : "unstable"); |
|||
}</lang> |
|||
Output: |
|||
<pre>Engagements: |
|||
Couples: |
|||
abi is engagedTo to jon |
|||
bea is engagedTo to fred |
|||
cath is engagedTo to bob |
|||
dee is engagedTo to col |
|||
eve is engagedTo to hal |
|||
fay is engagedTo to dan |
|||
gay is engagedTo to gav |
|||
hope is engagedTo to ian |
|||
ivy is engagedTo to abe |
|||
jan is engagedTo to ed |
|||
Marriages are stable |
|||
Swapping two fiances to introduce an error |
|||
abi is now engagedTo to fred |
|||
bea is now engagedTo to jon |
|||
fred likes bea better than abi and bea likes fred better than their current partner |
|||
Marriages are unstable</pre> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
This is not a direct translation of [[#Python|Python]], but it's fairly close (especially the stability check). |
This is not a direct translation of [[#Python|Python]], but it's fairly close (especially the stability check). |
||
Line 196: | Line 350: | ||
fred likes bea better than abi and bea likes fred better than their current partner |
fred likes bea better than abi and bea likes fred better than their current partner |
||
Marriages are unstable</pre> |
Marriages are unstable</pre> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
<lang python>import copy |
<lang python>import copy |