看板 C_and_CPP 關於我們 聯絡資訊
前陣子在python版看到有人討論到這個當年煞到我的遊戲, 一下子熱血舊夢又被重燃... 我還算有能力把我手上的想法用C弄出來, 幾個程式設計相關的板這裡也算是人氣較旺, 來這裡搞搞看有沒有人願意一起來玩玩瘋瘋 ------------------以上前情提要,只是說明這絕對不是作業文----------------- 幾A幾B猜數字遊戲,略述如下: 兩個人玩,一方出數字,一方猜。出數字的人要先想好一個沒有重複數字的4位數,不能 讓猜的人知道。猜的人就可以開始猜。每猜一個數,出數者就要根據這個數字給出幾A幾 B,其中A前面的數字表示位置正確的數的個數,而B前的數字表示數字正確而位置不對的 數的個數。 如正確答案為5234,而猜的人猜5346,則是1A2B,其中有一個5的位置對了,記為1A,而 3和4這兩個數字對了,而位置沒對,因此記為2B,合起來就是1A2B。 如果不清楚規則的可以看wiki: http://goo.gl/FvfLq,或者google 這個遊戲在網路上找到已經有人對其解法的幾個最佳化方向做過研究,一些事實: 1. worst case能保證幾次內猜到: 已證明為7次 (不可能6次) 2. 在所有合法的5040種可能性中worst case出現次數最少: <=50次 (疑似open) 3. 最短能保證平均幾次猜到: 已證明為約5.2131次 4. 尚未有人用暴力窮舉的方式跑完所有可能性過 (至少我沒查到) 5. 上述1、3有至少三種不同(非對稱等價)的演算法能同時達到 6. "刪除不可能,從剩餘中隨機猜"這個算法平均約5.47次,worst case很可能是10 那麼,我還想從這個被研究爛了的問題中搞什麼? 當然是個很直覺、很該問,而又沒有在所有被找到的研究中看到過的問題 首先我們來觀察上面第五點提到的這三種演算法 (詳見 http://goo.gl/rbXc4 第15頁) Strategy Name 1 2 3 4 5 6 7 8 Total ------------------------------------------------------------------------ Fast Strategy 1 7 62 718 2403 1757 92 26274 Slow Strategy 1 7 61 692 2445 1755 79 26274 Tanaka‘s Result 1 7 63 697 2424 1774 74 26274 ----------------------------------------------------------------------- 如上表,對於合法的5040種答案,第一種演算法能把其中718種在第四次猜出來 而這三種演算法都能拿到平均26274 / 5040 = 5.2131的平均次數 而且從次數分配表可以看出他們是明顯是不同的,不具有對稱等價關係 他們三者之間有什麼重要的不同嗎? 有!!! 三個人拿著這三種"最佳化"演算法相互對戰,誰會占優? 推廣出去一概而論的話,這個問題夠直覺、夠該問吧 以下解釋如何比較兩種演算法對戰的優劣關係 (以下假設演算法非隨機) 假設一個演算法能保證N次內猜出,且剛好在第k次猜中的機率為f(k), (則: sum = 0.0; for (i=1;i<=N;i++) sum += f(i); 顯然有sum == 100%的關係) 對於兩種演算法各自的分配f1, f2而言,在面對面的對戰中, 第一種演算法勝出的機率是下面算出的sum sum = 0.0; for (i=1;i<=N1;i++) for (j=i+1;j<=N2;j++) sum += f1(i) * f2(j) 而兩種演算法平手的機率是 sum = 0.0; for (i=1;i<=min(N1, N2);i++) sum += f1(i) * f2(i) 由這樣的分析,套入這三種演算法的次數分配表可知第二種是最相互對戰勝率最高的 (如果我現在腦袋中對之前的計算結果印象正確的話) 由此可知,同樣worst case步數、甚至同時有一樣的平均步數的兩個演算法 相互對戰仍有高下,就更不要說平均步數不同的演算法之間了。 甚至我還可以舉出一個假想中的極端例子, 平均步數較差的演算法可能在對戰勝率上贏過勝過平均較好的 假想演算法: 有一種worst case需要999999999999999步才算出來,其他都一步秒殺 這個精神就是"贏一步是贏一把,輸一百步也是輸一把" 所以一下子很(ㄗˋ)顯(ㄧˇ)然(ㄨㄟˊ)前面提到的直覺又重要的問題 "什麼演算法實戰勝率最高?" 好像變得有玩弄的空間了不是嗎? -------------------------以上是動機、背景說明-------------------------------- 所以我想幹嘛? 我想在這裡糾大家有閒的時候來實做自己的玩法 看看誰能提出實戰勝率比較厲害的算法來 實際比較由於有上面所述的評斷方法,所以不需要把大家的code放在同個平台上跑 只要各自提出自己算法的次數分配表(很可能是7個數字而已) 並附上演算法說明或程式碼給其他有興趣的人檢驗不是豪笅就可以了 考慮到上面提到的分析方法實務上只適用於"有確定流程"的演算法間的比較 對於具有隨機性的算法可能會很難測出真實的機率分配表 我建議大家盡可能的設計有確定流程的算法以便交流, 如果真的非隨機不可,建議附上至少跑1000圈(每圈5040種各一次)的累計次數分配結果 為了拋磚引玉, (我這兩天會弄出至少一個C code放在這個版以符合版旨,但新手需要點時間...) 以後有空的時候會陸續更新更好的算法 目前手上有三個用python實作的簡單隨機算法 平均是5.36~5.48次,其中最好的那個有worst case很可能是7次, 他的10圈成績是6, 15, 433, 4909, 22617, 20591, 1829 最爛的那個是天真的"每次從剩下可能中隨機選", 100圈成績是94, 1301, 10871, 61687, 177337, 185799, 61590, 5253, 67, 1 視大家對搞這個活動反應如何啦, 如果反應熱烈的話我願意提供p幣(等下看我有多少XD)給最優者 總之鼓勵大家一起來動腦PK殺時間,陪我瘋一瘋 再附上一個不錯的參考資料: http://bulls-cows.sourceforge.net/index.html -- 我不是學生,不是要交作業弄報告,也不是老師或帶人做科展 我甚至不是資訊科學相關本科系出身,只是對數學、益智遊戲有點興趣 而且有點基礎的寫程式能力,所以自己玩玩 想要調查我動機的不用太麻煩,台北附近可以約出來打棒球順便聊聊 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.169.168.123 更新: 最後一個正在跑的算法剛跑完100圈(目前最佳) 平均5.32,分配是: 99, 1353, 11057, 62986, 206472, 192151, 29683, 199 睡覺去... ※ 編輯: SocketAM2 來自: 118.169.168.123 (09/22 01:46)
EdisonX:Knuth 最愛的遊戲之一... 09/22 03:25
yoco315:Mastermind 超難的 XD 09/22 10:21
SocketAM2:來查查那是什麼... 09/22 10:26
changyuheng:外部測試機:https://gist.github.com/3766117 09/22 21:47
WJAider:要舉辦 pk 賽了嗎? 09/23 16:25