Ймовірності - наскільки високо ви можете піти?


10

Я раніше задав питання, як швидко та точно обчислити ймовірність. Однак, очевидно, це було занадто просто, оскільки було прийнято рішення закритої форми! Ось більш складна версія.

Це завдання полягає в написанні коду для того, щоб точно і швидко обчислити ймовірність . Вихід повинен бути точною ймовірністю, записаною у вигляді дробу в найбільш скороченому вигляді. Тобто вона ніколи не повинна виводити, 4/8а навпаки 1/2.

Для деякого додатного цілого числа nрозглянемо рівномірно випадковий рядок довжиною 1s та -1s nі назвемо його А. Тепер приєднайтесь до Aкопії себе. Тобто, A[1] = A[n+1]якщо індексація від 1 A[2] = A[n+2]тощо. Aтепер має довжину 2n. Тепер також розглянемо другий випадковий рядок довжини n, перші nзначення якого становлять -1, 0 або 1 з вірогідністю 1/4,1 / 2, 1/4 кожне і назвемо його B.

Тепер розглянемо внутрішній продукт Bз A[1+j,...,n+j]для різних j =0,1,2,....

Наприклад, розглянемо n=3. Можливі значення для Aі Bможуть бути A = [-1,1,1,-1,...]і B=[0,1,-1]. У цьому випадку перші два внутрішніх вироби є 0і 2.

Завдання

Для кожного j, починаючи з j=1, ваш код повинен виводити ймовірність того, що всі перші j+1внутрішні продукти дорівнюють нулю для кожного n=j,...,50.

Копіюючи таблицю, виготовлену Мартином Бюттнером, j=1ми маємо такі результати вибірки.

n   P(n)
1   1/2
2   3/8
3   7/32
4   89/512
5   269/2048
6   903/8192
7   3035/32768
8   169801/2097152

Оцінка

Ваш бал - найбільший, який jваш код заповнюється за 1 хвилину на моєму комп’ютері. Щоб трохи уточнити, кожен jотримує одну хвилину. Зауважте, що код динамічного програмування в попередньому пов'язаному питанні зробить це легко j=1.

Автоматичний вимикач

Якщо дві записи отримають однаковий jбал, тоді виграшним буде той, який за nодну хвилину на моїй машині потрапить до найвищого j. Якщо два найкращі результати за цим критерієм рівні, то переможцем буде відповідь, подана першим.

Мови та бібліотеки

Ви можете використовувати будь-яку вільно доступну мову та бібліотеки, які вам подобаються. Я повинен бути в змозі запустити ваш код, тому, будь-ласка, включіть повне пояснення, як запустити / скомпілювати ваш код у Linux.

My Machine Часи синхронізуються на моїй машині. Це стандартна установка ubuntu на восьмиядерний процесор AMD FX-8350. Це також означає, що мені потрібно мати можливість запускати ваш код.

Виграшні записи

  • j=2у Python Мітчем Шварцом.
  • j=2в Python від feersum. Наразі найшвидший запис.

Якщо питання якимось незрозумілим, будь ласка, повідомте мене, щоб я міг швидко його вирішити.

2
Ви, безумовно, мій улюблений запитувач. Потім, у мене є річ, щоб точно і швидко обчислити значення .
примо

@primo Дякую! Чи означає це, що ми можемо очікувати відповіді в RPython? :)

Чи можете ви поставити різницю між цим питанням та іншим?
kirbyfan64sos

