我是歌手第4季第一集就出現了倒數1、2名票數相同的情況,使得原本應該淘汰一名選手的賽制無法執行。出現這種概率的情況有多大?下面是粗略模擬計算其概率的python代碼。雖然無法估計每個候選人的權重,但出現倒數1、2名票數相同的情況也有百分之幾,概率不小。
"""本程序測試在投票活動中,出現并列倒數第一的概率是多少"""
import random
def onePoll(candidates):
"""候選人進行一次投票
Parameters
----------
candidates: [Integer]
候選人的權重,權重越大越可能被投票,len(candidates)是候選人數
Returns
-------
choiced: Integer, [0, len(candidates))
被投票候選人的序號
"""
t = sum(candidates)
n = random.randint(0, t-1)
for i in range(len(candidates)):
if (n >= candidates[i]):
n -= candidates[i]
else:
return i
else:
assert False, "不應該進入該分支"
def generatePollResult(voters, candidates):
"""產生投票結果
Parameters
----------
voters: Integer
投票人數
candidates: [Integer]
候選人的權重,權重越大越可能被投票,len(candidates)是候選人數
Returns
-------
result: [Integer]*len(candidates)
每個人所得票數
"""
result = [0]*len(candidates)
for i in range(voters):
result[onePoll(candidates)] += 1
return result
def simulate(count, voters, candidates, judge):
"""模擬投票行為,統計滿足要求的投票結果的概率
Parameters
----------
count: Integer
模擬投票的次數
voters: Integer
投票人數
candidates: [Integer]
候選人的權重,權重越大越可能被投票,len(candidates)是候選人數
judge: bool ([Integer]*len(candidates))
對投票結果是否符合要求的判斷
Results
-------
prop: Float
所求投票結果的概率
"""
satisfied = 0
for i in range(count):
result = generatePollResult(voters, candidates)
if (judge(result)):
satisfied += 1
return float(satisfied) / count
if __name__ == "__main__":
def isLast2Equal(result):
result.sort()
return result[0] == result[1]
print(simulate(1000, 500, [110,120,130,140,150,160,170,180], isLast2Equal))