Stable Matching Problem穩定匹配問題—–穩定婚姻演算法

來源:互聯網
上載者:User

原文地址“http://blog.csdn.net/cscmaker/article/details/8291131

(一)問題的引出:

            有N男N女,每個人都按照他對異性的喜歡程度排名。現在需要寫出一個演算法安排這N個男的、N個女的結婚,要求兩個人的婚姻應該是穩定的。

            何為穩定?

            有兩對夫妻M1 F2,M2 F1。M1心目中更喜歡F1,但是他和F2結婚了,M2心目中更喜歡F2,但是命運卻讓他和F1結婚了,顯然這樣的婚姻是不穩定的,隨時都可能發生M1和F1私奔或者M2和F2私奔的情況。所以在做出匹配選擇的時候(也就是結婚的時候),我們需要做出穩定的選擇,以防這種情況的發生。

(二)演算法介紹:

   參考:http://www.matrix67.com/blog/archives/2976

   1962 年,美國數學家 David Gale 和 Lloyd Shapley 發明了一種尋找穩定婚姻的策略。不管男女各有多少人,不管他們各自的偏好如何,應用這種策略後總能得到一個穩定的婚姻搭配。換句話說,他們證明了穩定的婚姻搭配總是存在的。有趣的是,這種策略反映了現實生活中的很多真實情況。
    

    演算法中採用了男生主動追求女孩的形式。

    演算法步驟描述:

        第一輪,每個男人都選擇自己名單上排在首位的女人,並向她表白。這種時候會出現兩種情況:(1)該女士還沒有被男生追求過,則該女士接受該男生的請求。(2)若該女生已經接受過其他男生的追求,那麼該女生會將該男士與她的現任男友進行比較,若更喜歡她的男友,那麼拒絕這個人的追求,否則,拋棄其男友(囧)……

       第一輪結束後,有些男人已經有女朋友了,有些男人仍然是單身。

       在第二輪追女行動中,每個單身男都從所有還沒拒絕過他的女孩中選出自己最中意的那一個,並向她表白,不管她現在是否是單身。這種時候還是會遇到上面所說的兩種情況,還是同樣的解決方案。直到所有人都不在是單身。

怎麼證明這個演算法肯定能夠得到穩定的婚姻:

(1)隨著輪數的增加,總有一個時候所有人都能配上對。因為男生根據自己心目中的排名依次對女士進行表白,假如有一個人沒有配上對,那麼這個人必定是向所有的女孩進行表白了。但是女孩只要被表白過一次,就不可能是單身,也就是說此時所有的女生都不是單身的,這與有一個人沒有配上對是相悖的。所以假設不成立。該演算法一定會使得所有人都能夠配對成功。

(2)隨著輪數的增加,男士追求的對象越來越糟,而女士的男友則可能變得越來越好。假設男A和女1各有各自的對象,但是比起現在的對象,男A更喜歡女1,所以,在此之前男A肯定已經跟女1表白過的,並且女1拒絕了男A,也就是女1有了比男A更好的男友,不會出現私奔的情況……。

(三)演算法實現

#include<iostream>#include <stack>using namespace std;#define NUM 4#define NIL -1int GetPositionFromLaday(int ladayArray[][NUM], int laday, int man){for(int i=0; i<NUM; i++)if(ladayArray[laday][i] == man)return i;return NIL;}void ChoosePartener(stack<int>& manStack, int manPos, int manArray[][NUM], int ladayArray[][NUM], int manPerfer[], int manStartPos[], int ladayNow[]){//選擇自己名單上排在首位的女人int perferLaday = manArray[manPos][manStartPos[manPos]];//如果該女孩沒有接受過表白,則接受該男孩的表白if(ladayNow[perferLaday] == NIL){ladayNow[perferLaday] = manPos;manPerfer[manPos] = perferLaday;}//如果已經有人向她表白,則判斷其現在擁有的有沒有現在追求的好else{int oldPos = GetPositionFromLaday(ladayArray, perferLaday, ladayNow[perferLaday]);int newPos = GetPositionFromLaday(ladayArray, perferLaday, manPos); if(oldPos < newPos){manStartPos[manPos]++;//說明該女生更喜歡現在擁有的,選心目中第二位//加入單身行列manStack.push(manPos);}else //換男友{//被甩的男友恢複自由身份manStartPos[ladayNow[perferLaday]]++;//加入單身行列manStack.push(ladayNow[perferLaday]);//將追求的男士改為現任男友ladayNow[perferLaday] = manPos;manPerfer[manPos] = perferLaday;}}}int main(){int manArray[NUM][NUM] ={{2,3,1,0},{2,1,3,0},{0,2,3,1},{1,3,2,0}};int ladayArray[NUM][NUM] = {{0,3,2,1},{0,1,2,3},{0,2,3,1},{1,0,3,2}};int manPerfer[NUM] = {0};//每位男生選中的女生int manStartPos[NUM] = {0};//記錄每位男生選取的是心目中第幾位的女生int ladayNow[NUM] = {NIL,NIL,NIL,NIL};//女生對應的男生stack<int> manStack; // 還處於單身的男士//進行第一輪迭代,每個男生都選擇自己名單上排在首位的女生。for(int pos=0; pos<NUM; pos++){ChoosePartener(manStack, pos, manArray, ladayArray, manPerfer, manStartPos,ladayNow);}while(manStack.size()!=0){int manPos = manStack.top();manStack.pop();ChoosePartener(manStack, manPos, manArray, ladayArray, manPerfer, manStartPos,ladayNow);}for(int i =0;i<NUM; ++i)cout<<"Man NO.: "<<i<<" Laday NO.: "<<manPerfer[i]<<endl;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.