एक संभावना की गणना बिल्कुल और जल्दी से


10

[यह सम्भावना है कि वास्तव में एक संभावना की गणना करने के लिए एक साथी प्रश्न है ]

यह कार्य वास्तव में एक संभावना की गणना करने के कोड लिखने के बारे में है और जल्दी से । आउटपुट एक सटीक संभाव्यता होना चाहिए जो कि इसके सबसे कम रूप में एक अंश के रूप में लिखा गया हो। वह यह है कि उत्पादन कभी नहीं 4/8बल्कि होना चाहिए 1/2

कुछ सकारात्मक पूर्णांक के लिए n, लंबाई के 1s और -1 के समान रूप से यादृच्छिक स्ट्रिंग पर विचार nकरें और इसे कॉल करें। ए। अब Aअपने पहले मूल्य के लिए संक्षिप्त करें । A[1] = A[n+1]यदि 1. से अनुक्रमण किया जाता है, तो Aअब लंबाई है n+1। अब लंबाई के दूसरे यादृच्छिक स्ट्रिंग पर भी विचार करें nजिनके पहले nमान -1, 0 या 1 हैं, प्रायिकता के साथ 1 / 4,1 / 2, 1/4 प्रत्येक और इसे बी कहते हैं।

अब की आंतरिक उत्पाद पर विचार A[1,...,n]और Bऔर की आंतरिक उत्पाद A[2,...,n+1]और B

उदाहरण के लिए, विचार करें n=3। संभावित मान हैं Aऔर Bहो सकता है A = [-1,1,1,-1]और B=[0,1,-1]। इस मामले में दो आंतरिक उत्पाद हैं 0और 2

आपके कोड को इस संभावना को आउटपुट करना होगा कि दोनों आंतरिक उत्पाद शून्य हैं।

मार्टिन ब्यूटनर द्वारा निर्मित तालिका की नकल करना हमारे पास निम्नलिखित नमूना परिणाम हैं।

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

भाषा और पुस्तकालय

आप किसी भी स्वतंत्र रूप से उपलब्ध भाषा और अपनी पसंद की लाइब्रेरी का उपयोग कर सकते हैं। मुझे आपका कोड चलाने में सक्षम होना चाहिए ताकि कृपया अपने कोड को लिनक्स में चलाने / संकलित करने के लिए एक पूर्ण विवरण शामिल करें यदि संभव हो तो।

काम

आपका कोड n=1एक अलग लाइन पर प्रत्येक बढ़ते n के लिए सही आउटपुट के साथ शुरू होना चाहिए । इसे 10 सेकंड के बाद रोकना चाहिए।

स्कोर

nआपके कंप्यूटर पर चलने पर 10 सेकंड के बाद आपका कोड रुकने से पहले स्कोर बस उच्चतम तक पहुंच जाता है। यदि कोई टाई है, तो विजेता सबसे अधिक स्कोर प्राप्त करने वाला व्यक्ति होगा।

प्रविष्टियों की तालिका

  • n = 64में अजगर । मिच श्वार्ट्ज द्वारा संस्करण 1
  • n = 106में अजगर । संस्करण 11 जून 2015 मिच श्वार्ट्ज द्वारा
  • n = 151में सी ++ । पोर्ट ऑफ मिच श्वार्ट्ज के उत्तर kirbyfan64sos द्वारा
  • n = 165में अजगर । संस्करण 11 जून 2015 के साथ मिच श्वार्ट्ज द्वारा "प्रूनिंग" संस्करण N_MAX = 165
  • n = 945एक सटीक सूत्र का उपयोग करके Min_25 द्वारा पायथन में । गजब का!
  • n = 1228एक और सटीक सूत्र (Min_25 के पिछले उत्तर के आधार पर) का उपयोग करके मिच श्वार्ट्ज द्वारा पायथन में ।
  • n = 2761एक ही सटीक सूत्र के तेजी से कार्यान्वयन का उपयोग करके मिच श्वार्ट्ज द्वारा पायथन में ।
  • n = 3250उसी कार्यान्वयन का उपयोग करके मिच श्वार्ट्ज द्वारा पाइपी का उपयोग करते हुए पायथन में । इस स्कोर को ओवरहेड स्क्रॉलिंग कंसोल से बचने की आवश्यकता है।pypy MitchSchwartz-faster.py |tail

