稳定匹配算法理解和Python实现

首先,男生需要按照对女生的好感对所有女生进行排序,即把最喜欢的女生排在最前,最不喜欢的放在最后。同样,每个女生 也需要给男生排序。【4 2 3 1】代表男生 1 的情感去向,他最喜欢女生 4,最不喜欢女生 1。 接着,男生将按照自己的名单一轮一轮地去对喜欢的女生表白,女生也将按照自己的偏好列表选择接受或拒绝男生的表白。 第一轮,每个男生都向自己名单上排在首位的女生表白。此时,一个女生可能面对的情况有三种:没有人跟她表白、只有一人 跟她表白、有不止一人跟她表白。在第一种情况下,这个女生什么都不做,继续等待即可;在第二种情况下,女生接受那个人 的表白,答应暂时和他做男女朋友;在第三种情况下,女生从所有追求者中选择自己最喜欢的那一位,答应和他暂时做男女朋 友,并拒绝其他所有的追求者。 没有男生给女生 2 表白,因此女生 2 静待缘分。女生 3 和女生 4 分别都收获了一位男生的表白,她们选择接受表白,和男生在 一起。而女生 1 收到了 2 位男生的表白,而女生 1 的偏好列表种,她更喜欢男生 4,因此她和男生 4 在一起,拒绝了男生 3。 第一轮结束后,男生 1、2、4 已经有女朋友了,而男生 3 被发了好人卡,依旧是单身狗。。。 第二轮,每个单身男生都会从所有还没拒绝过自己的女生中选出自己最喜欢的那一个,并向她表白,无论女生现在是否单身。 对于女生,和第一轮一样,每个被表白的女生需要从表白者中选择最喜欢的一位,并拒绝其他追求者。注意,如果这个女生当 前已经有男朋友了,当她遇到了偏好列表上更喜欢的追求者时,她将毫不犹豫地和现男友劈腿,投向新追求者的怀抱。这样以 来,一些单身狗将脱单,而某些倒霉的舔狗也会被绿,重新进入单身狗的行列。 可以看到,由于上一轮中每个男生都跟最喜欢的女生表了白,因此现在的偏好列表中,我们删除已经表白的女生。 在这一轮中,因为男生 3 是单身狗,因此只有他继续寻爱,他跟目前最喜欢的女生 3 表白。女生 3 在上一轮已经有男朋友(男 生 2),但她更喜欢男生 3,因此女生决定绿了男生 2,让男生 3 当接盘侠。 以后每一轮都如此循环,单身的男生跟还没有拒绝过他且当前最喜欢的女生示爱,直到所有男生都找到对象,循环结束。 这里注意一个问题,我们让男人对女人进行表白,而女人只被动的选择接受或拒绝表白,这种情况其实是对男人有利而对女人 不利的,女人是被动的,通常情况下无法和自己最喜欢的男人谈恋爱。想要改变这种情况,我们只需要调换男人和女人所执行 的行为,即:女人表白,男人接受或拒绝。

#data:
# data=[[2,6,4],[3,5,1],
#    [6,2,4],[3,5,1],
#    [2,4,6],[1,5,3]
#    ]
#2,4,6代表女生,是男生喜欢女生的列表数据(在data中下标值为0,2,4)
#1,3,5代表男生,是女生喜欢男生列表数据(在data中下标值为1,3,5)
def GS_Stable_Matching(Data):
    #临时婚配数据
    TemporaryMarriage=dict()
    #稳定婚配数据
    StableMariage=dict()
    #自由的男人
    FreeMan = list()
    #自由的女人
    FreeWoman=list()
    #数据长度的一半
    n=len(Data)//2
    #TemporaryMarriage:{1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0}
    #man=[1,3,5]
    #TemporaryMarriage的值为0,表示没有婚配过
    for i in range(n):
        #初始化男人临时婚配数据,对应TemporaryMarriage数据的keys(1,3,5)
        TemporaryMarriage[2*i+1]=0
        #初始化女人临时婚配数据,对应TemporaryMarriage数据的keys(2,4,6)
        TemporaryMarriage[2*i+2]=0
        #奇数表示男生
        FreeMan.append(2*i+1)
        #偶数表示女生
        FreeWoman.append(2*2+2)
    #次数
    count=0
    #如果自由男人存在
    while len(FreeMan):
        #取出这个自由男人(这里的值是1,3,5,7....)
        man_new=FreeMan[0]
        #存储下一个喜欢女人的下标值
        unmarried_women_index=0
        #如果这个男人以前婚配过,其结果会在StableMariage中出现
        if man_new in StableMariage:
            #这个男人的值(1,3,5,7....)减一就是对应Data数据中的第0列、第2列、第4列和第6列....)
            #拿出这个男人的喜欢的女生列表
            like_women_list=Data[man_new-1]
            #排除已经和男人暂时婚配的女人(被女人拒绝)
            #test_list.index(Test[man_new])+1:取出这个男人的喜欢的下一位女生的下标值
            unmarried_women_index=like_women_list.index(StableMariage[man_new])+1
        #拿出这个男人的喜欢的女生列表(从未婚配的女生开始)
        for woman in Data[man_new-1][unmarried_women_index:n]:
            count+=1
            #如果这个女人是自由的
            if  TemporaryMarriage[woman]==0:
                #记载男人man_new和女人woman婚配
                TemporaryMarriage[man_new]=woman
                TemporaryMarriage[woman]=man_new
                #移除已婚配的男人
                FreeMan.remove(man_new)
                #记载婚配
                StableMariage[man_new]=woman
                break
            #如果这个女人不是自由(以前婚配过)
            else:
                #man_new和暂时婚配的男人,如果这个女人更喜欢man_new
                if Data[woman-1].index(man_new)<Data[woman-1].index(TemporaryMarriage[woman]):
                    #移除这个自由男人(已婚配)
                    FreeMan.remove(man_new)
                    #加载暂时婚配的那个男人(比不过man_new,被女人woman抛弃)
                    FreeMan.append(TemporaryMarriage[woman])
                    #暂时答应婚配的数据恢复为0
                    TemporaryMarriage[TemporaryMarriage[woman]] = 0
                    #记载暂时婚配的数据
                    TemporaryMarriage[woman]=man_new
                    TemporaryMarriage[man_new]=woman
                    #记载婚配结果
                    StableMariage[man_new] = woman
                    break
    return  StableMariage

data=[[2,6,4],[3,5,1],
   [2,6,2],[3,1,5],
   [6,2,4],[1,5,3]
   ]

print(GS_Stable_Matching(data))


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值