Неполные проблемы (или нет)
Ваш код выглядит нормально, включая использование np.random.choice
.Возможно, возникла путаница, связанная со значением по умолчанию параметра replace
.replace
по умолчанию True
, поэтому вам не нужно явно передавать replace = True
в choice
в блоке кода (1).
Помимо этой очень незначительной проблемы, нет явных проблем сваш код.Таким образом, проблема может заключаться в математике и вероятности.
Проблемы вероятности
225 - это ожидаемое значение, когда размер ничьи равен 1. В вашем коде (1) размер ничьи увеличиваетсяс каждой итерацией.Подумайте об этом следующим образом: с увеличением размера тиража шансы получить все купоны за один тираж начинают становиться достаточно большими.Я не знаю точного числа ( РЕДАКТИРОВАТЬ: я нашел несколько точных чисел. Теперь они находятся в разделе «Более глубокое расследование» ниже ), но говорят, что вероятность получения всех 50 купонов в одномничья 100 - 0,01.К тому времени, когда вы начнете рисовать 143, кумулятивные шансы получить все купоны хотя бы один раз должны быть не менее 0,4 (и, вероятно, больше).
Более глубокое исследование
СНесколько твиков, ваш код может быть использован для оценки шансов увидеть все 50 купонов в одном розыгрыше размером x:
def collectx(coupon, x, reps):
x = np.asarray(x)
n = coupon.size
counts = np.zeros((x.size, reps), dtype=int)
for i,xsub in enumerate(x):
for j in range(reps):
count = 1
while np.unique(np.random.choice(coupon, size=xsub)).size < n:
count += 1
counts[i, j] = count
return counts
Вероятности для многих различных значений x
можно оценить сразу, передавв последовательности.Теперь, чтобы оценить вероятности для всех размеров рисования 120-143, вы можете выполнить:
n = 50
coupon = np.arange(0, n)
counts = collectx(coupon, np.arange(120,144), 100)
Это дает counts
, который является массивом формы (24, 100)
.Размер чертежа варьируется в зависимости от строк, а идентификатор репликации оценки зависит от столбцов.Вы можете получить вероятности «увидеть каждый купон в одном розыгрыше», взяв среднее по повторным оценкам и разделив результат на 1:
probx = (1/counts.mean(axis=1))
, который выглядит следующим образом:
[0.00418971 0.00563 0.00661288 0.00694493 0.00690799 0.00854774
0.00909339 0.01050531 0.01207875 0.01344086 0.01485222 0.0155642
0.02004008 0.02115059 0.02015723 0.02377556 0.02639916 0.02379819
0.02856327 0.03941663 0.04145937 0.03162555 0.03601008 0.04821601]
При размере ничьей в 120 вероятность все еще ниже 0,005, но она быстро увеличивается, а при размере ничьи 143 вероятность увидеть каждый купон составляет почти 0,05.Поскольку вероятности для размеров розыгрыша ниже 120 малы, суммирование по вероятностям размеров розыгрыша 120-143 дает разумную оценку совокупной вероятности того, что ваш кодовый блок (1) видел все купоны в одном розыгрыше к моменту его завершения сразмер розыгрыша 143:
print('%.3f' % probx.sum())
Вывод:
0.475
Таким образом, ваш кодовый блок (1) с большой вероятностью не видел бы каждый купон при n==143
.Что полностью соответствует результатам, которые вы наблюдали.Так что никаких проблем с Numpy, просто одна вероятность.