日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Gale-Shapley算法

發(fā)布時(shí)間:2024/8/23 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gale-Shapley算法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

最近看了一檔綜藝《心動(dòng)的信號(hào)》(唉, 單身久了, 開(kāi)始喜歡看別人談戀愛(ài)了)

節(jié)目中共有n男n女, 他們會(huì)在節(jié)目的最后進(jìn)行表白, 如果我喜歡你, 恰好你也喜歡我, 那么便就會(huì)在一起, 自此傳為一段佳話.

于是, 我就在想, 如何用算法來(lái)實(shí)現(xiàn)這個(gè)匹配的過(guò)程呢?

單一匹配

將信息抽象化, 現(xiàn)有兩個(gè)集合 M N, 每個(gè)集合中存在a個(gè)對(duì)象.

結(jié)果集 R 中元素為 (m, n), 其中 m ∈ M, n ∈ N, m 喜歡 n, n 也喜歡 m.

OK, 設(shè)計(jì)數(shù)據(jù)結(jié)果進(jìn)行實(shí)現(xiàn). (以下以Go進(jìn)行簡(jiǎn)單演示)

package mainimport "fmt"type people struct {Name string // 名字LikePeople string // 喜歡的人名 }type lovers struct {Boy peopleGirl people }func main() {// 分別構(gòu)造男女隊(duì)列boyArr := []people{}girlArr := []people{}// 分別對(duì)他們進(jìn)行匹配var result []loversfor _, boy := range boyArr {// 查看他喜歡的女孩是否喜歡他for _, girl := range girlArr {if boy.LikePeople == girl.Name {// 兩情相悅了if girl.LikePeople == boy.Name {result = append(result, lovers{Boy: boy,Girl: girl,})}break}}}fmt.Println(result) }

當(dāng)然, 這就是簡(jiǎn)單的循環(huán)查找, 但是如果將喜歡的人, 從單個(gè)換成一個(gè)列表呢? 別說(shuō), 我后面找了一下, 還真有這么一個(gè)算法.

Gale-Shapley 算法

再來(lái).現(xiàn)有兩個(gè)集合 M N, 每個(gè)集合中分別存在a個(gè)對(duì)象. 匹配集 R 中的元素為: (m, n), 其中 m ∈ M, n ∈ N.

到這, 基本上和我們上面的匹配一致. Gale-Shapley在此基礎(chǔ)上, 提出了完美匹配穩(wěn)定匹配的概念.

完美匹配

完美匹配是指, M 和N的每個(gè)成員, 都恰好出現(xiàn)在R的一個(gè)匹配隊(duì)列中. 恰好的意思是, 不多不少就一次.

說(shuō)人話就是: M和N中的所有人都配對(duì)成功, 不存在落單的男孩或女孩.

穩(wěn)定匹配

一個(gè)完美匹配中如果不存在不穩(wěn)定因素, 就稱為穩(wěn)定匹配.

我們上面每個(gè)人只能喜歡一個(gè)人, 現(xiàn)在不是了, 每個(gè)人都有一個(gè)喜歡程度從高到低的列表.

如果說(shuō) m1 在 n1 n2中更喜歡 n2, 那么m1的喜歡列表就是[n2, n1].

簡(jiǎn)單解釋一下不穩(wěn)定因素. 如果在結(jié)果集中, 存在這樣的兩個(gè)元素: (m1, n1), (m2, n2). 而m1相較于n1更喜歡n2, 同時(shí)n2相較于m2也更喜歡m1, 那么他倆就有私奔的可能. 這種可能就稱為不穩(wěn)定因素.

Gale-Shapley算法, 就是從中得出一個(gè)穩(wěn)定匹配的算法. 算法的思想通俗易懂, 一句話概括: 所有男生依次嘗試想所有女生表白

算法的實(shí)現(xiàn)步驟如下:

  • 找到一個(gè)還沒(méi)有對(duì)象, 且未向所有女生表白的男生m
  • 找到一個(gè)m還沒(méi)有表白過(guò)的女生n
  • 如果n還沒(méi)有對(duì)象, 則進(jìn)行匹配
  • 如果n有對(duì)象. 則判斷n的喜歡列表. 若更喜歡當(dāng)前對(duì)象, 則保持不變, 若更喜歡m則拋棄當(dāng)前對(duì)象
  • 直到m找到對(duì)象或向所有女生都表白過(guò). 則回到第一步, 直到找不到這樣的男生.

通過(guò)流程上來(lái)看, 這是一個(gè)時(shí)間復(fù)雜度O(n^2)的算法. 借用Go來(lái)簡(jiǎn)單實(shí)現(xiàn)一下:

package maintype people struct {Name string // 名字LikePeople []string // 喜好列表CurrentLike int // 后面算法記錄當(dāng)前表白對(duì)象時(shí)使用Friend string // 當(dāng)前匹配對(duì)象 }func main() {// 分別構(gòu)造男女隊(duì)列boyArr := []*people{}girlArr := []*people{}for true {// 找到一個(gè)沒(méi)有對(duì)象, 且未全部表白的男生var searchBoy *peoplefor _, boy := range boyArr {if boy.Friend != "" { // 當(dāng)前男孩已經(jīng)有對(duì)象了continue}// 男孩向所有女生表白過(guò)了if boy.CurrentLike >= len(boy.LikePeople) {continue}searchBoy = boybreak}if searchBoy == nil { // 已經(jīng)全部有對(duì)象了, 結(jié)束break}// 男生向女生依次表白var i intfor i := searchBoy.CurrentLike; i < len(searchBoy.LikePeople); i++ {girlName := searchBoy.LikePeople[i]// 找到這個(gè)女孩girl := searchPeople(girlArr, girlName)if girl == nil { // 習(xí)慣了, 判下空continue}if girl.Friend == "" { // 若女孩沒(méi)有對(duì)象, 則直接配對(duì)girl.Friend = searchBoy.NamesearchBoy.Friend = girl.Namebreak} else { // 若女孩有對(duì)象, 看下 girl 更喜歡誰(shuí)searchBoyIdx := searchNameIndex(girl.LikePeople, searchBoy.Name)girlFriendIdx := searchNameIndex(girl.LikePeople, girl.Friend)if girlFriendIdx < searchBoyIdx { // 保持當(dāng)前continue} else { // 重新組隊(duì)girlFriend := searchPeople(boyArr, girl.Friend)if girlFriend != nil { // 分手了girlFriend.Friend = ""}girl.Friend = searchBoy.NamesearchBoy.Friend = girl.Name}}}searchBoy.CurrentLike = i} }func searchPeople(peopleArr []*people, name string) *people {for _, people := range peopleArr {if people.Name == name {return people}}return nil }func searchNameIndex(nameArr []string, name string) int {for i, tmpName := range nameArr {if tmpName == name {return i}}return -1 }

攏共也沒(méi)有幾行, 但是, 它可以保證完美匹配穩(wěn)定匹配么? 這簡(jiǎn)單的邏輯讓我都有點(diǎn)不相信自己了, 不行, 得證明一下.

首先是完美匹配, 因?yàn)槭沁M(jìn)行的一對(duì)一匹配, 如果最終存在落單的女生, 那么就一定存在相同數(shù)量落單的男生. 同時(shí), 因?yàn)樵谂鷽](méi)有對(duì)象的時(shí)候, 會(huì)接收任意男生的表白, 可以得出落單的女生沒(méi)有收到過(guò)任何男生的表白. 而在匹配的過(guò)程中, 男生會(huì)向喜歡列表中的所有女生依次進(jìn)行表白, 得出落單的男生一定向所有女生進(jìn)行過(guò)表白. 前后矛盾. 故不存在這樣的情況. 因此結(jié)果為完美匹配.

