September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,87 @@
constant men = {"abe","bob","col","dan","ed","fred","gav","hal","ian","jon"}
enum abe , bob , col , dan , ed , fred , gav , hal , ian , jon
constant hen = {"abi","bea","cath","dee","eve","fay","gay","hope","ivy","jan"}
enum abi , bea , cath , dee , eve , fay , gay , hope , ivy , jan
-- Given a complete list of ranked preferences, where the most liked is to the left:
sequence mpref = repeat(0,length(men))
mpref[abe] = {abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay}
mpref[bob] = {cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay}
mpref[col] = {hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan}
mpref[dan] = {ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi}
mpref[ed] = {jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay}
mpref[fred] = {bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay}
mpref[gav] = {gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay}
mpref[hal] = {abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee}
mpref[ian] = {hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve}
mpref[jon] = {abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope}
sequence hpref = repeat(0,length(hen))
hpref[abi] = {bob, fred, jon, gav, ian, abe, dan, ed, col, hal}
hpref[bea] = {bob, abe, col, fred, gav, dan, ian, ed, jon, hal}
hpref[cath] = {fred, bob, ed, gav, hal, col, ian, abe, dan, jon}
hpref[dee] = {fred, jon, col, abe, ian, hal, gav, dan, bob, ed}
hpref[eve] = {jon, hal, fred, dan, abe, gav, col, ed, ian, bob}
hpref[fay] = {bob, abe, ed, ian, jon, dan, fred, gav, col, hal}
hpref[gay] = {jon, gav, hal, fred, bob, abe, col, ed, dan, ian}
hpref[hope] = {gav, jon, bob, abe, ian, dan, hal, ed, col, fred}
hpref[ivy] = {ian, col, hal, gav, fred, bob, abe, ed, jon, dan}
hpref[jan] = {ed, hal, gav, abe, bob, jon, col, ian, fred, dan}
sequence engagements := repeat(0,length(hen))
sequence freemen = tagset(length(men))
printf(1,"Engagements:\n")
-- use the Gale Shapley algorithm to find a stable set of engagements:
while length(freemen) do
integer man = freemen[1]
freemen = freemen[2..$]
integer fem, dumpee
-- each male loops through all females in order of his preference until one accepts him
for j=1 to length(mpref[man]) do
fem = mpref[man][j]
dumpee = engagements[fem]
if dumpee=0
or find(man,hpref[fem])<find(dumpee,hpref[fem]) then
exit
end if
end for
if dumpee!=0 then -- if she was previously engaged
freemen &= dumpee -- he goes to the bottom of the list
printf(1,"%s dumped %s and accepted %s\n",{hen[fem],men[dumpee],men[man]})
else
printf(1,"%s accepted %s\n",{hen[fem],men[man]})
end if
engagements[fem] := man -- the new engagement is registered
end while
printf(1,"\nCouples:\n")
for fem=1 to length(hen) do
printf(1,"%s is engaged to %s\n",{hen[fem],men[engagements[fem]]})
end for
procedure stable()
bool unstable = false
for fem=1 to length(hen) do
integer man = engagements[fem]
for j=1 to length(hen) do
if find(fem,mpref[man])>find(j,mpref[man])
and find(engagements[j],hpref[j])>find(man,hpref[j]) then
if unstable=false then
printf(1,"\nThese couples are not stable.\n")
unstable = true
end if
printf(1,"%s is engaged to %s but would prefer %s and %s is engaged to %s but would prefer %s\n",
{men[man],hen[fem],hen[j],hen[j],men[engagements[j]],men[man]})
end if
end for
end for
if not unstable then
printf(1,"\nThese couples are stable.\n")
end if
end procedure
stable()
printf(1,"\nWhat if cath and ivy swap?\n")
engagements[cath]:=abe; engagements[ivy]:=bob
stable()

View file

