【算法】戀愛中的博弈論(stable matching)(附帶源碼)

思路源自知乎:戀愛中有那些博弈?,主要是@尼克餘 的回答。感謝他。然後原文有些描述不清楚的,我直接就按照我的理解補充上去了。


注:本文采用C#實現


首先假設一個虛擬世界,這個世界中分別有N個男生,N個女生,男生與女生數量完全一樣,男生女生都有一個心儀對象列表,不同的人的心儀對象列表都是隨機的,在心儀對象列表排名越前面,說明對於他(她)來說越喜歡。男生能向女生表白,女生不能向男生表白,女生能接受或者拒絕男生的表白。


男生首先會向對他最喜歡的女生表白,然後是次喜歡的,依次下去表白。而女生則通過對錶白的男生進行判斷,如果他是自己心儀列表裏面排名第一的,嗯,就是他了,他就是最適合我的。但是如果不是,女生會說,對不起,你是個好人,然後拒絕男生。然後女生會想,是不是我要求太高了,那排名第二的也可以啦。然後女生把排名限制放寬到第二名。但是相應的,第二名就不是女生的最佳伴侶,如果她接受了第二名的邀請,那就說明她的幸福感並不是最高的。當然,如果在第二名向她表白之後,第一名也向她表白,她會無情的甩掉第二名,然後和第一名麼麼噠。


ok,基於上述要求,那麼首先要設計一個人類,人類需要有下面幾個屬性,分別是編號(方便認識和排序),性別,心儀對象列表,預期對象,伴侶。然後這個類還要能表白,能接受表白。主要功能就那麼多了。下面是類的設計

    enum Sex
    {
        Man,
        Woman
    }
    class Human
    {
        int _index = 0;                   //索引
        public int index { get { return _index; } }

        Sex _sex = Sex.Man;               //性別
        public Sex sex { get { return _sex; } }

        List<Human> _loveList = new List<Human>();  //心儀對象列表

        int _curLoveIndex = 0;         //幸福感
        public int LoveIndex { get { return _curLoveIndex; } }

        Human _partner = null;         //伴侶
        public Human partner { get { return _partner; } set { _partner = value; } }
        //表白
        public bool Confession()
        {

        }

        //考慮是否接受
        public bool Accept(Human askMan)
        {

        }
    }

首先是最爲重要的表白程序啦,表白者首先要獲取到心儀對象列表,挨個和心儀的對象表白,如果對象接受了,那OK,戀愛吧;如果對象不接受,嗯,傷心一下,繼續和下一個表白。哈哈哈。以下是表白函數的實現

        //表白
        public bool Confession()
        {
            if (_loveList.Count >= GetLoveIndex())
            {
                for (int i = 0; i < GetLoveIndex(); i++)
                {
                    form.AddList(string.Format("{0}號向{1}號表白", index, _loveList[i].index));
                    if (_loveList[i].Accept(this))      //表白
                    {
                        //成功
                        //設置伴侶
                        _partner = _loveList[i];
                        return true;
                    }
                    else
                    {
                        //失敗
                        //降低幸福感
                        AddLoveIndex();
                    }
                }
            }
            return false;
        }

表白了妹紙就要確定接受與否了,首先妹紙得看這個人自己喜歡不喜歡,如果不喜歡,直接拒絕沒得商量;如果喜歡的話,再看看自己有沒有男朋友;有男朋友的話,看看哪個比較好,如果男朋友比較差,那就直接甩了男朋友。妹紙就是醬紫 QAQ 

        //考慮是否接受
        public bool Accept(Human askMan)
        {
            if (_loveList.Count >= GetLoveIndex())
            {
                var list = _loveList.Take(GetLoveIndex()).ToList();
                var man = list.FirstOrDefault(x => x._index == askMan._index);
                if (man != null)
                {
                    //對象單身了
                    if (_partner != null)
                    {
                        _partner.partner = null;
                        _partner.AddLoveIndex();
                        form.AddList(string.Format("{0}號失戀了,他的伴侶{1}號接受了{2}號的表白", _partner.index, index, askMan.index));
                    }
                    _partner = askMan;
                    return true;
                }
                else
                {
                    //女生還單身的時候
                    AddLoveIndex();
                    return false;
                }
            }

            return false;
        }


然後就是虛擬世界的表白算法了,虛擬世界規定:1.只有男性才能表白 2.只有單身的男性才能表白

        //開始表白
        void StartConfession()
        {
            AddList("開始表白");
            foreach (var p in people)
            {
                if (p.sex == Sex.Man && p.partner == null)
                {
                    bool result = p.Confession();
                    if (result == true)
                    {
                        //戀愛
                        string msg = string.Format("{0}號與{1}號戀愛了", p.index, p.partner.index);
                        AddList(msg);
                    }
                    else
                    {
                        AddList(string.Format("{0}號表白失敗", p.index));
                    }
                }
            }
        }

然後知乎上的結果是,女性的幸福感會比男性的低,我設置了一千組數據,看看誰的幸福感比較高(注意,程序中設定幸福感數值越高表示幸福感越低,詳情請看函數AddLoveIndex)(PS:這只是運行一次的結果,運行多次結果可能不同)



源碼 點擊打開鏈接


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章