那么結(jié)果是否是穩(wěn)定匹配呢? 如果結(jié)果中存在不穩(wěn)定因素, 既(m1, n1), (m2, n2), 其中m1更喜歡n2, 同時(shí)n2也更喜歡m1. 根據(jù)算法的規(guī)則, m1會(huì)先向n2表白, 此時(shí), 如果n2單身, 則會(huì)接受表白, 如果n2已經(jīng)接受了m2的表白, 則會(huì)毅然決然的選擇分手, 和m1在一起. 即使后面n2再次收到m2的表白, 也不會(huì)和m1進(jìn)行分手. 故不存在這樣的不穩(wěn)定因素. 因此結(jié)果為穩(wěn)定匹配.

算法優(yōu)化

我們?cè)谧铋_(kāi)始分析的時(shí)候, 時(shí)間復(fù)雜度是O(n^2), 現(xiàn)在再來(lái)看一下我們實(shí)現(xiàn)的時(shí)間復(fù)雜度. 上方算法共有一下幾層循環(huán):

  • 找到?jīng)]有對(duì)象且未全部表白的男生, n
    • 向女生依次表白, n
      • 找到表白的女生, n
      • 若女生有對(duì)象, 則從女生的喜歡列表中, 找到這兩個(gè)男孩. 2n
      • 若重新組隊(duì), 則找到女生的當(dāng)前對(duì)象, n

. 很顯然, 大 O 時(shí)間復(fù)雜度為O(n^3). 哎? 怎么和之前分析的不一樣呢? 很明顯, 就差在了第三層. 只要想辦法消掉就好啦.

  • 找到要表白的女孩. 直接存儲(chǔ)女孩的索引即可直接找到.
  • 找到女生當(dāng)前對(duì)象同理, 直接存儲(chǔ)索引.
  • 從女生的喜歡列表中, 找到更喜歡誰(shuí)? 將數(shù)組換成 map, 即可實(shí)現(xiàn)O(1)的查找. 空間換時(shí)間唄.

至此, 第三層的循環(huán)全部去掉. 時(shí)間復(fù)雜度為O(n^2). 能不能再降低呢? 我還沒(méi)有想到.

擴(kuò)展

