ここでは2つのグループ(男、女)があり、お互いのグループの各メンバーは異なるグループのメンバーとカップルとなることを望んでおり、それぞれ異なるグループのメンバーについて、カップルとなりたい順序を持っているとする。 また誰ともカップルとならなかったら、最悪だと考えている。 さらにここでは簡単化のため、カップルの申し込みはグループ1のメンバーのみとする。

GSアルゴリズムの手順:
1. グループ1のメンバーはグループ2の第1希望のメンバーに一斉にカップルの申し込みを行う。
2. グループ2のメンバーは自分の好みにいちばん近い人を選んでキープし、残りのメンバーを拒否する
3. グループ1のメンバーは拒否される度に次に好みのメンバーに申し込む。
4. グループ2のメンバーはより好みのグループ1のメンバーの申し込みが来るたびにキープ相手を変更し、残りを断る。
※この作業を断られるグループ1のメンバーがいなくなるまで続ける。

/*
 * Stable Matching Algorithm
 * Gale-Shapley Algorithm
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* prefrence value is stronger as value is small ( 0 is most prefered ) */
#define NUMBER 10

void set_random( int* );

void initialize( int **, int **, int *, int *, int * );

int main( int argc, char **argv )
{
	int i, j;
	/* NUMBER is invalid(initial) NUMBER */
	int *men_pref[ NUMBER ],
		*women_pref[ NUMBER ];  /* preference list of women */
	int prop_list[ NUMBER ];
	int marriage_men[ NUMBER ];
	int marriage_women[ NUMBER ];
		
	initialize( men_pref, women_pref, prop_list, marriage_men, marriage_women );

	for( j = 0; j < NUMBER; j++ ) {
		printf( "MAN[%d]: ", j );
		for( i = 0; i < NUMBER; i++ )
			printf( "%d, ", men_pref[ j ][ i ] );
		printf( "\tWOMAN[%d]: ", j );
		for( i = 0; i < NUMBER; i++ )
			printf( "%d, ", women_pref[ j ][ i ] );
		printf("\n");
	}

	for( j = 0; j < NUMBER; j++ ) {
		printf( "== trial %d ==\n", j );
		trial( men_pref, women_pref, prop_list, marriage_men, marriage_women );
		printf("MEN:   ");
		for( i = 0; i < NUMBER; i++ ) {
			printf( "%2d ", marriage_men[ i ] );
		}
		printf( "\nWOMEN: " );
		for( i = 0; i < NUMBER; i++ ) {
			printf( "%2d ", marriage_women[ i ] );
		}
		printf( "\n" );
	}

	for( i = 0; i < NUMBER; i++ ) {
		free( men_pref[ i ] );
		free( women_pref[ i ] );
	}
	return 0;
}

int trial( int *men_list[], int *women_list[], int *prop_list, int *marriage_men, int *marriage_women )
{
	int i, j;
	int man_index, woman_index;
	for( i = 0; i < NUMBER; i++ ) {
		if( marriage_men[ i ] != NUMBER ) {  // already married
			continue;
		}
		woman_index = men_list[ i ][ prop_list [ i ] ];
		if( marriage_women[ woman_index ] == NUMBER ) { // woman is free
			marriage_men[ i ] = woman_index;          	// marriage
			marriage_women[ woman_index ] = i;          // marriage
		} else {
			man_index = marriage_women[ woman_index ]; // man married targeted woman
			for( j = 0; j < NUMBER; j++ ) {
				if( women_list[ woman_index ][ j ] == man_index ) // marriaged man is prefered
					break;
				else if( women_list[ woman_index ][ j ] == i ) {   // proposed man is prefered
					marriage_men[ i ] = woman_index;          // marriage
					marriage_women[ woman_index ] = i;        // marriage
					marriage_men[ man_index ] = NUMBER;       // dismarriage
				}
			}
		}
		prop_list[ i ] ++;
	}
	
	return 0;
}

void set_random( int *list )
{
	int i, tmp;
	for( i = 0; i < NUMBER; i++ ){
		list[i] = NUMBER;
	}
	for( i = 0; i < NUMBER; i++ ){
		while( list[( tmp = random( ) % NUMBER )] != NUMBER );  /* retry */
		list[tmp] = i;  /* set preference value */
	}
	return;
}

void initialize( int *men_list[], int *women_list[], int *prop_list, int *marriage_men, int *marriage_women )
{
	int i, tmp;
	srandom( time( 0 ) );

	for( i = 0; i < NUMBER; i++ ) {
		if( ( men_list[ i ] = (int *)malloc( NUMBER * sizeof( int ) ) ) == NULL ) {
			perror( "malloc" ); 
			exit( EXIT_FAILURE );
		}
		set_random( men_list[ i ] );
		if( ( women_list[ i ] = (int *)malloc( NUMBER * sizeof( int ) ) ) == NULL ) {
			perror( "malloc" ); 
			exit( EXIT_FAILURE );
		}
		set_random( women_list[ i ] );
		prop_list[ i ] = 0;
		marriage_men[ i ] = NUMBER;
		marriage_women[ i ] = NUMBER;
	} 
	return;
}