मुझे आश्चर्य है कि अगर बूस्ट सी + + से एक खस्ता समाधान तेजी से चलेगा?
qwr

@qwr मुझे लगता है कि सुन्न, सुब्बा और साइथन सभी दिलचस्प होंगे क्योंकि वे पायथन परिवार के भीतर रहते हैं।

2
मैं इन सबसे तेज़-कोड समस्याओं को देखना पसंद
करूंगा

@qwr यह मेरा पसंदीदा प्रश्न है ... धन्यवाद! चुनौती यह है कि जिस कोड को आप सबसे कम स्तर की भाषा में पा सकते हैं, ठीक उसी तरह के एल्गोरिथ्म को शामिल न करें।

क्या आप कंसोल या किसी फ़ाइल पर परिणाम लिख रहे हैं? एक फ़ाइल के लिए pypy और लेखन का उपयोग करना मेरे लिए सबसे तेज़ लगता है। कंसोल प्रक्रिया को काफी धीमा कर देता है।
जिब्बलर

जवाबों:


24

अजगर

का एक क्लोज्ड फॉर्मूला p(n)है

यहाँ छवि विवरण दर्ज करें

का एक घातीय उत्पादक कार्य p(n)है

यहाँ छवि विवरण दर्ज करें

I_0(x)पहली तरह का संशोधित बेसेल फ़ंक्शन कहां है।

2015-06-11 पर संपादित करें:
- पायथन कोड अपडेट किया गया।

2015-06-13 पर संपादित करें:
- उपरोक्त सूत्र का एक प्रमाण जोड़ा गया।
- तय किया time_limit
- एक PARI / GP कोड जोड़ा गया।

अजगर