人數(shù)不匹配

如果男女生人數(shù)不一致呢? 那自然是無(wú)法得出完美匹配穩(wěn)定匹配了, 但是通過(guò)上面的步驟, 無(wú)論是讓人數(shù)較少的一方主動(dòng)選擇, 還是人數(shù)較多的一方主動(dòng)選擇, 得出的還是一個(gè)比較滿意的匹配結(jié)果. 當(dāng)然, 因?yàn)槿藬?shù)不匹配, 最終是一定有落單的人.

喜歡列表不為全部

如果女生的喜歡列表, 只是部分男生呢? 那么對(duì)于未出現(xiàn)在喜歡列表的人有兩種情況:

  • 十分討厭, 不能進(jìn)行匹配
  • 無(wú)所謂, 如果不能和我喜歡的人在一起, 那和誰(shuí)都一樣
  • 對(duì)于這兩種態(tài)度, 處理方式也自然不同.

    如果不能進(jìn)行匹配, 則匹配結(jié)果可能不是完美匹配, 因?yàn)槟阆矚g的已經(jīng)和別人跑了, 而喜歡你的你又拒絕了.

    如果是無(wú)所謂的態(tài)度, 處理流程基本上和上面一致. 比較是不存在的給出一個(gè)較大的默認(rèn)值即可.

    應(yīng)用

    那么這個(gè)算法可以應(yīng)用到哪些場(chǎng)景呢? 想了一下, 關(guān)于這種意向匹配的場(chǎng)景, 基本上都可以參考此算法, 比如: 相親、工作分配、大學(xué)招生、拍賣等等


    別人看綜藝, 想從中學(xué)到交友之法, 而我看到的卻是算法? 或許, 破案了? 唉, 不說(shuō)了, 刷劇去了.

    總結(jié)

    以上是生活随笔為你收集整理的Gale-Shapley算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 91丨国产丨白丝 | 亚洲无码国产精品 | 午夜成人在线视频 | 男女日批在线观看 | 成人在线观看国产 | 国产精品不卡视频 | 精品国产一区二区三区久久久蜜月 | 春日野结衣av | 亚洲乱亚洲乱妇 | 国产人人插| 在线观看污污网站 | 国产成人愉拍精品久久 | 欧美s码亚洲码精品m码 | 久久无码高潮喷水 | 亚洲无套 | 国产精品欧美综合亚洲 | 国产传媒一区二区三区 | 亚洲美女操 | 一区二区成人精品 | 久草免费在线视频 | 狼人综合伊人 | 免费一级黄 | 我会温柔一点的日剧 | 国产欧美一区二区在线观看 | 自拍偷在线精品自拍偷无码专区 | 久草a在线 | 不卡影院一区二区 | 91视频在线视频 | 99在线视频精品 | 强开乳罩摸双乳吃奶羞羞www | 欧美www | 99热免费在线观看 | 天堂久久久久 | 天天鲁一鲁摸一摸爽一爽 | 无码人妻久久一区二区三区 | 欧美日韩综合精品 | 91久久人人 | 亚洲天堂aaa| 插少妇视频 | 在线免费观看黄色av | 日本aaa级片| 亚洲成a人在线观看 | 亚洲色图欧美在线 | 看免费一级片 | 男女做爰真人视频直播 | 老女人一毛片 | 一级片视频免费观看 | 久久艳片www.17c.com | 二十四小时在线更新观看 | 五月激情小说 | 综合爱爱网 | 调教撅屁股啪调教打臀缝av | 中国爆后菊女人的视频 | 色干综合 | 中国黄色小视频 | 欧美最猛性xxxx | 国产51页 | 欧美色图中文字幕 | 中文字幕国产视频 | 牛夜精品久久久久久久99黑人 | 日韩在线视频在线观看 | 成人在线三级 | 色www亚洲国产张柏芝 | 麻豆免费视频网站 | 美女日批视频在线观看 | 91精品国产高清 | 催眠美妇肉奴系统 | 日韩城人网站 | 国产在线综合视频 | 日韩av不卡在线观看 | 光棍影院手机版在线观看免费 | www.欧美 | 91高清免费视频 | 男生操女生在线观看 | 熟女少妇内射日韩亚洲 | 欧美无专区 | 久久9999久久免费精品国产 | 国产国语对白 | 国产精品久久久久久亚洲调教 | 欧美乱码精品一区二区 | 午夜黄色 | 国产三极片 | 国产青青操 | 亚洲无套 | 欧美18av| 波多野结衣中文字幕久久 | 亚州男人的天堂 | 欧美性狂猛xxxxxbbbbb | 极品少妇视频 | 少妇在线| 欧美日韩电影一区二区三区 | 黄色免费观看网站 | 国产不卡视频在线播放 | 嫩草影院av | 欧美另类极品videosbest使用方法 | 免费av手机在线观看 | 国产男女猛烈无遮挡a片漫画 | 嫩模被强到高潮呻吟不断 | 告诉我真相俄剧在线观看 |