出力結果

MAN[0]: 2, 3, 8, 0, 4, 9, 1, 7, 5, 6, WOMAN[0]: 8, 3, 4, 7, 6, 0, 9, 1, 2, 5, MAN[1]: 9, 0, 6, 3, 5, 8, 7, 2, 1, 4, WOMAN[1]: 2, 5, 0, 8, 4, 3, 7, 1, 6, 9, MAN[2]: 1, 7, 6, 3, 0, 4, 2, 8, 9, 5, WOMAN[2]: 2, 9, 3, 5, 0, 4, 8, 1, 7, 6, MAN[3]: 6, 5, 2, 9, 1, 7, 8, 4, 0, 3, WOMAN[3]: 8, 4, 5, 7, 3, 6, 9, 2, 0, 1, MAN[4]: 6, 2, 5, 9, 0, 1, 7, 4, 3, 8, WOMAN[4]: 5, 4, 8, 3, 1, 9, 2, 0, 6, 7, MAN[5]: 9, 0, 2, 1, 3, 5, 4, 7, 8, 6, WOMAN[5]: 7, 5, 8, 0, 6, 1, 2, 9, 4, 3, MAN[6]: 5, 1, 3, 8, 6, 4, 7, 0, 9, 2, WOMAN[6]: 1, 3, 0, 4, 5, 7, 9, 6, 2, 8, MAN[7]: 7, 9, 4, 8, 3, 2, 5, 1, 0, 6, WOMAN[7]: 9, 2, 0, 3, 4, 1, 6, 5, 8, 7, MAN[8]: 2, 4, 1, 6, 3, 5, 9, 0, 8, 7, WOMAN[8]: 6, 4, 1, 8, 7, 5, 3, 0, 9, 2, MAN[9]: 8, 0, 2, 5, 4, 3, 9, 1, 7, 6, WOMAN[9]: 3, 2, 6, 4, 1, 7, 9, 0, 8, 5, == trial 0 == MEN: 2 9 1 6 10 10 5 7 10 8 WOMEN: 10 2 0 10 10 6 3 7 9 1 == trial 1 == MEN: 2 9 1 6 10 0 5 7 4 8 WOMEN: 5 2 0 10 8 6 3 7 9 1 == trial 2 == MEN: 2 9 1 6 10 0 5 7 4 8 WOMEN: 5 2 0 10 8 6 3 7 9 1 == trial 3 == MEN: 2 10 1 6 9 0 5 7 4 8 WOMEN: 5 2 0 10 8 6 3 7 9 4 == trial 4 == MEN: 10 0 1 6 9 2 5 7 4 8 WOMEN: 1 2 5 10 8 6 3 7 9 4 == trial 5 == MEN: 3 0 1 6 9 2 5 7 4 8 WOMEN: 1 2 5 0 8 6 3 7 9 4 == trial 6 == MEN: 3 0 1 6 9 2 5 7 4 8 WOMEN: 1 2 5 0 8 6 3 7 9 4 == trial 7 == MEN: 3 0 1 6 9 2 5 7 4 8 WOMEN: 1 2 5 0 8 6 3 7 9 4 == trial 8 == MEN: 3 0 1 6 9 2 5 7 4 8 WOMEN: 1 2 5 0 8 6 3 7 9 4 == trial 9 == MEN: 3 0 1 6 9 2 5 7 4 8 WOMEN: 1 2 5 0 8 6 3 7 9 4



#include <stdio.h>
 
int verbose = 0;
enum {
	clown = -1,
	abe, bob, col, dan, ed, fred, gav, hal, ian, jon,
	abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan,
};
const char *name[] = {
	"Abe", "Bob", "Col",  "Dan", "Ed",  "Fred", "Gav", "Hal",  "Ian", "Jon",
	"Abi", "Bea", "Cath", "Dee", "Eve", "Fay",  "Gay", "Hope", "Ivy", "Jan"
};
int pref[jan + 1][jon + 1] = {
	{ abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay },
	{ cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay },
	{ hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan },
	{ ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi },
	{ jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay },
	{ bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay },
	{ gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay },
	{ abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee },
	{ hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve },
	{ abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope },
 
	{ bob, fred, jon, gav, ian, abe, dan, ed, col, hal   },
	{ bob, abe, col, fred, gav, dan, ian, ed, jon, hal   },
	{ fred, bob, ed, gav, hal, col, ian, abe, dan, jon   },
	{ fred, jon, col, abe, ian, hal, gav, dan, bob, ed   },
	{ jon, hal, fred, dan, abe, gav, col, ed, ian, bob   },
	{ bob, abe, ed, ian, jon, dan, fred, gav, col, hal   },
	{ jon, gav, hal, fred, bob, abe, col, ed, dan, ian   },
	{ gav, jon, bob, abe, ian, dan, hal, ed, col, fred   },
	{ ian, col, hal, gav, fred, bob, abe, ed, jon, dan   },
	{ ed, hal, gav, abe, bob, jon, col, ian, fred, dan   },
};
int pairs[jan + 1], proposed[jan + 1];
 
