演算法淺談——怎麼樣才最有可能選中真命天子呢?
本文始發於個人公眾號:TechFlow
正文開始之前,我們先來講一個故事。
在很久很久以前,有一個萬人迷。
她從18歲開始就有數不完的追求者,追她的男生一個個在她的窗前排起了長隊。但是她挑來挑去,終究不覺得滿意。終於,這個萬人迷一天天長大,年老色衰,在她門口排隊的男生也越來越少。
她開始後悔拒絕男生時的輕率,懷念起了從前的榮光。她也不知道,最後她是會向現實妥協,選擇一個看起來遠不是那麼好的男生共度一生,還是會就這麼一直等下去。
這樣的故事其實並不罕見,知乎裡關於剩男剩女以及婚嫁的問題屢見不鮮。選擇配偶也是我們人生當中的必經之路,蘇格拉底說過,人生就是一次無法重複的選擇,在婚姻這個問題上尤為明顯。
那麼問題來了,如果我們是故事中的萬人迷,我們應該如何選擇配偶呢?
即使是真的萬人迷,她可以選擇的配偶也一定是有限的。我們可以做一個簡單的量化,假設她一年平均有30個追求者,她打算28歲結婚。那麼從她18歲開始算起,假設她的魅力保持不變,她一共可以遇到300個潛在的配偶。
這個數字對於每個女生而言各有不同,但是它其實並不重要,並不會影響我們的計算過程。為了簡化計算,我們就假設它為n。接著,我們再進一步簡化模型,假設這n個男生排成一隊,一個一個地來發起追求。我們假設女生面臨每個追求者的時候只會有兩個選擇,一是直接拒絕,二是答應追求,從此牽手共度一生。
那麼,我們來做一個好的決策呢?
和現實中一樣,一種比較聰明的做法是,先和前面的一些男生每個人都相處一段時間,做一個瞭解,摸清這些男生大概的水平底細之後再認真考慮。抽象成數學模型來,就是女生會直接拒絕掉前面k個男生,從第k+1個男生開始一一和前面k個男生比對。當一個比前面k個男生都要好的男生出現的時候,她果斷選擇接受,從此和他共度一生。
如此一來,這就成了一個數學問題,究竟這個k應該等於多少,才可以使得女生選中所有男生當中最好的那個的概率最大呢?
所以,我們應該怎麼求出這個K呢?
對於某個固定的K,我們假設最佳配偶出現在了第i的位置。想讓他能被挑選中,必須要保證前面i-1個人中的最好的配偶出現在前K個人當中。也就是說如果真命天子前面沒有出現另一個優質的男生,會導致女生在遇見真命天子前就草草選擇。從這個問題上來說,真命天子也需要好的對手陪襯。
這個概率不難計算,是:\(\frac{K}{i-1}\)。
那麼,我們對所有的i進行加權求和即可:
\(P(K)=\sum_{i=K+1}^n\frac{1}{n}\cdot \frac{K}{i-1}=\frac{K}{n}\sum_{i=K+1}^n\frac{1}{i-1}\)
我們假設n是一個很大的值,我們可以先算後面的部分。如果n足夠大,可以認為
\[\sum_{i=K+1}^n\frac{1}{i-1}=\int_{K}^n\frac{1}{t}dt=ln(n)-ln(K)=ln(\frac{n}{K})\]
我們令\(x=\frac{K}{n}\)
求積分,可以得到:
\(P(K)=x(ln(\frac{n}{K}))=x(ln(\frac{1}{x}))=-x\cdot ln(x)\)
我們對\(P(K)\)的求導,令它等於0,可以求出\(P(K)\)最大時\(x=\frac{1}{e}\)。這裡的\(e\)就是數學當中經常出現的尤拉常數,也叫自然底數,\(\frac{1}{e}\)約等於37%. 那麼,算到了這個結果,這個問題也就有了答案。
如果你是一個萬人迷,那麼你應該拒絕掉前面37%的追求者,然後在剩下的63%的男士當中挑選一個比前面都強的作為配偶。那麼你選到最佳配偶的概率達到最大值,它的概率為37%。
雖然有了答案,但是我們並不知道這個答案對不對,但是沒關係,我們是程式設計師,可以用程式碼來模擬。
我們就按照萬人迷的配置來設定好了,假設她一生當中會面臨300個追求者。我們假設這三百個追求者的好壞層次不齊,按照分數排序,可以得到一個0到299的序號。排名越靠後,說明分數越大,男生越優質,然後我們再對這些男生進行亂序。
import random
def generateBoys():
boys = [i for i in range(300)]
random.shuffle(boys)
return boys
接著我們來編寫程式的主體,其實也很簡單,我們模擬進行許多次同樣的配偶選擇,模擬出我們通過這種策略能夠選中最佳配偶的概率,程式碼並不難寫:
# iterations 是模擬擇偶的次數
def simulation(iterations=10000):
matched = 0
for i in range(iterations):
# 每次都建立新的追求者集合
boys = generateBoys()
# 最佳配偶的序號
best = max(boys)
maxi = 0
partner = 0
# 計算K, K=0.37 * 追求者總數
pickedNum = int(0.37 * len(boys))
for j in range(pickedNum):
maxi = max(maxi, boys[j])
# 一旦找到比前K個最好的都要好的,就結束
for j in range(pickedNum, len(boys)):
if boys[j] > maxi:
partner = boys[j]
break
# 判斷是否找到了最佳配偶
if partner == best:
matched += 1
return matched / float(iterations)
最後,我們執行程式碼,得出的答案是0.3629。當然這也不是一個精確值,也是一個會波動的估算結果。迭代的次數越多,這個得到的結果越逼近真實值。用大量的實驗去測算某個事件發生的概率,這個也是統計學上常用的方法。
通過建模,我們把一個抽象的,無從下手的問題,簡化成了一個明確的數學問題。通過建立函式求最值的方法,求出了最優解。從結果上來看,如果真有一個姑娘能有這麼多追求者,通過一種方法可以擁有37%的概率挑中她的真命天子,也算是非常棒了。
但是數學模型的是理想的,現實和理想總是有些差別。現實中,我們的時間精力是有限的,我們不一定有時間來一一衡量前面追求者的優劣。而且追求者的分佈也不一定是隨機的,很有可能隨著我們自身的變化而變化。比如我們通過自己的努力,去往了更好的學校、公司,那麼我們接觸到的異性也會更好。
不過儘管如此,這道演算法問題對我們還是很有借鑑意義,希望能夠給大家帶來啟發。
今天的文章就到這裡,希望大家有所收穫。如果喜歡本文,請順手點個關注吧。
相關推薦
演算法淺談——怎麼樣才最有可能選中真命天子呢?
本文始發於個人公眾號:TechFlow 正文開始之前,我們先來講一個故事。 在很久很久以前,有一個萬人迷。 她從18歲開始就有數不完的追求者,追她的男生一個個在她的窗前排起了長隊。但是她挑來挑去,終究不覺得滿意。終於,這個萬人迷一天天長大,年老色衰,在她門口排隊的男生也越來越少。 她開始後悔拒絕男生時的輕率,
BZOJ 1598 淺談AstaR啟發式搜尋有向圖網路K階最短路
世界真的很大 今天考了字串 沒看空限被86M卡空間唉,下次一定注意了 草草地學了一下這個什麼Astar演算法,也不算是完全瞭解吧就找了這道題來做做 Astar好像聽說在AI方面有很多運用,但是隻是在競賽中的話一般用做搜尋的剪枝和順序處理 這道題體現
查詢演算法 淺談演算法和資料結構: 七 二叉查詢樹 淺談演算法和資料結構: 十一 雜湊表
閱讀目錄 1. 順序查詢 2. 二分查詢 3. 插值查詢 4. 斐波那契查詢 5. 樹表查詢 6. 分塊查詢 7. 雜湊查詢 查詢是在大量的資訊中尋找一個特定的資訊元素,在計算機應用中,查詢是常用的基本運算,例如編譯程式中符號表的查詢。本文
淺談 Java 10 ,你可能不知道的五件事
Java 9出現之後僅僅過去6個月,現在Java 10已經在敲門了。與它的版本號一樣,Java 10提供了10個新特性,本文提供了我認為最重要的5個特性(您可以在Open JDK 10專案頁面上檢視它們)。區域性變數型別推斷是有爭議的熱點,但Java 10在JVM中的垃圾收集和容器識別上帶來
淺談Floyd解決最短路問題
我這條鹹魚又來啦!!啊哈演算法看到結尾部分,大佬說要給我幾個題測測我到什麼水平了,於是就有了這篇在被虐中寫出的部落格,不廢話了,粘題 大佬告訴我說這是一道裸的不能再裸的最短路題,但我還是掛了好幾次(鹹魚沒跑了) 先粘上我開始的錯誤程式碼再慢慢說 #include<bits/std
找出最有可能被 OOM Killer 殺掉的程序
最近有位 VPS 客戶抱怨 MySQL 無緣無故掛掉,還有位客戶抱怨 VPS 經常宕機,登陸到終端看了一下,都是常見的 Out of memory 問題。這通常是因為某時刻應用程式大量請求記憶體導致系統記憶體不足造成的,這通常會觸發 Linux 核心裡的 Out of Memory (OOM) ki
2019年3月華為最有可能出現的python面試題
這篇是小編,這麼多年去華為面試,總結的經驗。跟著小編走永遠不迷路,大不了多走幾條路。嘻嘻~! 1、有1、2、3、4個數字,能組成多少個互不相同且無重複數字的三位數?都是多少? 2、考慮如下表結構,寫出建表語句 3、order by與group by的區別 4、什麼是事務?及其特性
倍增RMQ演算法淺談
題目: 求某一區間的最大值。 f[a][b]中a代表的是當前的位置,b代表的是以a為起點往後移動的區間長度2^b。 1 void bz(int n) 2 { 3 for(int i=1;i<=n;i++) 4 f[i][0]=a[i];//先定
淺談三種最常規的HTTPS流量解密方法及原理
Web 安全是一項系統工程,任何細微疏忽都可能導致整個安全壁壘土崩瓦解。拿 HTTPS 來說,它的「內容加密、資料完整性、身份認證」三大安全保證,也會受到非法根證書、服務端配置錯誤、SSL 庫漏洞、私鑰被盜等等風險的影響。很多同學認為只要訪問的網站地址前有一把小綠鎖就絕對安全,其實不然。本文通過介紹
Java基礎複習筆記——資料結構和演算法淺談
為什麼要學習資料結構和演算法,這裡我舉個簡單的例子。 程式設計好比是一輛汽車,而資料結構和演算法是汽車內部的變速箱。一個開車的人不懂變速箱的原理也是能開車的,同理一個不懂資料結構和演算法的人也能程式設計。但是如果一個開車的人懂變速箱的原理,比如降低速度來獲得更大
區塊鏈的發展應用最有可能的行業是什麼?
區塊鏈起源於Bitcoin,目前最成功的區塊鏈也是比特幣的區塊鏈,而區塊鏈之所以讓人遐想無限,正是因為它擁有了透明度高,不可更改,無需中間人的這些特性。區塊鏈投資已炙手可熱,統計資料顯示,2017年新成立的46家風險投資機構中有9家投資方向專注於區塊鏈,去年很多區塊鏈專案天使
這樣的單點登入才最有效果,很多大咖牛人都不知道!
導讀:單點登入,是指在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。本文從友戶通單點登入型別、認證安全以及應用整合的角度,聊下解決複雜場景下的單點登入方案。隨著雲端計算的飛速發展,越來越多的雲應用、雲服務充斥在日常的工作當中。人們在享受資訊化帶來的便捷的同時,也遭受著應用系統反覆登入,
這樣的單點登錄才最有效果,很多大咖牛人都不知道!
roc 廣泛 ldap 支持跨域 jsonp 多次 社會化 而且 存在 導讀:單點登錄,是指在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。本文從友戶通單點登錄類型、認證安全以及應用集成的角度,聊下解決復雜場景下的單點登錄方案。隨著雲計算的飛速發展,越
演算法淺談——遞迴演算法與海盜分金問題
本文始發於個人公眾號:TechFlow 最近看到一道很有意思的問題,分享給大家。 還是老規矩,在我們聊演算法問題之前,先來看一個故事。 傳說中,有5個海盜組成了一支無敵的海盜艦隊,他們在最後一次的尋寶當中找尋到了100枚價值連城的金幣。於是,很自然的,這群海盜面臨分贓的問題。為了防止海盜內訌,殘忍的海盜們
演算法淺談——分治演算法與歸併、快速排序(附程式碼和動圖演示)
在之前的文章當中,我們通過海盜分金幣問題詳細講解了遞迴方法。 我們可以認為在遞迴的過程當中,我們通過函式自己呼叫自己,將大問題轉化成了小問題,因此簡化了編碼以及建模。今天這篇文章呢,就正式和大家聊一聊將大問題簡化成小問題的分治演算法的經典使用場景——排序。 排序演算法 排序演算法有很多,很多博文都有總結
演算法淺談——走迷宮問題與廣度優先搜尋
本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 在之前週末LeetCode專欄當中,我們詳細描述了深度優先搜尋和回溯法,所以今天我們繼續這個話題,來和大家聊聊搜尋演算法的另一個分支,廣度優先搜尋。 廣度優先搜尋的英文是Breadth First Search,簡寫為bfs。與它相對的深
淺談最短路之——迪傑斯特拉(Dijkstar)演算法
迪傑斯特拉演算法複雜度為O(n^2),加入堆優化後可以優化到O((m+n)logn)的級別。主要適用於解決不含負邊權的單源最短路。其基本思想是:記S為已找到源點的最短路的點的集合,V為不在集合S中的點的集合,用dis陣列記錄i到源點的最短路徑長度,每次取V中w值最小的
淺談:狄克斯特拉演算法Dijkstra找最小樹問題
•標號過程分為兩步: –1.修改T標號。假定 是新產生的P標號點,考察以 為始點的所有弧段 ,如果 是P標號點,則對該點不再進行標號;如果 是T標號點,則進行如下修改 –2.產生新的P標號點,原則:在現有的所有T標號中將值最小者改為P標號 以上為狄克斯特拉的演算法詳述,為了讓後來者有一個清晰的認識,
阿何談時間管理視頻——最接地氣、最能實用、最有效果的時間管理課程
阿何 時間管理 很可能是你見過最接地氣、最能實用、最有效果的時間管理課程。無需任何接觸,聽完就能懂、學完就能用、用完馬上看到效果。 不需要掌握各種高大上的理論,不需要很強大的意誌力。只要理念上走上正確的軌道,配合一些實用的小方法,就能從容自由地做時間的主人。 下載地址:https://pan.baid
淺談冷庫造價的關聯因素都有哪些方面?
提升 一定的 降溫 規格 放置 自己的 技術 簡單 關聯 冷庫造價其實和多方面的內容都有一定的聯系,比如說冷庫的設計方案,冷庫的安裝實情以及冷庫在安裝過程中所需要的設備,但是大部分的客戶對於這方面的知識都不是很了解,如果你想要了解冷庫造價,那麽就應該關註一家具有實力的廠家,