Stable Matching 稳定匹配 婚姻算法 shapley 算法
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4051286.html
稳定匹配问题:有N男N女,每个人对于异性都一个排名,先需要得到一种稳定的匹配,即不会出现一个匹配中的人与另一个匹配中的异性对对方的排名均高于目前配对的人的排名。
shapley算法:
每次取出一个单身男生,让他向没有拒绝过她的女生中其排名最高人表白,若该女生没有对象则配对成功,否则与其当前的对象排名进行对比,如果当前对象排名较高,则拒绝表白男生,否则dump掉目前对象。直到没有单身男子为止。
伪代码如下:
for m = 1 to M do
partner[m] = NULL
end for
for w = 1 to W do
partner[w] = NULL
end for
while TRUE do
if there is no man m such that partner[m] = NULL then
return;
end if
select such a man m arbitrarily;
w = the first woman on m′ s list to whom m have not yet proposed;
if partner[w] == NULL then
partner[w] = m; partner[m] = w;
else if w prefers m to state[w] then
partner[partner[w]] = NULL; partner[w] = m; partner[m] = w;
else
; //do nothing means simply rejecting m;
end if
end while
实现时,可以把单身男生放入一个队列中,每次取出一个进行配对。另外为了在O(1)时间内找到第i个男生的第j喜欢的女生,令排名矩阵ManMat[i][j]表示男生i的第j喜欢的女生为ManMat[i][j]。为了在O(1)的时间内找到第i个女生对第i个男生的排名,令排名矩阵WomanMat[i][j]表示第i个女生对与第j个男生的排名为WomanMat[i][j]。这两个矩阵并不对称。
代码如下:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <cstring> 5 #include <map> 6 #include <fstream> 7 #include <queue> 8 #define MAXNUM 1000 9 using namespace std; 10 int ManMat[MAXNUM][MAXNUM];//man i's jth favourate woman is ManMat[i][j] 11 int WomanMat[MAXNUM][MAXNUM];//woman i's to the man j's rank is WomanMat[i][j] 12 int ManPartner[MAXNUM];//man i's partner woman is ManPartner[i] 13 int WomanPartner[MAXNUM];//woman i's partner man is WomanPartner[i] 14 int ManPropose[MAXNUM];//ManPropose[i] means the number of man i's propose 15 void shapley(int n) 16 { 17 memset(ManPartner, -1, sizeof(ManPartner)); 18 memset(WomanPartner, -1, sizeof(WomanPartner)); 19 queue<int> manqueue; 20 for( int i = 0 ; i < n ; i++ ) 21 { 22 manqueue.push(i); 23 } 24 int i = 0; 25 while(1) 26 { 27 if( manqueue.size() == 0 ) 28 { 29 return; 30 } 31 i = manqueue.front(); 32 int like = ManMat[i][ManPropose[i]]; 33 ManPropose[i]++; 34 if( WomanPartner[like] == -1 ) 35 { 36 WomanPartner[like] = i; 37 ManPartner[i] = like; 38 manqueue.pop(); 39 } 40 else if( WomanMat[like][WomanPartner[like]] > WomanMat[like][i] ) 41 { 42 ManPartner[WomanPartner[like]] = -1; 43 manqueue.push(WomanPartner[like]); 44 WomanPartner[like] = i; 45 ManPartner[i] = like; 46 manqueue.pop(); 47 } 48 } 49 }