import java.util.HashSet; public class StableMatching { public static class Person { Person[] preferences; int id = -1; boolean isEngaged = false; Person engagedTo = null; int lastProposedToIndex = -1; int currentlyEngagedIndex = -1; } static Person[] allMen; static Person[] allWomen; public static void initPersons(Person[] persons) { for (int i = 0; i < persons.length; i++) { persons[i] = new Person(); persons[i].id = i; persons[i].preferences = new Person[persons.length]; } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int numTries[] = {4,10,20,50,70,100,150,300,500,600,700};//1000}; double n = 3; for (int i = 1; i < numTries.length; i++) { int M=0; int W=0; int numSamples = numTries[i]; double numSamplesFloat = 1.0*numSamples; for (int j=0; j<n; j++){ generateRandomLists(numSamples); generateStableMatching(numSamples); for (int k = 0; k < numSamples; k++) { M += allMen[k].lastProposedToIndex+1; W += allWomen[k].currentlyEngagedIndex+1; } } String s = String.format("%d,M,%f,W,%f", numSamples,(double) (M/numSamplesFloat), (double) W/numSamplesFloat); System.out.println(s); } System.out.println("okay done..."); } private static void printOutMatchingIndexes(int n) { int M=0; int N=0; for (int i = 0; i < n; i++) { M += allMen[i].lastProposedToIndex+1; N += allWomen[i].currentlyEngagedIndex+1; String s = String.format("M,%d,W,%d", allMen[i].lastProposedToIndex+1, allWomen[i].currentlyEngagedIndex); //System.out.println(s); } System.out.println("Final Ranks" + M + ":" + N); } public static void generateStableMatching(int n) { // list of men and their preferences int numEngaged = 0; while (numEngaged != n) { //System.out.println("number left" + numEngaged); for (int i=0; i < n; i++) { Person currMan = allMen[i]; if (!currMan.isEngaged) { int currIndexToPropose = currMan.lastProposedToIndex+1; Person currWoman = currMan.preferences[currIndexToPropose]; if (!currWoman.isEngaged) { // engage the man and woman currMan.isEngaged = true; currWoman.isEngaged = true; currWoman.currentlyEngagedIndex = findIndexOfMan(currWoman, currMan.id); numEngaged++; } else { int manIndex = findIndexOfMan(currWoman, currMan.id); if (manIndex < currWoman.currentlyEngagedIndex) { currWoman.preferences[currWoman.currentlyEngagedIndex].isEngaged = false; currWoman.currentlyEngagedIndex = manIndex; currWoman.isEngaged = true; currMan.isEngaged = true; } } currMan.lastProposedToIndex++; } } } } private static int findIndexOfMan(Person currWoman, int id) { for (int i = 0 ; i < currWoman.preferences.length; i++) { Person currMan = currWoman.preferences[i]; if (currMan.id == id) { return i; } } return 0; } public static void generateRandomLists(int n) { // each man will have a random list of women allMen = new Person[n]; allWomen = new Person[n]; //System.out.println("starting generation"); initPersons(allMen); initPersons(allWomen); for (int i=0; i < n; i++) { HashSet<Integer> indexesUsed = new HashSet<Integer>(n); //System.out.println(i); for (int j=0; j < n; j++) { int indexToUse = (int) (Math.random() * 1.0 * n); while (indexesUsed.contains(indexToUse)) { indexToUse = (int) (Math.random() * 1.0 * n); } allMen[i].preferences[j] = allWomen[indexToUse]; indexesUsed.add(indexToUse); } if (indexesUsed.size() != n) { System.out.println("woops. not fully specifying preference list"); } } for (int i=0; i < n; i++) { HashSet<Integer> indexesUsed = new HashSet<Integer>(n); for (int j=0; j < n; j++) { int indexToUse = (int) (Math.random() * 1.0 * n); while (indexesUsed.contains(indexToUse)) { indexToUse = (int) (Math.random() * 1.0 * n); } allWomen[i].preferences[j] = allMen[indexToUse]; indexesUsed.add(indexToUse); } if (indexesUsed.size() != n) { System.out.println("woops. not fully specifying preference list"); } } } }