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");
}
}
}
}