% File : marriage.pl % Author : Neng-Fa ZHOU % Date : 2001 % Purpose: solve the stable pair match puzzle /* There is a group of women and a group of the same number of men. Each person has expressed his/her ranking for the members in the opposite group. The problem is to find a matching between the two groups such that the marriages are stable. A marriage between a man m and a woman w is said to be stable provided that: if m prefers another woman o to w, o prefers her spouse to m. if w prefers another man o to m, o prefers her spouse to w. The following are the rankings: Men 1. Richard [5,1,2,4,3] 2. Jame [4,1,3,2,5] 3. John [5,3,2,4,1] 4. Hugh [1,5,4,3,2] 5. Greg [4,3,2,1,5] Women 1.Helen [1,2,4,3,5] 2.Tracy [3,5,1,2,4] 3. Linda [5,4,2,1,3] 4. Sally [1,3,5,4,2] 5.Wanda [4,2,3,5,1] For example Wanda is Richard's most favoriate choice and Linda is Richard's least favoriate choice. */ go:- cgWindow(Win,"marriage"),Win^topMargin #= 50, handleWindowClosing(Win), marriage(Os), cgSame(Os,window,Win), cgShow(Os). handleWindowClosing(Win),{windowClosing(Win)} => cgClose(Win). marriage(Os):- Men=a(Richard,Jame,John,Hugh,Greg), Women=a(Helen,Tracy,Linda,Sally,Wanda), Vars=[Richard,Jame,John,Hugh,Greg,Helen,Tracy,Linda,Sally,Wanda], Vars in 1..5, % men(MenRankings), women(WomenRankings), stable(Men,Women,MenRankings,WomenRankings,1,5), stable(Women,Men,WomenRankings,MenRankings,1,5), labeling(Vars), % display the solutions output(Men,Os). % For each man M, if M chooses W then W must choose M to form a pair. % The pair M and W must be stable stable(Men,Women,MenRankings,WomenRankings,M,Arity):-M>Arity,!. stable(Men,Women,MenRankings,WomenRankings,M,Arity):- arg(M,Men,PartnerOfM), %M choose PartnerOfM nth_arg(PartnerOfM,Women,M), %PartnerOfM must choose M to form a pair arg(M,MenRankings,p(Name,MRanking)), nth_arg(PartnerOfMpos,MRanking,PartnerOfM), % PartnerOfM is ranked PartnerOfMpos by M stablePair(M,MRanking,PartnerOfMpos,Women,WomenRankings,1,5), M1 is M+1, stable(Men,Women,MenRankings,WomenRankings,M1,Arity). % For each women W, if M likes his partner more than W, then W likes her spouse more than M stablePair(M,MRanking,PartnerOfMpos,Women,WomenRankings,W,Arity):-W>Arity,!. stablePair(M,MRanking,PartnerOfMpos,Women,WomenRankings,W,Arity):- nth_arg(Wpos,MRanking,W), %W is ranked Wpos by M arg(W,WomenRankings,p(Name,WRanking)), arg(W,Women,PartnerOfW), % W choose PartnerOfW nth_arg(Mpos,WRanking,M), %M is ranked Mpos by W nth_arg(PartnerOfWpos,WRanking,PartnerOfW), %PartnerOfW is ranked PartnerOfWpos by W Wpos #< PartnerOfMpos #=> PartnerOfWpos #< Mpos, %if M likes W more than his partner, then W likes her partner more than M W1 is W+1, stablePair(M,MRanking,PartnerOfMpos,Women,WomenRankings,W1,Arity). nth_arg(I,a(A1,A2,A3,A4,A5),V):- V#=A1 #=> I#=1, I#=1 #=> V#=A1, V#=A2 #=> I#=2, I#=2 #=> V#=A2, V#=A3 #=> I#=3, I#=3 #=> V#=A3, V#=A4 #=> I#=4, I#=4 #=> V#=A4, V#=A5 #=> I#=5, I#=5 #=> V#=A5. men(ranking(p('Richard',a(5,1,2,4,3)), p('Jame',a(4,1,3,2,5)), p('John',a(5,3,2,4,1)), p('Hugh',a(1,5,4,3,2)), p('Greg',a(4,3,2,1,5)))). women(ranking(p('Helen',a(1,2,4,3,5)), p('Tracy',a(3,5,1,2,4)), p('Linda',a(5,4,2,1,3)), p('Sally',a(1,3,5,4,2)), p('Wanda',a(4,2,3,5,1)))). %%%%%%%%% output(Men,Os):- MenLabels=a(Lrichard,Ljame,Ljohn,Lhugh,Lgreg), WomenLabels=a(Lhelen,Ltracy,Llinda,Lsally,Lwanda), Labels=[Lrichard,Ljame,Ljohn,Lhugh,Lgreg,Lhelen,Ltracy,Llinda,Lsally,Lwanda], cgLabel(Labels,["Richard","Jame","John","Hugh","Greg","Helen","Tracy","Linda","Sally","Wanda"]), cgTable([[Lrichard,Ljame,Ljohn,Lhugh,Lgreg], [Lhelen,Ltracy,Llinda,Lsally,Lwanda]],0,50), cgSame(Labels,fontSize,14), cgSetAlignment(Labels,center), Lines=a(L1,L2,L3,L4,L5), cgLine([L1,L2,L3,L4,L5]), constrainLines(Lines,Men,MenLabels,WomenLabels,1,5), Os=[L1,L2,L3,L4,L5|Labels]. constrainLines(Lines,Men,MenLabels,WomenLabels,M,N):-M>N,!. constrainLines(Lines,Men,MenLabels,WomenLabels,M,N):- arg(M,Lines,Line), arg(M,Men,W), arg(M,MenLabels,MLabel), arg(W,WomenLabels,WLabel), Line^x1 #= MLabel^centerX, Line^y1 #= MLabel^bottomY, Line^x2 #= WLabel^centerX, Line^y2 #= WLabel^y, M1 is M+1, constrainLines(Lines,Men,MenLabels,WomenLabels,M1,N).