def solve():
  # straightforward implementation

  from time import time
  from itertools import count

  def binom(n, r):
    return facts[n] // (facts[r] * facts[n - r])

  def p(N):
    ans = 0
    for i in range(1 + N // 2):
      t = binom(2 * (N - 2 * i), N - 2 * i)
      t *= binom(N, 2 * i)
      t *= binom(4 * i, 2 * i)
      ans += t
    e = (ans & -ans).bit_length() - 1
    numer = ans >> e
    denom = 1 << (3 * N - 1 - e)
    return numer, denom

  facts = [1]
  time_limit = 10.0 + time()

  for i in count(1):
    facts.append(facts[-1] * (2 * i - 1))
    facts.append(facts[-1] * (2 * i))

    n, d = p(i)

    if time() > time_limit:
      break

    print("%d %d/%d" % (i, n, d))

solve()

PARI / जीपी

p(n) = polcoeff( (exp(x/2) + 1) * besseli(0, x/4) ^ 2, n) * n!;

प्रमाण:
यह समस्या 2-आयामी (प्रतिबंधित) यादृच्छिक चलने की समस्या के समान है।

तो A[i] = A[i+1], हम से ले जा सकते हैं (x, y)करने के लिए (x+1, y+1)[1 जिस तरह से], (x, y)[2 तरीके] या (x-1, y-1)[1 जिस तरह से]।

तो A[i] != A[i+1], हम से ले जा सकते हैं (x, y)करने के लिए (x-1, y+1)[1 जिस तरह से], (x, y)[2 तरीके] या (x+1, y-1)[1 जिस तरह से]।

चलो a(n, m) = [x^m]((x+1)^n + (x-1)^n), b(n) = [x^n](1+x)^{2n}और c(n)तरीके से स्थानांतरित करने की संख्या हो (0, 0)करने (0, 0)के साथ nकदम दूर है।

फिर, c(n) = \sum_{i=0}^n a(n, i) * b(i) * b(n-i).

चूंकि p(n) = c(n) / 8^n, हम उपरोक्त बंद-फॉर्मूला प्राप्त कर सकते हैं।


1
यह .. अच्छा .. अद्भुत है! पृथ्वी पर आपने सटीक सूत्र की गणना कैसे की?

1
वाह! बंद रूप हमेशा साफ है!
qwr

1
@ लेम्बिक: मैंने एक (मोटा) प्रमाण जोड़ा।
मिन_२५

1
@ लेखक: धन्यवाद। मै भी यही सोचता हूँ !
मिनट_25

1
@ mbomb007: हाँ। लेकिन, यह एक कंप्यूटिंग कार्य के बजाय एक कार्यान्वयन कार्य है। इसलिए, मैं इसे C ++ में कोड नहीं करूंगा।
Min_25

9

अजगर

नोट: बंद-फ़ॉर्म समाधान खोजने के लिए Min_25 को बधाई!

दिलचस्प समस्या के लिए धन्यवाद! यह डीपी का उपयोग करके हल किया जा सकता है, हालांकि मैं वर्तमान में उच्च स्कोर प्राप्त करने के लिए गति के अनुकूलन के लिए बहुत प्रेरित महसूस नहीं कर रहा हूं। यह गोल्फ के लिए अच्छा हो सकता है।

N=39पायथन 2.7.5 पर चलने वाले इस पुराने लैपटॉप पर 10 सेकंड के भीतर कोड पहुंच गया ।

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

X={(1,0,0,0):1,(-1,0,0,0):1}

T=time()
N=0

while 1:
    Y=defaultdict(lambda:0)
    n=d=0
    for a,b,s,t in X:
        c=X[(a,b,s,t)]
        for A in ( (1,-1) if N else [a] ):
            for B in 1,0,0,-1:
                n+=c*(s+A*B==0==t+A*b+a*B)
                d+=c
                Y[(a,B,s+A*B,t+A*b)]+=c
    if time()>T+10: break
    N+=1
    print N,Fraction(n,d)
    X=Y

टपल के लिए (a,b,s,t): aके पहले तत्व है A, bके अंतिम तत्व है B, sके भीतर उत्पाद है A[:-1]और B, और tके भीतर उत्पाद है A[1:-1]और B[:-1], अजगर टुकड़ा अंकन का उपयोग। मेरा कोड सरणियों को Aया Bकहीं भी संग्रहीत नहीं करता है , इसलिए मैं उन पत्रों का उपयोग करता हूं ताकि अगले तत्वों को क्रमशः Aऔर B, में जोड़ा जा सके । यह चर नामकरण विकल्प स्पष्टीकरण को थोड़ा अजीब बनाता है, लेकिन A*b+a*Bकोड में ही एक अच्छा दिखने की अनुमति देता है। ध्यान दें कि जो तत्व जोड़ा जा रहा Aहै, वह प्रथागत है, क्योंकि अंतिम तत्व हमेशा पहले जैसा ही होता है। मैंने मार्टिन बर्टनर की चाल का उपयोग 0दो बार में किया हैBउम्मीदवारों को उचित संभावना वितरण प्राप्त करने के लिए। शब्दकोश X(जो नाम दिया गया है Yके लिए N+1) टपल के मूल्य के अनुसार हर संभव सरणियों की गिनती का ट्रैक रखता है। चर nऔर dअंश और भाजक के लिए खड़े होते हैं, यही वजह है कि मैंने nसमस्या कथन का नाम बदल दिया N

तर्क का मुख्य हिस्सा यह है कि आप टपल में केवल मूल्यों का उपयोग Nकरने से अपडेट कर सकते हैं N+1। प्रश्न में निर्दिष्ट दो आंतरिक उत्पादों द्वारा दिए गए हैं s+A*Bऔर t+A*b+a*B। यह स्पष्ट है यदि आप परिभाषाओं की थोड़ी जांच करते हैं; ध्यान दें कि [A,a]और [b,B]सरणियों के अंतिम दो तत्व हैं Aऔर Bक्रमशः।

ध्यान दें कि sऔर tछोटे और के अनुसार घिरा रहे हैं N, और एक तेजी से भाषा में एक तेजी से लागू करने के लिए हम सरणियों के पक्ष में शब्दकोशों से बच सकते हैं।

केवल संकेत में भिन्न मूल्यों पर विचार करके समरूपता का लाभ उठाना संभव हो सकता है; मैंने उस पर गौर नहीं किया है।

टिप्पणी 1 : शब्दकोश का आकार चतुर्भुज रूप से बढ़ता है N, जहां आकार का अर्थ कुंजी-मूल्य वाले जोड़े की संख्या है।

टिप्पणी 2 : यदि हम एक ऊपरी बाउंड सेट करते हैं N, तो हम ट्यूपल्स को उसके लिए N_MAX - N <= |s|और इसी तरह से ट्यून कर सकते हैं t। यह एक अवशोषित राज्य को निर्दिष्ट करके, या छंटनी की स्थिति को गिनने के लिए एक चर के साथ निहित किया जा सकता है (जिसे प्रत्येक पुनरावृत्ति में 8 से गुणा करने की आवश्यकता होगी)।

अद्यतन : यह संस्करण तेज है:

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

N_MAX=115

def main():
    T=time()

    N=1
    Y={(1,0,0,0):1,(1,1,1,0):1}
    n=1
    thresh=N_MAX

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

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

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

        for a,b,s,t in X:
            if not abs(s)<thresh>=abs(t):
                continue

            c=X[(a,b,s,t)]

            # 1,1

            if not s+1 and not t+b+a: n+=c
            Y[(a,1,s+1,t+b)]+=c

            # -1,1

            if not s-1 and not t-b+a: n+=c
            Y[(a,1,s-1,t-b)]+=c

            # 1,-1

            if not s-1 and not t+b-a: n+=c
            Y[(a,-1,s-1,t+b)]+=c

            # -1,-1

            if not s+1 and not t-b-a: n+=c
            Y[(a,-1,s+1,t-b)]+=c

            # 1,0

            c+=c

            if not s and not t+b: n+=c
            Y[(a,0,s,t+b)]+=c

            # -1,0

            if not s and not t-b: n+=c
            Y[(a,0,s,t-b)]+=c

        thresh-=1

main()

ऑप्टिमाइज़ेशन लागू:

  • सब कुछ डाल main()- स्थानीय चर वैश्विक की तुलना में तेजी से होता है
  • N=1चेक से बचने के लिए स्पष्ट रूप से संभाल लें (1,-1) if N else [a](जो यह बताता है कि टपल में पहला तत्व सुसंगत है, जब Aखाली सूची से शुरू करने के लिए तत्वों को जोड़ना )
  • आंतरिक छोरों को नियंत्रित करें, जो गुणा को भी समाप्त करता है
  • उन ऑपरेशनों को दो बार करने के बजाय cए जोड़ने के लिए गिनती दोगुनी करें0B
  • भाजक हमेशा होता है 8^Nइसलिए हमें इसका ट्रैक रखने की आवश्यकता नहीं है
  • अब समरूपता को ध्यान में रखते हुए: हम के Aरूप में पहले तत्व को ठीक कर सकते हैं 1और भाजक को विभाजित कर सकते हैं 2, क्योंकि वैध जोड़े के (A,B)साथ A[1]=1और उन लोगों को A[1]=-1नकारात्मक रूप से एक-से-एक पत्राचार में रखा जा सकता है A। इसी तरह, हम Bगैर-नकारात्मक के पहले तत्व को ठीक कर सकते हैं ।
  • अब छंटाई के साथ। आपको यह देखने की ज़रूरत होगी N_MAXकि आपकी मशीन पर क्या स्कोर हो सकता है। यह N_MAXद्विआधारी खोज के द्वारा स्वचालित रूप से एक उपयुक्त खोजने के लिए फिर से लिखा जा सकता है , लेकिन अनावश्यक लगता है? नोट: हमें आसपास तक पहुंचने तक छंटाई की स्थिति की जांच करने की आवश्यकता नहीं है N_MAX / 2, इसलिए हम दो चरणों में पुनरावृत्ति करके थोड़ा गति प्राप्त कर सकते हैं, लेकिन मैंने सादगी और कोड स्वच्छता के लिए निर्णय लिया।

1
यह एक बहुत अच्छा जवाब है! क्या आप बता सकते हैं कि आपने अपनी गति में क्या किया है?

@Lembik धन्यवाद :) ने एक स्पष्टीकरण जोड़ा, एक और छोटा अनुकूलन, और इसे पायथन 3 अनुरूप बनाया।
मिच श्वार्ट्ज

