(廢文) 從一張無聊的MEME看Simulation的強大之處
不知為何最近我的社交群組都在流傳一個堪稱”一分鐘淘汱掉100人”的面試題:
筆者驟眼看了一眼題目,便笑而不語,這豈不是普通的機率問題,可是當我開始思考了10秒後,我不禁後悔了,這根本沒有想像中簡單!還好,老子還有一部強大的電腦幫我做運算開掛,不然我一分鐘我自己也算不出來。
於是,我利用一分鐘的時間用Python寫幾行簡短的程式碼做Simulation,等待數秒,結果就出來了,就是10個人。整個過程根本無需人腦的運算,只需要把問題設計好給電腦作運算就好了。
方法大概就是制作N個平行空間,為什麼是N?那是因為這個數量是我們自己控制的,然後,要在這N個平行空間,從中找出我們想要知道的答案,這就是Simulation的威力!
每個平行空間都是隨機地安排,然後從這N個平行空間找到我們想要知道的答案。到底要怎樣才可以用神的視覺來作隨機的安排,首先,只考慮一個平行空間,會有30個學生,每位學生也有3組的語文,英文和數學的成績,那麼我就把他們的成績放在三組Array上,你可能會問:裡面應該裝些什麼呢?為方便計算,我會把滿分的成績用1來表示,0為沒有拿到滿分。然後,我們先專注語文的Array,首先,語文科滿分的只有20人,因此,在整條Array中1的數量應只有20,而0則有10。以下就是一條任意排列:
可是要如何在程式中實現這種隨機的排列呢?其實很簡單,就是先建造一組連續數的陣列,而排列均是隨機的。在Python的世界,我會用numpy中的random模組去實現:
然後都把小於19的數學都換成1,其餘都是0,那就可以確保陣列裡有20個滿分的人。如此類推,數學和英文的Array也是用這個方法去作隨機的排列。好了,最後就是記錄每個平行空間有多少人能夠拿到三科滿分,也就是在三個Array中在同一個位置都出現三個1。終於回歸到面試問題的本身:至少有多少學霸拿到連中三元?筆者選擇用了100個平行空間,以下就是在每個平行世界的學霸數量:
如果我們把這個面試題換成:最多有多少人能拿三科全滿分?那麼我們在一千結果找最大的值就可以了,也就是20人。
現在各位應該可以看到Simulation的威力,無需進行機率和複雜方程式的計算,只要懂得制作出不同形式的平行世界就可以了。尤其是做過Bayesian Data Analysis的朋友們,一定知道要用數學算式Derive出那些複雜的事後機率分怖(Posterior Probability Distribution)是多麼的玩命,相反,只要跑MCMC Simulation的程序便很快完事了。
P. S. 筆者把Code都放在我的Github裡,有興趣的朋友可以參考一下。
來到這裡,可能你們還會有疑問,要多少的平行空間結果才可以,愈多的會愈準確嗎?對的,如果筆者只用10個的平行世界,把程式中的N改成10,電腦就會算到12人。既然平行空間愈多愈好,為何不早設定一萬個或者是更多的來解決問題?那是因為愈多的平行世界意味著愈多的嘗試,會令電腦更多時間去運算,如果寫出來的算法Algorithm,computational complexity是O(N2)或者是更多,那麼這會是個災難,簡單來說就是用平常更多的時間去計算。所以找到平衡點是非常重要,這也印證我一位出色的舊上司說的:在Trading的世界中做Simulation,準確度固然重要,可是時間的掌握才是重點;時間太短的Simulation會令結果失去準確性,時間太多則會耽誤決策時機,這也是Simulation的藝術。
哈哈,沒想到以前學的東西竟然也能應用在這種地方上,雖然如此,這亦令筆者感思到,可能因為工作的關係,自己也未免太過於依賴電腦幫助運算,所以我也要思考一下,如果沒有計算機的幫助要如何解決這種難題。
經過冷靜的思索一番,其實也不是這麼困難,只要把滿分的人排成以下這個樣子,很明顯的這是最極端的例子,一共有20的學霸。
換上另一種排列方式,把0都分散開去不要有重疊,便是另一外個極端,只有10個學生能拿到全滿分。Problem resolved~!
所以結論就是筆者不要殺雞用牛刀了,完~
Comments
Post a Comment