確率-どのくらい高くできますか?


10

以前に確率をすばやく正確に計算する方法について質問しました。しかし、明らかに、閉じた形のソリューションが与えられたので、それはあまりにも簡単でした!これはより難しいバージョンです。

このタスクは、確率を正確かつ迅速に計算するコードを記述することです。出力は、最も縮小された形式で分数として記述された正確な確率でなければなりません。つまり、出力んです4/8けど、むしろ1/2

いくつかの正の整数の場合n、1と-1の長さの一様にランダムな文字列を検討し、nそれをAと呼びます。次に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 である長さの2番目のランダムな文字列についても検討し、Bと呼びます。

今の内積考えるBA[1+j,...,n+j]異なるためにj =0,1,2,...

たとえば、を検討してくださいn=3。以下のための可能な値Aとは、B可能性A = [-1,1,1,-1,...]B=[0,1,-1]。この場合、最初の2つの内積は0および2です。

仕事

それぞれについて、jで始まるj=1コードは、すべての最初のj+1内積がすべてゼロになる確率を出力する必要がありますn=j,...,50

MartinBüttnerが作成したテーブルをコピーする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に1分を与えます。前のリンクされた質問の動的プログラミングコードは、これを簡単に実行しj=1ます。

タイ・ブレーカー

2つのエントリが同じjスコアを取得した場合n、私のマシンで1分間で最高のスコアを獲得したエントリが勝者となりますj。2つの最高のエントリがこの基準でも等しい場合、勝者が最初に送信された回答になります。

言語とライブラリ

自由に利用できる言語とライブラリを使用できます。私はあなたのコードを実行できなければならないので、可能であればLinuxでコードを実行/コンパイルする方法の完全な説明を含めてください。

私のマシンタイミングは私のマシンで実行されます。これは、AMD FX-8350 8コアプロセッサへの標準のUbuntuインストールです。これは、コードを実行できる必要があることも意味します。

入賞作品

  • j=2Pythonのミッチ・シュワルツによって。
  • j=2Pythonの feersumによります。現在最速のエントリー。

質問が不明な場合は、すぐに修正できるようにお知らせください。

2
あなたは断然私のお気に入りの質問者です。繰り返しになりますが、私は正確かつ迅速に値を計算することができます。
primo

@primoありがとうございます!これは、RPythonで回答を期待できることを意味しますか?:)

この質問と他の質問の違いを教えていただけませんか?
kirbyfan64sos

@ kirbyfan64sosもう1つは、本質的には `j = 1`についてのみ同じ質問です。

回答:


3

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

eA [i] == A [i + 1]の場合n、またはA [i]!= A [i + 1]の場合、i番目のメンバーが存在するシーケンスを考えます。iプログラムでは、ns の数です。場合iでもあり、シーケンスがで始まり、で終了する必要がありますe。場合はi奇数で、シーケンスが開始して終了する必要がありますn。シーケンスは、連続するesまたはnsの実行回数によってさらに分類されます。j一方とj他方の+ 1 があります。

ランダムウォークのアイデアを3次元に拡張したとき、4つの可能に歩く方向(のそれぞれに1つずつ存在すること残念問題があるeeenne、またはnnそれらは直線的に依存しない手段)。したがって、kインデックスは、方向(1、1、1)のいずれかで行われたステップの数を合計します。次に、それをキャンセルするために他の3つの方向に行わなければならない正確な数のステップがあります。

P(n、p)は、n個のオブジェクトをp個の部分に順序付けしたパーティションの数を示します。W(l、d)は、lステップのランダムウォークが正確にの距離を移動する方法の数を示しますd。前と同じように、左に移動するチャンスは1回、右に移動するチャンスは1回、そのままの状態にとどまるチャンスは2回です。


ありがとうございました!式のイメージは本当に素晴らしいでしょう。

ご説明ありがとうございます。あなたはそれをシンプルに見せます!私はあなたがの解決策を作ることができるというあなたのコメントを見ましたj=3。それは素晴らしいでしょう!

3

Python、j = 2

前の質問に対するj = 1私の回答の動的プログラミングアプローチは、higher 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()

ここでは、の最初の2つの要素の追跡されたA最後の2つの要素B(ここで、b2最後の要素である)、の内積(A[:n], B)(A[1:n], B[:-1])および(A[2:n], B[:-2])


....残り21.20秒でN_MAXに到達
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.