अपने कंप्यूटर पर, मुझे N=57पहले संस्करण के N=75लिए और दूसरे के लिए मिला ।
kirbyfan64sos

आपके जवाब कमाल के रहे हैं। यह सिर्फ इतना है कि Min_25 का जवाब और भी अधिक था :)

5

अजगर

रैंडम वॉक के Min_25 के विचार का उपयोग करते हुए, मैं एक अलग सूत्र में आने में सक्षम था:

p (n) = \ _ {शुरू} केसेस} \ frac {\ _ _ _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} / 2i} 4 ^ {n-2i}} {8 ^ n} & n \ text {विषम} \ \ frac {\ binom {n} {n / 2} ^ 2 + \ sum _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} {2i} 4 ^ {n-2i}} {8 ^ n} & n \ n पाठ {सम} {\ _ {मामलों}

यहाँ Min_25 के आधार पर पायथन कार्यान्वयन है:

from time import*
from itertools import*

def main():
    def binom(n, k):
        return facts[n]/(facts[k]*facts[n-k])

    def p(n):
        numer=0
        for i in range(n/2+1):
            t=binom(2*i,i)
            t*=t
            t*=binom(n,2*i)
            t<<=2*(n-2*i)
            numer+=t
        if not n&1:
            numer+=t
        e=(numer&-numer).bit_length()-1
        numer>>=e
        denom=1<<(3*n-e)
        return numer, denom

    facts=[1]
    time_limit=time()+10

    for i in count(1):
        facts.append(facts[-1]*i)

        n,d=p(i)

        if time()>time_limit:
            break

        print("%d %d/%d"%(i,n,d))

main()

स्पष्टीकरण / प्रमाण:

पहले हम संबंधित गिनती की समस्या को हल करते हैं, जहां हम अनुमति देते हैं A[n+1] = -A[1]; अर्थात् , पहले तत्व की परवाह किए बिना या उसके लिए अतिरिक्त तत्व Aहो सकता है । इसलिए हमें इस बात का ध्यान रखने की आवश्यकता नहीं है कि कितनी बार होता है। हम निम्नलिखित यादृच्छिक चलना है:1-1A[i] = A[i+1]

से (x,y)हम करने के लिए स्थानांतरित कर सकते हैं (x+1,y+1)[1 जिस तरह से], (x+1,y-1)[1 जिस तरह से], (x-1,y+1)[1 जिस तरह से], (x-1,y-1)[1 जिस तरह से], (x,y)[4 तरीके]

जहां xऔर yदो डॉट उत्पादों के लिए खड़े हो जाओ, और हम तरीके की संख्या से स्थानांतरित करने के लिए गिनती कर रहे हैं (0,0)करने के लिए (0,0)में nकदम दूर है। उस गणना को 2इस तथ्य से गुणा किया जाएगा कि इस तथ्य की Aशुरुआत किससे हो सकती है1 या इसके सकता है -1

हम शून्य चाल के(x,y) रूप में रहने का उल्लेख करते हैं

हम गैर-शून्य चालों की संख्या पर पुनरावृत्ति करते हैं i, जिसे वापस पाने के लिए भी होना चाहिए (0,0)। क्षैतिज और ऊर्ध्वाधर आंदोलनों दो स्वतंत्र एक आयामी यादृच्छिक चलता है, जिसके द्वारा गिना जा सकता है बनाते हैं C(i,i/2)^2, जहां C(n,k)द्विपद गुणांक है। ( kबाएं कदम और kदाएं कदमों के साथ टहलने के लिए, चरणों C(2k,k)के क्रम को चुनने के तरीके हैं ।) इसके अलावा C(n,i)चालों को रखने के 4^(n-i)तरीके और शून्य चालों को चुनने के तरीके भी हैं। तो हमें मिलता है:

a(n) = 2 * sum_{i in (0,2,4,...,n)} C(i/2,i)^2 * C(n,i) * 4^(n-i)

अब, हमें मूल समस्या पर वापस जाने की आवश्यकता है। यदि शून्य (A,B)हो तो परिवर्तनीय जोड़ी को परिभाषित करने योग्य बनाएं B। एक जोड़ी (A,B)को परिभाषित करें कि लगभग स्वीकार्य हो अगर A[n+1] = -A[1]और दो डॉट उत्पाद दोनों शून्य हैं।

लेम्मा: किसी दिए गए के लिए n, लगभग स्वीकार्य जोड़े परिवर्तनीय जोड़े के साथ एक-से-एक पत्राचार में हैं।

हम (प्रतिवर्ती रूप से) एक परिवर्तनीय जोड़ी (A,B)को (A',B')नकारात्मक रूप से लगभग स्वीकार्य जोड़ी में बदल सकते हैं A[m+1:]और B[m+1:], जहां mअंतिम शून्य का सूचकांक है B। इसके लिए जाँच सीधी है: यदि अंतिम तत्व Bशून्य है, तो हमें कुछ भी करने की आवश्यकता नहीं है। अन्यथा, जब हम अंतिम तत्व की उपेक्षा करते हैं, तो हम शिफ्ट डॉट उत्पाद के अंतिम शब्द को संरक्षित करने के लिए Aअंतिम तत्व को नकार सकते हैं B। लेकिन यह गैर-स्थानांतरित डॉट उत्पाद के अंतिम मूल्य को नकारता है, इसलिए हम इसे दूसरे-से-अंतिम तत्व की उपेक्षा करके ठीक करते हैं A। लेकिन फिर यह स्थानांतरित उत्पाद के दूसरे-से-अंतिम मूल्य को फेंक देता है, इसलिए हम दूसरे-से-अंतिम तत्व की उपेक्षा करते हैं B। और इसी तरह, जब तक एक शून्य तत्व अंदर नहीं पहुंच जाता B

अब, हमें केवल यह दिखाने की आवश्यकता है कि लगभग कोई स्वीकार्य जोड़ी Bनहीं है जिसके लिए शून्य नहीं है। डॉट उत्पाद के बराबर शून्य के लिए, हमारे पास रद्द करने के लिए समान संख्या 1और -1शब्द होने चाहिए। प्रत्येक -1शब्द (1,-1)या से बना है (-1,1)। तो -1उस होने वाली संख्या की समता तय होती है n। यदि पहले और अंतिम तत्वों में Aअलग-अलग लक्षण हैं, तो हम समानता को बदलते हैं, इसलिए यह असंभव है।

तो हम प्राप्त करते हैं

c(n) = a(n)/2 if n is odd, else a(n)/2 + C(n,n/2)^2

p(n) = c(n) / 8^n

जो उपरोक्त सूत्र देता है (के साथ पुन: अनुक्रमण करता है i' = i/2)।

अद्यतन: यहां एक ही सूत्र का उपयोग करके एक तेज़ संस्करण है:

from time import*
from itertools import*

def main():
    time_limit=time()+10

    binoms=[1]
    cb2s=[1]
    cb=1

    for n in count(1):
        if n&1:
            binoms=[a+b for a,b in zip([0]+binoms,binoms)]
        else:
            binoms=[a+b for a,b in zip([0]+binoms,binoms+[binoms[-1]])]
            cb=(cb<<2)-(cb+cb)/(n/2)
            cb2s.append(cb*cb)

        numer=0
        for i in xrange(n/2+1):
            t=cb2s[i]*binoms[min(2*i,n-2*i)]
            t<<=2*(n-2*i)
            numer+=t
        if not n&1:
            numer+=t
        e=(numer&-numer).bit_length()-1
        numer>>=e
        denom=1<<(3*n-e)

        if time()>time_limit:
            break

        print("%d %d/%d"%(n,numer,denom))

main()

ऑप्टिमाइज़ेशन लागू:

  • इनलाइन समारोह p(n)
  • के C(n,k)साथ द्विपद गुणांक के लिए पुनरावृत्ति का उपयोग करेंk <= n/2
  • केंद्रीय द्विपद गुणांक के लिए पुनरावृत्ति का उपयोग करें

बस आप जानते हैं, p(n)एक टुकड़ा करने की क्रिया होने की जरूरत नहीं है। सामान्य तौर पर, यदि f(n) == {g(n) : n is odd; h(n) : n is even}आप इसके बजाय लिख f(n) == (n-2*floor(n/2))*g(n) + ((n+1)-2*(floor((n+1)/2)))*h(n)या उपयोग कर सकते n mod 2हैं (n-2*floor(n/2))यहां
mbomb007

1
@ mbomb007 यह स्पष्ट और निर्बाध है।
मिच श्वार्ट्ज

3

Min_25 के सूत्र का स्पष्टीकरण

Min_25 ने एक महान प्रमाण पोस्ट किया लेकिन इसका पालन करने में थोड़ा समय लगा। यह लाइनों के बीच में भरने के लिए थोड़ा सा स्पष्टीकरण है।

a (n, m) A को चुनने के तरीकों की संख्या को दर्शाता है जैसे A [i] = A [i + 1] m बार। A (n, m) के लिए सूत्र n (n, m) = {2 * (n choose m) के लिए nm के समतुल्य है; 0 एनएम विषम के लिए।} केवल एक समता की अनुमति है क्योंकि A [i]! = A [i + 1] को सम संख्या में होना चाहिए ताकि A [0] = A [n]। 2 का कारक प्रारंभिक पसंद A [0] = 1 या A [0] = -1 है।

एक बार जब (A [i]! = A [i + 1]) की संख्या q तय हो जाती है (i को c (n) फॉर्मूला में नाम दिया जाता है), तो यह दो 1D यादृच्छिक चाल लंबाई q और nq में अलग हो जाती है। बी (एम) एम चरणों के एक-आयामी रैंडम वॉक लेने के तरीकों की संख्या है जो उसी स्थान पर समाप्त होती है, जहां से यह शुरू हुआ था, और बाईं ओर बढ़ने का 25% मौका है, 50% अभी भी रहने की संभावना है, और 25% की संभावना है सही चल रहा है। जनरेटिंग फंक्शन को बताने का एक और स्पष्ट तरीका है [x ^ m] (1 + 2x + x ^ 2) ^ n, जहाँ 1, 2x और x ^ 2 क्रमशः बायें, कोई चाल नहीं, और दायें दर्शाते हैं। लेकिन फिर 1 + 2x + x ^ 2 = (x + 1) ^ 2।


पीपीसीजी को प्यार करने का एक और कारण! धन्यवाद।

2

सी ++

मिच श्वार्ट्ज द्वारा (उत्कृष्ट) पायथन जवाब का सिर्फ एक बंदरगाह। प्राथमिक अंतर यह है कि मैं प्रयोग किया जाता है 2का प्रतिनिधित्व करने -1के लिए aचर और के लिए कुछ इसी तरह किया था b, जो मुझे एक सरणी का उपयोग करने की अनुमति दी। के साथ Intel C ++ का उपयोग करते हुए -O3, मुझे मिल गया N=141! मेरा पहला संस्करण मिला N=140

यह बूस्ट का उपयोग करता है। मैंने एक समानांतर संस्करण की कोशिश की, लेकिन कुछ परेशानी में भाग गया।

#include <boost/multiprecision/gmp.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/rational.hpp>
#include <boost/chrono.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <utility>
#include <map>

typedef boost::multiprecision::mpz_int integer;
typedef boost::array<boost::array<std::map<int, std::map<int, integer> >, 3>, 2> array;
typedef boost::rational<integer> rational;

int main() {
    BOOST_AUTO(T, boost::chrono::high_resolution_clock::now());

    int N = 1;
    integer n = 1;
    array* Y = new array, *X = NULL;
    (*Y)[1][0][0][0] = 1;
    (*Y)[1][1][1][0] = 1;

    while (boost::chrono::high_resolution_clock::now() < T+boost::chrono::seconds(10)) {
        std::cout << N << " " << rational(n, boost::multiprecision::pow(integer(8), N)/4) << std::endl;
        ++N;
        delete X;
        X = Y;
        Y = new array;
        n = 0;

        for (int a=0; a<2; ++a)
            for (int b=0; b<3; ++b)
                for (BOOST_AUTO(s, (*X)[a][b].begin()); s != (*X)[a][b].end(); ++s)
                    for (BOOST_AUTO(t, s->second.begin()); t != s->second.end(); ++t) {
                        integer c = t->second;
                        int d = b&2 ? -1 : b, e = a == 0 ? -1 : a;

                        if (s->first == -1 && t->first+d+e == 0) n += c;
                        (*Y)[a][1][s->first+1][t->first+d] += c;

                        if (s->first == 1 && t->first-d+e == 0) n += c;
                        (*Y)[a][1][s->first-1][t->first-d] += c;

                        if (s->first == 1 && t->first+d-e == 0) n += c;
                        (*Y)[a][2][s->first-1][t->first+d] += c;

                        if (s->first == -1 && t->first-d-e == 0) n += c;
                        (*Y)[a][2][s->first+1][t->first-d] += c;

                        c *= 2;

                        if (s->first == 0 && t->first+d == 0) n += c;
                        (*Y)[a][0][s->first][t->first+d] += c;

                        if (s->first == 0 && t->first-d == 0) n += c;
                        (*Y)[a][0][s->first][t->first-d] += c;
                    }
    }

    delete X;
    delete Y;
}

इसे g++ -O3 kirbyfan64sos.cpp -o kirbyfan64sos -lboost_system -lboost_timer -lboost_chrono -lrt -lgmpसंकलित करने की आवश्यकता है। (Aditsu का धन्यवाद।)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.