Моделирование черновой лотереи NBA в Python - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь написать имитирующий симулятор лотереи в качестве упражнения для размышления и для некоторой вводной практики по питону, где каждая команда получит в два раза больше шансов получить первый выбор, чем команда, которая предшествовала им в турнирной таблице. Приведенный ниже код работает (хотя я уверен, что есть более эффективный способ его написания), но теперь я хотел бы найти способ найти шансы каждой отдельной команды на получение определенного места для черновика на основе их шансов. Я считаю, что есть 12! способы задания порядка, так что было бы почти невозможно вычислить вручную. Есть ли способ запустить симуляцию в python (скажем, 10 миллионов раз) и посмотреть, какой процент от тех времен каждая команда попадает в определенное место в перетасованном списке?

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]))

Ответы [ 3 ]

1 голос
/ 20 июня 2019

Вместо того, чтобы делать выборку подобным образом, я бы использовал дискретное распределение для вероятности получения команды i и выборку с использованием random.choices. Мы обновляем дистрибутив после выборки, отбрасывая все заявки от этой команды (поскольку она не может появиться снова).

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



0 голосов
/ 20 июня 2019

Вот способ сделать это (достаточно быстро, чтобы запустить 1M за 15 минут, поэтому для 10 миллионов вам, вероятно, придется подождать несколько часов):

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())))
0 голосов
/ 20 июня 2019

Вот то, что вы хотите, я думаю, но, как сказано в другом комментарии, он работает очень медленно, и я бы не стал пробовать 10 миллионов раз, это достаточно медленно, как есть.

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

print Counter(countList)

добавьте цикл for в конец кода и импортируйте вверху.

...