void engage(int man, int woman)
{
	pairs[man] = woman;
	pairs[woman] = man;
	if (verbose) printf("%4s is engaged to %4s\n", name[man], name[woman]);
}
 
void dump(int woman, int man)
{
	pairs[man] = pairs[woman] = clown;
	if (verbose) printf("%4s dumps %4s\n", name[woman], name[man]);
}
 
/* how high this person ranks that: lower is more preferred */
int rank(int this, int that)
{
	int i;
	for (i = abe; i <= jon && pref[this][i] != that; i++);
	return i;
}
 
void propose(int man, int woman)
{
	int fiance = pairs[woman];
	if (verbose) printf("%4s proposes to %4s\n", name[man], name[woman]);
 
	if (fiance == clown) {
		engage(man, woman);
	} else if (rank(woman, man) < rank(woman, fiance)) {
		dump(woman, fiance);
		engage(man, woman);
	}
}
 
int covet(int man1, int wife2)
{
	if (rank(man1, wife2) < rank(man1, pairs[man1]) &&
			rank(wife2, man1) < rank(wife2, pairs[wife2])) {
		printf( "    %4s (w/ %4s) and %4s (w/ %4s) prefer each other"
			" over current pairing.\n",
			name[man1], name[pairs[man1]], name[wife2], name[pairs[wife2]]
		);
		return 1;
	}
	return 0;
}
 
int thy_neighbors_wife(int man1, int man2)
{	/* +: force checking all pairs; "||" would shortcircuit */
	return covet(man1, pairs[man2]) + covet(man2, pairs[man1]);
}
 
int unstable()
{
	int i, j, bad = 0;
	for (i = abe; i < jon; i++) {
		for (j = i + 1; j <= jon; j++)
			if (thy_neighbors_wife(i, j)) bad = 1;
	}
	return bad;
}
 
int main()
{
	int i, unengaged;
	/* init: everyone marries the clown */
	for (i = abe; i <= jan; i++)
		pairs[i] = proposed[i] = clown;
 
	/* rounds */
	do {
		unengaged = 0;
		for (i = abe; i <= jon; i++) {
		//for (i = abi; i <= jan; i++) { /* could let women propose */
			if (pairs[i] != clown) continue;
			unengaged = 1;
			propose(i, pref[i][++proposed[i]]);
		}
	} while (unengaged);
 
	printf("Pairing:\n");
	for (i = abe; i <= jon; i++)
		printf("  %4s - %s\n", name[i],
			pairs[i] == clown ? "clown" : name[pairs[i]]);
 
	printf(unstable()
		? "Marriages not stable\n" /* draw sad face here */
		: "Stable matchup\n");
 
	printf("\nBut if Bob and Fred were to swap:\n");
	i = pairs[bob];
	engage(bob, pairs[fred]);
	engage(fred, i);
	printf(unstable() ? "Marriages not stable\n" : "Stable matchup\n");
 
	return 0;
}



出力結果
Pairing:
   Abe - Ivy
   Bob - Cath
   Col - Dee
   Dan - Fay
    Ed - Jan
  Fred - Bea
   Gav - Gay
   Hal - Eve
   Ian - Hope
   Jon - Abi
Stable matchup

But if Bob and Fred were to swap:
    Fred (w/ Cath) and  Ivy (w/  Abe) prefer each other over current pairing.
     Bob (w/  Bea) and  Fay (w/  Dan) prefer each other over current pairing.
     Bob (w/  Bea) and Hope (w/  Ian) prefer each other over current pairing.
     Bob (w/  Bea) and  Abi (w/  Jon) prefer each other over current pairing.
    Fred (w/ Cath) and  Dee (w/  Col) prefer each other over current pairing.
    Fred (w/ Cath) and  Abi (w/  Jon) prefer each other over current pairing.
Marriages not stable


Google







メカニズムデザイン


マーケットデザイン入門


学校選択制のデザイン