@ -1,121 +1,107 @@
import java.util._
import scala.collection.JavaConversions._
object SMP extends App {
def run() {
Seq("abe" -> Array("abi", "eve", "cath", "ivy", "jan", "dee", "fay", "bea", "hope", "gay"),
"bob" -> Array("cath", "hope", "abi", "dee", "eve", "fay", "bea", "jan", "ivy", "gay"),
"col" -> Array("hope", "eve", "abi", "dee", "bea", "fay", "ivy", "gay", "cath", "jan"),
"dan" -> Array("ivy", "fay", "dee", "gay", "hope", "eve", "jan", "bea", "cath", "abi"),
"ed" -> Array("jan", "dee", "bea", "cath", "fay", "eve", "abi", "ivy", "hope", "gay"),
"fred" -> Array("bea", "abi", "dee", "gay", "eve", "ivy", "cath", "jan", "hope", "fay"),
"gav" -> Array("gay", "eve", "ivy", "bea", "cath", "abi", "dee", "hope", "jan", "fay"),
"hal" -> Array("abi", "eve", "hope", "fay", "ivy", "cath", "jan", "bea", "gay", "dee"),
"ian" -> Array("hope", "cath", "dee", "gay", "bea", "abi", "fay", "ivy", "jan", "eve"),
"jon" -> Array("abi", "fay", "jan", "gay", "eve", "bea", "dee", "cath", "ivy", "hope"))
.foreach { e => guyPrefers.put(e._1, e._2.toList) }
private def checkMarriages(): Unit =
if (check)
println("Marriages are stable")
else
println("Marriages are unstable")
Seq("abi" -> Array("bob", "fred", "jon", "gav", "ian", "abe", "dan", "ed", "col", "hal"),
"bea" -> Array("bob", "abe", "col", "fred", "gav", "dan", "ian", "ed", "jon", "hal"),
"cath" -> Array("fred", "bob", "ed", "gav", "hal", "col", "ian", "abe", "dan", "jon"),
"dee" -> Array("fred", "jon", "col", "abe", "ian", "hal", "gav", "dan", "bob", "ed"),
"eve" -> Array("jon", "hal", "fred", "dan", "abe", "gav", "col", "ed", "ian", "bob"),
"fay" -> Array("bob", "abe", "ed", "ian", "jon", "dan", "fred", "gav", "col", "hal"),
"gay" -> Array("jon", "gav", "hal", "fred", "bob", "abe", "col", "ed", "dan", "ian"),
"hope" -> Array("gav", "jon", "bob", "abe", "ian", "dan", "hal", "ed", "col", "fred"),
"ivy" -> Array("ian", "col", "hal", "gav", "fred", "bob", "abe", "ed", "jon", "dan"),
"jan" -> Array("ed", "hal", "gav", "abe", "bob", "jon", "col", "ian", "fred", "dan"))
.foreach { e => girlPrefers.put(e._1, e._2.toList) }
private def swap() {
val girl1 = girls.head
val girl2 = girls(1)
val tmp = girl2 -> matches(girl1)
matches += girl1 -> matches(girl2)
matches += tmp
println(girl1 + " and " + girl2 + " have switched partners")
}
val matches = matching(guys, guyPrefers, girlPrefers)
matches.foreach { e => println(s"${e._1} is engaged to ${e._2}") }
if (checkMatches(guys, girls, matches, guyPrefers, girlPrefers))
println("Marriages are stable")
else
println("Marriages are unstable")
private type TM = scala.collection.mutable.TreeMap[String, String]
val tmp = matches(girls(0))
matches += girls(0) -> matches(girls(1))
matches += girls(1) -> tmp
println(girls(0) + " and " + girls(1) + " have switched partners")
if (checkMatches(guys, girls, matches, guyPrefers, girlPrefers))
println("Marriages are stable")
else
println("Marriages are unstable")
}
private def check: Boolean = {
if (!girls.toSet.subsetOf(matches.keySet) || !guys.toSet.subsetOf(matches.values.toSet))
return false
private def matching(guys: Iterable[String],
guyPrefers: Map[String, List[String]],
girlPrefers: Map[String, List[String]]): Map[String, String] = {
val engagements = new TreeMap[String, String]
val freeGuys = new LinkedList[String](guys)
while (!freeGuys.isEmpty) {
val guy = freeGuys.remove(0)
val guy_p = guyPrefers(guy)
var break = false
for (girl <- guy_p)
if (!break)
if (!engagements.containsKey(girl)) {
engagements += girl -> guy
break = true
}
else {
val other_guy = engagements(girl)
val girl_p = girlPrefers(girl)
if (girl_p.indexOf(guy) < girl_p.indexOf(other_guy)) {
engagements += girl -> guy
freeGuys += other_guy
break = true
val invertedMatches = new TM
matches foreach { invertedMatches += _.swap }
for ((k, v) <- matches) {
val shePrefers = girlPrefers(k)
val sheLikesBetter = shePrefers.slice(0, shePrefers.indexOf(v))
val hePrefers = guyPrefers(v)
val heLikesBetter = hePrefers.slice(0, hePrefers.indexOf(k))
for (guy <- sheLikesBetter) {
val fiance = invertedMatches(guy)
val guy_p = guyPrefers(guy)
if (guy_p.indexOf(fiance) > guy_p.indexOf(k)) {
println(s"$k likes $guy better than $v and $guy likes $k better than their current partner")
return false
}
}
}
for (girl <- heLikesBetter) {
val fiance = matches(girl)
val girl_p = girlPrefers(girl)
if (girl_p.indexOf(fiance) > girl_p.indexOf(v)) {
println(s"$v likes $girl better than $k and $girl likes $v better than their current partner")
return false
}
}
}
true
}
engagements
}
private val guys = "abe" :: "bob" :: "col" :: "dan" :: "ed" :: "fred" :: "gav" :: "hal" :: "ian" :: "jon" :: Nil
private val girls = "abi" :: "bea" :: "cath" :: "dee" :: "eve" :: "fay" :: "gay" :: "hope" :: "ivy" :: "jan" :: Nil
private val guyPrefers = Map("abe" -> List("abi", "eve", "cath", "ivy", "jan", "dee", "fay", "bea", "hope", "gay"),
"bob" -> List("cath", "hope", "abi", "dee", "eve", "fay", "bea", "jan", "ivy", "gay"),
"col" -> List("hope", "eve", "abi", "dee", "bea", "fay", "ivy", "gay", "cath", "jan"),
"dan" -> List("ivy", "fay", "dee", "gay", "hope", "eve", "jan", "bea", "cath", "abi"),
"ed" -> List("jan", "dee", "bea", "cath", "fay", "eve", "abi", "ivy", "hope", "gay"),
"fred" -> List("bea", "abi", "dee", "gay", "eve", "ivy", "cath", "jan", "hope", "fay"),
"gav" -> List("gay", "eve", "ivy", "bea", "cath", "abi", "dee", "hope", "jan", "fay"),
"hal" -> List("abi", "eve", "hope", "fay", "ivy", "cath", "jan", "bea", "gay", "dee"),
"ian" -> List("hope", "cath", "dee", "gay", "bea", "abi", "fay", "ivy", "jan", "eve"),
"jon" -> List("abi", "fay", "jan", "gay", "eve", "bea", "dee", "cath", "ivy", "hope"))
private val girlPrefers = Map("abi" -> List("bob", "fred", "jon", "gav", "ian", "abe", "dan", "ed", "col", "hal"),
"bea" -> List("bob", "abe", "col", "fred", "gav", "dan", "ian", "ed", "jon", "hal"),
"cath" -> List("fred", "bob", "ed", "gav", "hal", "col", "ian", "abe", "dan", "jon"),
"dee" -> List("fred", "jon", "col", "abe", "ian", "hal", "gav", "dan", "bob", "ed"),
"eve" -> List("jon", "hal", "fred", "dan", "abe", "gav", "col", "ed", "ian", "bob"),
"fay" -> List("bob", "abe", "ed", "ian", "jon", "dan", "fred", "gav", "col", "hal"),
"gay" -> List("jon", "gav", "hal", "fred", "bob", "abe", "col", "ed", "dan", "ian"),
"hope" -> List("gav", "jon", "bob", "abe", "ian", "dan", "hal", "ed", "col", "fred"),
"ivy" -> List("ian", "col", "hal", "gav", "fred", "bob", "abe", "ed", "jon", "dan"),
"jan" -> List("ed", "hal", "gav", "abe", "bob", "jon", "col", "ian", "fred", "dan"))
private def checkMatches(guys: Iterable[String], girls: Iterable[String],
matches: Map[String, String],
guyPrefers: Map[String, List[String]],
girlPrefers: Map[String, List[String]]): Boolean = {
if (!matches.keySet.containsAll(girls) || !matches.values.containsAll(guys))
return false
val invertedMatches = new TreeMap[String, String]
matches.foreach { invertedMatches += _.swap }
for ((k, v) <- matches) {
val shePrefers = girlPrefers(k)
val sheLikesBetter = new LinkedList[String]
sheLikesBetter.addAll(shePrefers.subList(0, shePrefers.indexOf(v)))
val hePrefers = guyPrefers(v)
val heLikesBetter = new LinkedList[String]
heLikesBetter.addAll(hePrefers.subList(0, hePrefers.indexOf(k)))
for (guy <- sheLikesBetter) {
val fiance = invertedMatches(guy)
val guy_p = guyPrefers(guy)
if (guy_p.indexOf(fiance) > guy_p.indexOf(k)) {
println(s"$k likes $guy better than $v and $guy likes $k better than their current partner")
return false
private lazy val matches = {
val engagements = new TM
val freeGuys = scala.collection.mutable.Queue.empty ++ guys
while (freeGuys.nonEmpty) {
val guy = freeGuys.dequeue()
val guy_p = guyPrefers(guy)
var break = false
for (girl <- guy_p)
if (!break)
if (!engagements.contains(girl)) {
engagements(girl) = guy
break = true
}
else {
val other_guy = engagements(girl)
val girl_p = girlPrefers(girl)
if (girl_p.indexOf(guy) < girl_p.indexOf(other_guy)) {
engagements(girl) = guy
freeGuys += other_guy
break = true
}
}
}
}
for (girl <- heLikesBetter) {
val fiance = matches(girl)
val girl_p = girlPrefers(girl)
if (girl_p.indexOf(fiance) > girl_p.indexOf(v)) {
println(s"$v likes $girl better than $k and $girl likes $v better than their current partner")
return false
}
}
engagements foreach { e => println(s"${e._1} is engaged to ${e._2}") }
engagements
}
true
}
private val guys = "abe" :: "bob" :: "col" :: "dan" :: "ed" :: "fred" :: "gav" :: "hal" :: "ian" :: "jon" :: Nil
private val girls = "abi" :: "bea" :: "cath" :: "dee" :: "eve" :: "fay" :: "gay" :: "hope" :: "ivy" :: "jan" :: Nil
private val guyPrefers = new HashMap[String, List[String]]
private val girlPrefers = new HashMap[String, List[String]]
run()
checkMarriages()
swap()
checkMarriages()
}

View file

@ -0,0 +1,62 @@
var
Boys=Dictionary(
"abe", "abi eve cath ivy jan dee fay bea hope gay".split(),
"bob", "cath hope abi dee eve fay bea jan ivy gay".split(),
"col", "hope eve abi dee bea fay ivy gay cath jan".split(),
"dan", "ivy fay dee gay hope eve jan bea cath abi".split(),
"ed", "jan dee bea cath fay eve abi ivy hope gay".split(),
"fred","bea abi dee gay eve ivy cath jan hope fay".split(),
"gav", "gay eve ivy bea cath abi dee hope jan fay".split(),
"hal", "abi eve hope fay ivy cath jan bea gay dee".split(),
"ian", "hope cath dee gay bea abi fay ivy jan eve".split(),
"jon", "abi fay jan gay eve bea dee cath ivy hope".split(), ),
Girls=Dictionary(
"abi", "bob fred jon gav ian abe dan ed col hal".split(),
"bea", "bob abe col fred gav dan ian ed jon hal".split(),
"cath","fred bob ed gav hal col ian abe dan jon".split(),
"dee", "fred jon col abe ian hal gav dan bob ed".split(),
"eve", "jon hal fred dan abe gav col ed ian bob".split(),
"fay", "bob abe ed ian jon dan fred gav col hal".split(),
"gay", "jon gav hal fred bob abe col ed dan ian".split(),
"hope","gav jon bob abe ian dan hal ed col fred".split(),
"ivy", "ian col hal gav fred bob abe ed jon dan".split(),
"jan", "ed hal gav abe bob jon col ian fred dan".split(), ),
Couples=List(); // ( (boy,girl),(boy,girl),...)
Boyz:=Boys.pump(Dictionary(),fcn([(b,gs)]){ return(b,gs.copy()) }); // make writable copy
while( bgs:=Boyz.filter1( 'wrap([(Boy,gs)]){ // while unattached boy
gs and (not Couples.filter1("holds",Boy))
}) )
{
Boy,Girl:=bgs; Girl=Girl.pop(0);
Pair:=Couples.filter1("holds",Girl); // is Girl part of a couple?
if(not Pair) Couples.append(List(Boy,Girl)); # no, Girl was free
else{ // yes, Girl is engaged to Pair[0]
bsf,nBoy,nB:=Girls[Girl].index, bsf(Boy),bsf(Pair[0]);
if(nBoy<nB) Pair[0]=Boy; # Girl prefers Boy, change Couples
}
}
foreach Boy,Girl in (Couples){ println(Girl," is engaged to ",Boy) }
fcn checkCouples(Couples){
Couples.filter(fcn([(Boy,Girl)]){
Girls[Girl].filter1('wrap(B){
// is B before Boy in Girls preferences?
bsf,nBoy,nB:=Girls[Girl].index, bsf(Boy),bsf(B);
// Does B prefer Girl (over his partner)?
_,G:=Couples.filter1("holds",B); // (B,G)
gsf,nGirl,nG:=Boys[B].index, gsf(Girl),gsf(G);
( nB<nBoy and nGirl<nG and
println(Girl," likes ",B," better than ",Boy," and ",
B," likes ",Girl," better than ",G) )
})
}) or println("All marriages are stable");
}
checkCouples(Couples);
println();
println("Engage fred with abi and jon with bea");
Couples.filter1("holds","fred")[1]="abi";
Couples.filter1("holds","jon") [1]="bea";
checkCouples(Couples);