@ kirbyfan64sos Інший - це по суті те саме питання для `j = 1 '.

Відповіді:


3

Пітон 2, j = 2

Я намагався знайти своєрідну «закриту форму» для j = 2. Можливо, я міг би зробити його MathJax-образ, хоча це було б по-справжньому некрасиво з усіма індексами. Я написав цей неоптимізований код лише для тестування формули. На це потрібно близько 1 секунди. Результати збігаються з кодом Мітча Шварца.

ch = lambda n, k: n>=k>=0 and fac[n]/fac[k]/fac[n-k]
W = lambda l, d: ch(2*l, l+d)
P = lambda n, p: n==0 or ch(n-1, p-1)
ir = lambda a,b: xrange(a,b+1)

N = 50
fac = [1]
for i in ir(1,4*N): fac += [i * fac[-1]]

for n in ir(2, N):
    s = 0
    for i in ir(0,n+1):
     for j in ir(0,min(i,n+1-i)):
      for k in ir(0,n+i%2-i-j):
       t=(2-(k==0))*W(n+i%2-i-j,k)*W(i-(j+i%2),k)*W(j,k)**2*P(i,j+i%2)*P(n+1-i,j+1-i%2)
       s+=t
    denp = 3 * n - 1
    while denp and not s&1: denp -= 1; s>>=1
    print n, '%d/%d'%(s,1<<denp)

Розглянемо послідовність, де i-член, eякщо A [i] == A [i + 1] або nякщо A [i]! = A [i + 1]. iу програмі - кількість ns. Якщо iпарне, послідовність повинна починатися і закінчуватися e. Якщо iце непарно, послідовність повинна починатися і закінчуватися n. Послідовності додатково класифікуються за кількістю циклів послідовних es або ns. Є j+ 1 одного, а jіншого.

Коли ідея випадкової ходьби збільшуються до 3 -х вимірах, є невдала проблема , що існує 4 можливих напрямки , щоб йти в ( по одному для кожного з ee, en, ne, або nn) означає , що вони не є лінійно залежними. Так kіндекс підсумовує кількість кроків, зроблених в одному з напрямків (1, 1, 1). Тоді буде точна кількість кроків, які необхідно зробити в інших трьох напрямках, щоб скасувати її.

P (n, p) дає кількість упорядкованих розділів n об’єктів на p частини. W (l, d) дає кількість способів для випадкового проходження lкроків, щоб пройти відстань рівно d. Як і раніше, є 1 шанс рухатися ліворуч, 1 шанс рухатись праворуч і 2 залишатися поставленим.


Дякую! Образ формули був би справді чудовим.

Дякую за пояснення. Ви робите це просто! Я щойно побачив ваш коментар, що ви можете прийняти рішення j=3. Це було б дивовижно!

3

Пітон, j = 2

Підхід до динамічного програмування, що відповідаєj = 1 моїй відповіді на попереднє запитання, не потребує багатьох модифікацій для роботи на вищих j, але швидко стає повільним. Довідкова таблиця:

n   p(n)

2   3/8
3   11/64
4   71/512
5   323/4096
6   501/8192
7   2927/65536
8   76519/2097152
9   490655/16777216
10  207313/8388608

І код:

from time import*
from fractions import*
from collections import*

def main():
    N_MAX=50

    T=time()

    n=2
    Y=defaultdict(lambda:0)
    numer=0

    for a1 in [1]:
        for b1 in (1,0):
            for a2 in (1,-1):
                for b2 in (1,0,0,-1):
                    if not a1*b1+a2*b2 and not a2*b1+a1*b2:
                        numer+=1
                    Y[(a1,a2,b1,b2,a1*b1+a2*b2,a2*b1,0)]+=1

    thresh=N_MAX-1

    while time() <= T+60:
        print('%d %s'%(n,Fraction(numer,8**n/4)))

        if thresh<2:
            print('reached N_MAX with %.2f seconds remaining'%(T+60-time()))
            return

        n+=1
        X=Y
        Y=defaultdict(lambda:0)
        numer=0

        for a1,a2,b1,b2,s,t,u in X:
            if not ( abs(s)<thresh and abs(t)<thresh+1 and abs(u)<thresh+2 ):
                continue

            c=X[(a1,a2,b1,b2,s,t,u)]

            # 1,1

            if not s+1 and not t+b2+a1 and not u+b1+a1*b2+a2: numer+=c
            Y[(a1,a2,b2,1,s+1,t+b2,u+b1)]+=c

            # -1,1

            if not s-1 and not t-b2+a1 and not u-b1+a1*b2+a2: numer+=c
            Y[(a1,a2,b2,1,s-1,t-b2,u-b1)]+=c

            # 1,-1

            if not s-1 and not t+b2-a1 and not u+b1+a1*b2-a2: numer+=c
            Y[(a1,a2,b2,-1,s-1,t+b2,u+b1)]+=c

            # -1,-1

            if not s+1 and not t-b2-a1 and not u-b1+a1*b2-a2: numer+=c
            Y[(a1,a2,b2,-1,s+1,t-b2,u-b1)]+=c

            # 1,0

            c+=c

            if not s and not t+b2 and not u+b1+a1*b2: numer+=c
            Y[(a1,a2,b2,0,s,t+b2,u+b1)]+=c

            # -1,0

            if not s and not t-b2 and not u-b1+a1*b2: numer+=c
            Y[(a1,a2,b2,0,s,t-b2,u-b1)]+=c

        thresh-=1

main()

Тут ми відслідковуємо перші два елементи A, останні два елементиB (де b2це останній елемент), і внутрішні продукти (A[:n], B), (A[1:n], B[:-1])і (A[2:n], B[:-2]).


.... досяг N_MAX, залишившись
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.