简体   繁体   English

用python模拟NBA选秀彩票

[英]Simulation of a nba draft lottery in python

I am trying to write a mock lottery simulator as a thought excercize and for some introductory python practice, where each team would have 2x the odds of getting the first pick as the team that preceded them in the standings. 我正在尝试编写一个模拟彩票模拟器,作为一种思想锻炼和一些入门python的实践,其中每支球队在榜单上领先于他们的队伍将获得被选为第一的可能性的2倍。 The code below works (although I am sure there is a more efficient way to write it), but now I would like to figure out a way to find each individual teams odds of getting a certain draft spot based on their odds. 下面的代码有效(尽管我确信有一种更有效的编写方法),但是现在我想找出一种方法来找到每个团队的赔率,根据他们的赔率获得某个选秀位。 I believe there are 12! 相信有十二个! ways for the order to be set, so it would be next to impossible to compute by hand. 设置订单的方式,因此几乎无法手动计算。 Is there a way to run a simulation in python (say 10 million times) and see what percentage of those times each team ends up in a certain spot of the shuffled list? 有没有一种方法可以在python中运行模拟(例如,进行一千万次),并查看每个团队在混排列表中的某个位置所占的百分比是多少?

import random
from time import sleep

first = [1*['team 1']]
second = [2*['team 2']]
third = [4*['team 3']]
fourth = [8*['team 4']]
fifth = [16*['team 5']]
sixth = [32*['team 6']]
seventh = [64*['team 7']]
eighth = [128*['team 8']]
ninth = [256*['team 9']]
tenth = [512*['team 10']]
eleventh = [1024*['team 11']]
twelfth = [2048*['team 12']]

total = []

for i in first:
    for x in i:
        total.append(x)

for i in second:
    for x in i:
        total.append(x)

for i in third:
    for x in i:
        total.append(x)

for i in fourth:
    for x in i:
        total.append(x)

for i in fifth:
    for x in i:
        total.append(x)

for i in sixth:
    for x in i:
        total.append(x)

for i in seventh:
    for x in i:
        total.append(x)

for i in eighth:
    for x in i:
        total.append(x)

for i in ninth:
    for x in i:
        total.append(x)

for i in tenth:
    for x in i:
        total.append(x)

for i in eleventh:
    for x in i:
        total.append(x)

for i in twelfth:
    for x in i:
        total.append(x)

random.shuffle(total)

order = []
for i in total:
    if i not in order:
        order.append(i)

print('the twelfth pick goes to {}'.format(order[11]))
sleep(1)
print('the eleventh pick goes to {}'.format(order[10]))
sleep(1)
print('the tenth pick goes to {}'.format(order[9]))
sleep(1)
print('the ninth pick goes to {}'.format(order[8]))
sleep(1)
print('the eighth pick goes to {}'.format(order[7]))
sleep(1)
print('the seventh pick goes to {}'.format(order[6]))
sleep(2)
print('the sixth pick goes to {}'.format(order[5]))
sleep(2)
print('the fifth pick goes to {}'.format(order[4]))
sleep(2)
print('the fourth pick goes to {}'.format(order[3]))
sleep(3)
print('the third pick goes to {}'.format(order[2]))
sleep(3)
print('the second pick goes to {}'.format(order[1]))
sleep(3)
print('the first pick goes to {}'.format(order[0]))

Instead of doing your sampling like this, I would use a discrete distribution for the probability of getting the team i, and sample using random.choices. 与其像这样进行抽样,不如使用离散分布来获得团队i的概率,并使用random.choices进行抽样。 We update the distribution after the sampling by discarding all the tickets from that team (since it cannot appear again). 我们会在采样后通过删除该团队的所有票证来更新分配(因为它无法再次出现)。

from random import choices
ticket_amounts = [2**i for i in range(12)]
teams = [ i + 1 for i in range(12)]
for i in range(12):
    probabilities = [count/sum(ticket_amounts) for count in ticket_amounts]
    team_picked = choices(teams, probabilities)[0]
    print("team picked is{}".format(team_picked))
    # update probabilities by discarding all the tickets
    # belonging to picked team
    ticket_amounts[team_picked-1] = 0



Here is what you want I think, but as the other comment said it runs very slow and I would not try 10 million times, its slow enough as is. 我想这就是您想要的内容,但是正如其他评论所说的那样,它运行非常缓慢,我不会尝试1000万次,它的运行速度足够快。

from collections import Counter
for i in range(1,10000):
    random.shuffle(total)
    countList.append(total[0])

print Counter(countList)

add the for loop to the end of your code and the import at the top. 将for循环添加到代码的末尾,并在顶部添加导入。

Here is a way to do it (it fast enough to run 1M time in about 15 min, so for 10 millions you would probably need to wait a few hours): 这是一种方法(速度足够快,可以在大约15分钟内运行1M,所以对于1000万,您可能需要等待几个小时):

import numpy as np
from collections import Counter

n_teams = 12
n_trials = int(1e4)

probs = [ 2**i for i in range(0,n_teams) ]
probs = [ prob_i / sum(probs) for prob_i in probs ]

lottery_results = np.zeros([n_trials, n_teams],dtype=np.int8) # to store the positions at each lottery
for i in range(n_trials):
    lottery_results[i,:] = np.random.choice(n_teams, n_teams, replace=False, p=probs)

for i in range(n_teams):
    positions = Counter(lottery_results[:,i])
    print("Team {}".format(i), dict(sorted(positions.items())))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM