The Stable Marriage Problem states that given N men and N women, where each person has ranked all members of the opposite sex in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. If there are no such people, all the marriages are “stable” (Source Wiki).
Consider the following example. Let there be two men m1 and m2 and two women w1 and w2. Let m1’s list of preferences be {w1, w2} Let m2’s list of preferences be {w1, w2} Let w1’s list of preferences be {m1, m2} Let w2’s list of preferences be {m1, m2} The matching { {m1, w2}, {w1, m2} } is not stable because m1 and w1 would prefer each other over their assigned partners. The matching {m1, w1} and {m2, w2} is stable because there are no two people of opposite sex that would prefer each other over their assigned partners.
It is always possible to form stable marriages from lists of preferences (See references for proof). Following is Gale–Shapley algorithm to find a stable matching:
The idea is to iterate through all free men while there is any free man available. Every free man goes to all women in his preference list according to the order. For every woman he goes to, he checks if the woman is free, if yes, they both become engaged. If the woman is not free, then the woman chooses either says no to him or dumps her current engagement according to her preference list. So an engagement done once can be broken if a woman gets better option. Time Complexity of Gale-Shapley Algorithm is O(n2).
Initialize all men and women to free
while there exist a free man m who still has a woman w to propose to
{
w = m's highest ranked such woman to whom he has not yet proposed
if w is free
(m, w) become engaged
else some pair (m', w) already exists
if w prefers m to m'
(m, w) become engaged
m' becomes free
else
(m', w) remain engaged
}
Input & Output: Input is a 2D matrix of size (2*N)*N where N is number of women or men. Rows from 0 to N-1 represent preference lists of men and rows from N to 2*N – 1 represent preference lists of women. So men are numbered from 0 to N-1 and women are numbered from N to 2*N – 1. The output is list of married pairs.
Following is the implementation of the above algorithm.
C++
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
#define N 4
bool wPrefersM1OverM( int prefer[2*N][N], int w, int m, int m1)
{
for ( int i = 0; i < N; i++)
{
if (prefer[w][i] == m1)
return true ;
if (prefer[w][i] == m)
return false ;
}
}
void stableMarriage( int prefer[2*N][N])
{
int wPartner[N];
bool mFree[N];
memset (wPartner, -1, sizeof (wPartner));
memset (mFree, false , sizeof (mFree));
int freeCount = N;
while (freeCount > 0)
{
int m;
for (m = 0; m < N; m++)
if (mFree[m] == false )
break ;
for ( int i = 0; i < N && mFree[m] == false ; i++)
{
int w = prefer[m][i];
if (wPartner[w-N] == -1)
{
wPartner[w-N] = m;
mFree[m] = true ;
freeCount--;
}
else
{
int m1 = wPartner[w-N];
if (wPrefersM1OverM(prefer, w, m, m1) == false )
{
wPartner[w-N] = m;
mFree[m] = true ;
mFree[m1] = false ;
}
}
}
}
cout << "Woman Man" << endl;
for ( int i = 0; i < N; i++)
cout << " " << i+N << "\t" << wPartner[i] << endl;
}
int main()
{
int prefer[2*N][N] = { {7, 5, 6, 4},
{5, 4, 6, 7},
{4, 5, 6, 7},
{4, 5, 6, 7},
{0, 1, 2, 3},
{0, 1, 2, 3},
{0, 1, 2, 3},
{0, 1, 2, 3},
};
stableMarriage(prefer);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int N = 4 ;
static boolean wPrefersM1OverM( int prefer[][], int w,
int m, int m1)
{
for ( int i = 0 ; i < N; i++)
{
if (prefer[w][i] == m1)
return true ;
if (prefer[w][i] == m)
return false ;
}
return false ;
}
static void stableMarriage( int prefer[][])
{
int wPartner[] = new int [N];
boolean mFree[] = new boolean [N];
Arrays.fill(wPartner, - 1 );
int freeCount = N;
while (freeCount > 0 )
{
int m;
for (m = 0 ; m < N; m++)
if (mFree[m] == false )
break ;
for ( int i = 0 ; i < N &&
mFree[m] == false ; i++)
{
int w = prefer[m][i];
if (wPartner[w - N] == - 1 )
{
wPartner[w - N] = m;
mFree[m] = true ;
freeCount--;
}
else
{
int m1 = wPartner[w - N];
if (wPrefersM1OverM(prefer, w, m, m1) == false )
{
wPartner[w - N] = m;
mFree[m] = true ;
mFree[m1] = false ;
}
}
}
}
System.out.println( "Woman Man" );
for ( int i = 0 ; i < N; i++)
{
System.out.print( " " );
System.out.println(i + N + " " +
wPartner[i]);
}
}
public static void main(String[] args)
{
int prefer[][] = new int [][]{{ 7 , 5 , 6 , 4 },
{ 5 , 4 , 6 , 7 },
{ 4 , 5 , 6 , 7 },
{ 4 , 5 , 6 , 7 },
{ 0 , 1 , 2 , 3 },
{ 0 , 1 , 2 , 3 },
{ 0 , 1 , 2 , 3 },
{ 0 , 1 , 2 , 3 }};
stableMarriage(prefer);
}
}
|
Python3
N = 4
def wPrefersM1OverM(prefer, w, m, m1):
for i in range (N):
if (prefer[w][i] = = m1):
return True
if (prefer[w][i] = = m):
return False
def stableMarriage(prefer):
wPartner = [ - 1 for i in range (N)]
mFree = [ False for i in range (N)]
freeCount = N
while (freeCount > 0 ):
m = 0
while (m < N):
if (mFree[m] = = False ):
break
m + = 1
i = 0
while i < N and mFree[m] = = False :
w = prefer[m][i]
if (wPartner[w - N] = = - 1 ):
wPartner[w - N] = m
mFree[m] = True
freeCount - = 1
else :
m1 = wPartner[w - N]
if (wPrefersM1OverM(prefer, w, m, m1) = = False ):
wPartner[w - N] = m
mFree[m] = True
mFree[m1] = False
i + = 1
print ( "Woman " , " Man" )
for i in range (N):
print (i + N, "\t" , wPartner[i])
prefer = [[ 7 , 5 , 6 , 4 ], [ 5 , 4 , 6 , 7 ],
[ 4 , 5 , 6 , 7 ], [ 4 , 5 , 6 , 7 ],
[ 0 , 1 , 2 , 3 ], [ 0 , 1 , 2 , 3 ],
[ 0 , 1 , 2 , 3 ], [ 0 , 1 , 2 , 3 ]]
stableMarriage(prefer)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int N = 4;
static bool wPrefersM1OverM( int [,]prefer, int w,
int m, int m1)
{
for ( int i = 0; i < N; i++)
{
if (prefer[w, i] == m1)
return true ;
if (prefer[w, i] == m)
return false ;
}
return false ;
}
static void stableMarriage( int [,]prefer)
{
int []wPartner = new int [N];
bool []mFree = new bool [N];
for ( int i = 0; i < N; i++)
wPartner[i] = -1;
int freeCount = N;
while (freeCount > 0)
{
int m;
for (m = 0; m < N; m++)
if (mFree[m] == false )
break ;
for ( int i = 0; i < N &&
mFree[m] == false ; i++)
{
int w = prefer[m,i];
if (wPartner[w - N] == -1)
{
wPartner[w - N] = m;
mFree[m] = true ;
freeCount--;
}
else
{
int m1 = wPartner[w - N];
if (wPrefersM1OverM(prefer, w, m, m1) == false )
{
wPartner[w - N] = m;
mFree[m] = true ;
mFree[m1] = false ;
}
}
}
}
Console.WriteLine( "Woman Man" );
for ( int i = 0; i < N; i++)
{
Console.Write( " " );
Console.WriteLine(i + N + " " +
wPartner[i]);
}
}
public static void Main(String[] args)
{
int [,]prefer = new int [,]{{7, 5, 6, 4},
{5, 4, 6, 7},
{4, 5, 6, 7},
{4, 5, 6, 7},
{0, 1, 2, 3},
{0, 1, 2, 3},
{0, 1, 2, 3},
{0, 1, 2, 3}};
stableMarriage(prefer);
}
}
|
Javascript
<script>
N = 4;
function wPrefersM1OverM( prefer, w, m, m1)
{
for ( var i = 0; i < N; i++)
{
if (prefer[w][i] == m1)
return true ;
if (prefer[w][i] == m)
return false ;
}
}
function stableMarriage( prefer)
{
var wPartner = new Array(N);
mFree = new Array(N);
wPartner.fill(-1);
mFree.fill( false );
var freeCount = N;
while (freeCount > 0)
{
var m;
for (m = 0; m < N; m++)
if (mFree[m] == false )
break ;
for ( var i = 0; i < N && mFree[m] == false ; i++)
{
var w = prefer[m][i];
if (wPartner[w-N] == -1)
{
wPartner[w-N] = m;
mFree[m] = true ;
freeCount--;
}
else
{
var m1 = wPartner[w-N];
if (wPrefersM1OverM(prefer, w, m, m1) == false )
{
wPartner[w-N] = m;
mFree[m] = true ;
mFree[m1] = false ;
}
}
}
}
document.write( "Woman Man" + "<br>" );
for ( var i = 0; i < N; i++)
document.write( " " + (i+N) + " " + wPartner[i] + "<br>" );
}
var prefer = [ [7, 5, 6, 4],
[5, 4, 6, 7],
[4, 5, 6, 7],
[4, 5, 6, 7],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
];
stableMarriage(prefer);
</script>
|
OutputWoman Man
4 2
5 1
6 3
7 0
Time Complexity : O(N2) , where n is number of men/women.
Auxiliary Space : O(N2)