囚徒問題(100 prisoners problem)的python驗證


  密碼學課上老師介紹了這樣一個問題,囚徒問題(100 prisoners problem):一百個囚徒被關在牢房里,典獄長給他們最后一次機會,100人依次進入一個有100個抽屜的牢房,每個抽屜置亂放入1~100的號碼,每個人依次打開50個抽屜,如果每個人都能找到自己的號碼(0~100),則所有人被釋放,反之所有人都會被殺死。

  典型的算法給出的被釋放概率幾乎為零,但是有這樣一種方法:第i號囚徒打開第i號抽屜,如果這個抽屜放的是自己的號碼牌,ok pass,如果不是,則打開該抽屜中號碼牌對應的抽屜,依次進行,直到找到自己的號碼牌或者失敗。

  那么,這個方法的成功率有多少呢。使用python模擬的代碼如下:

import random

flag = 0    # 單次實驗是否成功flag
counter = 0     # 實驗成功次數counter
fcounter = 0    # 單個囚徒打開抽屜次數fcounter
N = 10000   # 設置試驗次數
A = list(range(100))
random.shuffle(A)   # 抽屜置亂
for i in range(N):
    flag = 1
    # experiment begins
    for j in range(100):
        k = j
        while(A[k] != j and fcounter < 50):
            k = A[k]
            fcounter += 1
        if(fcounter >= 50):
            flag = 0
            fcounter = 0
            break
        fcounter = 0

    if(flag == 1):
        counter += 1
    flag = 0
    random.shuffle(A)
print('Success Rate: ' + str(counter/N))

  最終的成功率是驚人的

Success Rate: 0.3117

  這種方法的原理是什么呢,用置換的方法看,一次1~100置亂可以分解為若干個不相交的小循環。若所有小循環的階都小於50,則囚犯都可以找到自己的號牌。

  [公式] 囚徒遇到大於五十階循環的概率如左所示,則囚徒們成功的概率達到了驚人的0.3118


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM