Це узагальнення відомої проблеми з днем народження : з урахуванням осіб, які мають випадкові, рівномірно розподілені "дні народження" серед безлічі можливостей, який шанс, що жоден день народження не поділяється більше осіб?d = 6 м = 20n=100d=6m=20
Точний розрахунок дає відповідь (з подвоєною точністю). Я буду замалювати теорію і навести код для загальних Асимптотичний час коду - що робить його придатним для дуже великої кількості днів народження і забезпечує розумну продуктивність, поки стане тисячами. Тоді наближення Пуассона, обговорене під час розширення парадокса дня народження до більш ніж 2 людей, повинно працювати в більшості випадків.п , м , д . O ( n 2 log ( d ) ) d n0.267747907805267n,m,d.O(n2log(d))dn
Пояснення рішення
Функція, що генерує ймовірність (pgf) для результатів незалежних рулонів однобічного штампу, єdnd
d−nfn(x1,x2,…,xd)=d−n(x1+x2+⋯+xd)n.
Коефіцієнт при розширенні цього мультиномії дає кількість способів, за якими обличчя може відображатися саме разів, i e i i = 1 , 2 , … , d .xe11xe22⋯xeddieii=1,2,…,d.
Обмеження нашої зацікавленості не більш ніж появою будь-яким обличчям рівнозначно оцінюванню modulo ідеального породжував Для проведення цієї оцінки використовуйте теорему бінома рекурсивно для отриманняf n I x m + 1 1 , x m + 1 2 , … , x m + 1 d .mfnIxm+11,xm+12,…,xm+1d.
fн( х1, … , Хг)= ( ( х1+ ⋯ + xr) + ( хr + 1+ хr + 2+ ⋯ + x2 р) )н= ∑k = 0н( нк) (х1+ ⋯ + xr)к( хr + 1+ ⋯ + x2 р)n - k= ∑k = 0н( нк) fк( х1, … , Хr) fn - k( хr + 1, … , Х2 р)
коли парне. Записуючи ( терміни), маємоf ( d ) n = f n ( 1 , 1 , … , 1 ) dг= 2 рf( д)н= fн( 1 , 1 , … , 1 )г
f( 2 р )н= ∑k = 0н( нк) f( r )кf( r )n - k.(а)
Коли непарне, використовуйте аналогічне розкладанняг=2r+1
fн( х1, … , Хг)= ( ( х1+ ⋯ + x2 р) + х2 r + 1)н= ∑k = 0н( нк) fк( х1, … , Х2 р) fn - k( х2 r + 1) ,
давання
f( 2 r + 1 )н= ∑k = 0н( нк) f( 2 р )кf( 1 )n - k.(b)
В обох випадках ми можемо також зменшити все модуль , що легко виконується починаючи зЯ
fн( хj) ≅{ хн0n ≤ mn > ммодЯ,
забезпечення вихідних значень для рекурсії,
f( 1 )н= { 10n ≤ mn > м
Це робить це ефективним тим, що розбиваючи змінні на дві однакові за розміром групи змінних і встановлюючи всі значення змінних до нам потрібно лише оцінити все один раз для однієї групи, а потім об'єднати результати. Для цього потрібні обчислення до доданків, кожен з яких потребує обчислення для комбінації. Нам навіть не потрібен 2D-масив для зберігання , тому що при обчисленні потрібні лише і .r 1 , n + 1 O ( n ) f ( r ) n f ( d ) n , f ( r ) n f ( 1 ) nгr1 ,n + 1O ( n )f( r )нf( д)н,f( r )нf( 1 )н
Загальна кількість кроків на одну меншу, ніж кількість цифр у двійковому розширенні (яка рахує розбиття на рівні групи у формулі ) плюс кількість одиниць розширення (що рахує всі рази непарні значення зустрічається, що вимагає застосування формули ). Це все-таки лише кроки .( a ) ( b ) O ( log ( d ) )г( а )( b )O ( журнал( д) )
На R
робочій станції десятиліття робота була виконана за 0,007 секунд. Код вказано в кінці цієї публікації. Він використовує логарифми ймовірностей, а не самі ймовірності, щоб уникнути можливих переливів або накопичення занадто великого переливу. Це дає змогу видалити фактор у рішенні, щоб ми могли обчислити підрахунки, що лежать в основі ймовірностей.г- н
Зауважимо, що ця процедура призводить до обчислення всієї послідовності ймовірностей одразу, що легко дозволяє нам вивчити, як шанси змінюються при . nf0, ф1, … , Фнн
Програми
Розподіл в узагальненій задачі про день народження обчислюється функцією tmultinom.full
. Єдине завдання полягає у пошуку верхньої межі кількості людей, які повинні бути присутніми, перш ніж шанс зіткнення стане надто великим. Наступний код робить це грубою силою, починаючи з малого і подвоюючи його, поки він не буде достатньо великим. Тому весь розрахунок займає час де - рішення. Обчислюється весь розподіл ймовірностей на кількість людей, що перевищують .m + 1нО ( н.)2журнал( n ) журнал( д) )нн
#
# The birthday problem: find the number of people where the chance of
# a collision of `m+1` birthdays first exceeds `alpha`.
#
birthday <- function(m=1, d=365, alpha=0.50) {
n <- 8
while((p <- tmultinom.full(n, m, d))[n] > alpha) n <- n * 2
return(p)
}
Як приклад, мінімальна кількість людей, необхідних у натовпі, щоб зробити більш імовірним, ніж щонайменше вісім з них поділяють день народження, - , як видно з розрахунку . Це займає всього пару секунд. Ось сюжет частини результату:798birthday(7)
Спеціальна версія цієї проблеми розглядається в подовженні парадоксу дня народження більш ніж 2 -х чоловік , який стосується випадку односторонній штампи , який розгортають дуже велика кількість раз.365
Код
# Compute the chance that in `n` independent rolls of a `d`-sided die,
# no side appears more than `m` times.
#
tmultinom <- function(n, m, d, count=FALSE) tmultinom.full(n, m, d, count)[n+1]
#
# Compute the chances that in 0, 1, 2, ..., `n` independent rolls of a
# `d`-sided die, no side appears more than `m` times.
#
tmultinom.full <- function(n, m, d, count=FALSE) {
if (n < 0) return(numeric(0))
one <- rep(1.0, n+1); names(one) <- 0:n
if (d <= 0 || m >= n) return(one)
if(count) log.p <- 0 else log.p <- -log(d)
f <- function(n, m, d) { # The recursive solution
if (d==1) return(one) # Base case
r <- floor(d/2)
x <- double(f(n, m, r), m) # Combine two equal values
if (2*r < d) x <- combine(x, one, m) # Treat odd `d`
return(x)
}
one <- c(log.p*(0:m), rep(-Inf, n-m)) # Reduction modulo x^(m+1)
double <- function(x, m) combine(x, x, m)
combine <- function(x, y, m) { # The Binomial Theorem
z <- sapply(1:length(x), function(n) { # Need all powers 0..n
z <- x[1:n] + lchoose(n-1, 1:n-1) + y[n:1]
z.max <- max(z)
log(sum(exp(z - z.max), na.rm=TRUE)) + z.max
})
return(z)
}
x <- exp(f(n, m, d)); names(x) <- 0:n
return(x)
}
Відповідь отримуємо за допомогою
print(tmultinom(100,20,6), digits=15)
0,267747907805267