1+ package src .test .java .com .matchings .stableMatching ;
2+
3+ import src .main .java .com .matchings .stableMatching .GaleShapley ;
4+ import org .junit .Test ;
5+
6+ import static junit .framework .Assert .assertEquals ;
7+
8+ import java .util .Random ;
9+ import java .util .Collections ; // for shuffling
10+ import java .util .ArrayList ; // for shuffling
11+ import java .util .List ; // for shuffling
12+
13+ public class GaleShapleyTest {
14+
15+ /**
16+ * Test a number of GaleShapley executions on pseudo-random instances of the
17+ * stable marriage problem.
18+ */
19+
20+ @ Test
21+ public void testGaleShapley () {
22+ GaleShapley galeShapley = new GaleShapley ();
23+ int N = 10 ;
24+ int [][] menPrefs ;
25+ int [][] womenPrefs ;
26+ int [] GaleShapleyMenMatching ; // the solution returned by GaleShapley.java
27+ // for each n from 0 to N-1, create and test an instance of the problem.
28+ for (int n = 0 ; n < N ; n ++) {
29+ System .out .println ("testing n = " + n );
30+ menPrefs = new int [n ][n ];
31+ womenPrefs = new int [n ][n ];
32+ // set all other sex individuals in each individual's preference list,
33+ // then shuffle
34+ for (int i = 0 ; i < n ; i ++) {
35+ for (int j = 0 ; j < n ; j ++) {
36+ menPrefs [i ][j ] = j ;
37+ womenPrefs [i ][j ] = j ;
38+ }
39+ shuffleArray (menPrefs [i ], i );
40+ shuffleArray (womenPrefs [i ], n +i );
41+ }
42+ // Now we have pseudo-random preferences for each man and each woman.
43+ GaleShapleyMenMatching = galeShapley .GaleShapleyStableMarriage (menPrefs , womenPrefs );
44+ assertEquals ("Unstable matching" , true , isStable (GaleShapleyMenMatching , menPrefs , womenPrefs ));
45+ }
46+ }
47+
48+ /**
49+ * Determine if the proposed menMatching is stable, i.e. if there is no
50+ * potential couple in which both members would strictly prefer being with each
51+ * other than being with their current partner.
52+ *
53+ * @param menMatching
54+ * @param menPrefs
55+ * @param womenPrefs
56+ * @return whether menMatching is stable according to menPrefs and womenPrefs
57+ */
58+
59+ public boolean isStable (int [] menMatching , int [][] menPrefs , int [][] womenPrefs ) {
60+ int n = menMatching .length ;
61+ // reconstruct womenMatching (for each woman, the associated man):
62+ int [] womenMatching = new int [n ];
63+ int man ;
64+ int woman ;
65+ for (man = 0 ; man < n ; man ++) {
66+ woman = menMatching [man ];
67+ womenMatching [woman ] = man ;
68+ }
69+
70+ // construct menRanks and womenRanks to quickly compare preferences:
71+ int [][] menRanks = new int [n ][n ];
72+ int [][] womenRanks = new int [n ][n ];
73+ int individualAtThisRank ;
74+ for (int i = 0 ; i < n ; i ++) {
75+ for (int rank = 0 ; rank < n ; rank ++) {
76+ // womenRanks
77+ individualAtThisRank = womenPrefs [i ][rank ];
78+ womenRanks [i ][individualAtThisRank ] = rank ;
79+
80+ // menRanks
81+ individualAtThisRank = menPrefs [i ][rank ];
82+ menRanks [i ][individualAtThisRank ] = rank ;
83+ }
84+ }
85+
86+ // Do the actual test by considering all potential n*n couples and verifying
87+ // that at least one of them is happier now than they
88+ // would be in the potential couple
89+
90+ int currentEngagedMan ; // man currently engaged to considered woman
91+ int currentEngagedWoman ; // woman currently engaged to considered man
92+ for (man = 0 ; man < n ; man ++) {
93+ for (woman = 0 ; woman < n ; woman ++) {
94+ currentEngagedMan = womenMatching [woman ];
95+ currentEngagedWoman = menMatching [man ];
96+ if (womenRanks [woman ][man ] < womenRanks [woman ][currentEngagedMan ]
97+ && menRanks [man ][woman ] < menRanks [man ][currentEngagedWoman ]) {
98+ // man prefers woman over currentEngagedWoman, and
99+ // woman prefers man over currentEngagedMan.
100+ // The marriage therefore isn't stable.
101+ return false ;
102+ }
103+ }
104+ }
105+ return true ;
106+ }
107+
108+ /**
109+ * Shuffle an array using Collections.shuffle
110+ *
111+ * @param array array to be shuffled
112+ * @param seed fixed seed, for reproducibility
113+ */
114+
115+ public void shuffleArray (int [] array , long seed ) {
116+ List <Integer > list = new ArrayList <>();
117+ for (int i : array ) {
118+ list .add (i );
119+ }
120+ Collections .shuffle (list , new Random (seed ));
121+ for (int i = 0 ; i < list .size (); i ++) {
122+ array [i ] = list .get (i );
123+ }
124+ }
125+ }
0 commit comments