حساب النتيجة الدقيقة للرمية المعقدة لاثنين من D30

StackOverflow https://stackoverflow.com/questions/302379

سؤال

حسنًا، لقد أزعجني هذا لعدة سنوات حتى الآن.إذا كنت مهووسًا بالإحصاء والرياضيات العالية في المدرسة، فابتعد، الآن.بعد فوات الأوان.

تمام.خذ نفس عميق.هنا القواعد.يأخذ اثنين النرد ذو الثلاثين وجهًا (نعم، إنهم موجودون) ولفها في وقت واحد.

  • أضف الرقمين
  • إذا أظهر كلا النردين <= 5 أو >= 26، قم برمي النرد مرة أخرى و يضيف النتيجة لما لديك
  • إذا كان أحدهما <= 5 والآخر >= 26، فارمي مرة أخرى و طرح او خصم النتيجة مما لديك
  • كرر ذلك حتى يصبح أي منهما > 5 و< 26!

إذا كتبت بعض التعليمات البرمجية (انظر أدناه)، وقمت برمي النرد بضعة ملايين من المرات وقمت بحساب عدد المرات التي تتلقى فيها كل رقم كنتيجة نهائية، فستحصل على منحنى مسطح جدًا على يسار 1، حوالي 45 درجة بين 1 و 60 ومسطحة فوق 60.فرصة التدحرج 30.5 أو أفضل أكبر من 50%، والتدحرج أفضل من 18 هي 80%، والتدحرج أفضل من 0 هي 97%.

والآن السؤال:هل من الممكن كتابة برنامج ل احسب ال بالضبط القيمة f(x)، أياحتمال لفة قيمة معينة؟

خلفية:بالنسبة إلى لعبة تمثيل الأدوار "Jungle of Stars" بحثنا عن طريقة للتحكم في الأحداث العشوائية.تضمن القواعد المذكورة أعلاه نتيجة أكثر استقرارًا لشيء تحاول تجربته :)

بالنسبة للمهوسين، الكود في بايثون:

import random
import sys

def OW60 ():
    """Do an open throw with a "60" sided dice"""
    val = 0
    sign = 1

    while 1:
        r1 = random.randint (1, 30)
        r2 = random.randint (1, 30)

        #print r1,r2
        val = val + sign * (r1 + r2)
        islow = 0
        ishigh = 0
        if r1 <= 5:
            islow += 1
        elif r1 >= 26:
            ishigh += 1
        if r2 <= 5:
            islow += 1
        elif r2 >= 26:
            ishigh += 1

        if islow == 2 or ishigh == 2:
            sign = 1
        elif islow == 1 and ishigh == 1:
            sign = -1
        else:
            break

        #print sign

    #print val
    return val

result = [0] * 2000
N = 100000
for i in range(N):
    r = OW60()
    x = r+1000
    if x < 0:
        print "Too low:",r
    if i % 1000 == 0:
        sys.stderr.write('%d\n' % i)
    result[x] += 1

i = 0
while result[i] == 0:
    i += 1

j = len(result) - 1
while result[j] == 0:
    j -= 1

pSum = 0
# Lower Probability: The probability to throw this or less
# Higher Probability: The probability to throw this or higher
print "Result;Absolut Count;Probability;Lower Probability;Rel. Lower Probability;Higher Probability;Rel. Higher Probability;"
while i <= j:
    pSum += result[i]
    print '%d;%d;%.10f;%d;%.10f;%d;%.10f' % (i-1000, result[i], (float(result[i])/N), pSum, (float(pSum)/N), N-pSum, (float(N-pSum)/N))
    i += 1
هل كانت مفيدة؟

المحلول

اضطررت إلى إعادة كتابة الكود الخاص بك أولاً قبل أن أتمكن من فهمه:

def OW60(sign=1):
    r1 = random.randint (1, 30)
    r2 = random.randint (1, 30)
    val = sign * (r1 + r2)

    islow  = (r1<=5)  + (r2<=5)
    ishigh = (r1>=26) + (r2>=26)

    if islow == 2 or ishigh == 2:
        return val + OW60(1)
    elif islow == 1 and ishigh == 1:
        return val + OW60(-1)
    else:
        return val

ربما تجد هذا أقل قابلية للقراءة؛لا أعرف.(تحقق مما إذا كان معادلاً لما كان يدور في ذهنك.) أيضًا، فيما يتعلق بالطريقة التي تستخدم بها "النتيجة" في التعليمات البرمجية الخاصة بك - هل تعرف لغة Python قاموسس؟

على أي حال، مسائل أسلوب البرمجة جانبا:لنفترض أن F(x) هو سي دي إف من OW60(1)، أي.

F(x) = the probability that OW60(1) returns a value ≤ x.

السماح بالمثل

G(x) = the probability that OW60(-1) returns a value ≤ x.

ثم يمكنك حساب F(x) من التعريف، عن طريق جمع كل القيم المحتملة (30×30) لنتيجة الرمية الأولى.على سبيل المثال، إذا كانت الرمية الأولى هي (2,3) فسوف تقوم بالرمي مرة أخرى، لذلك يساهم هذا الحد (1/30)(1/30)(5+F(x-5)) في التعبير الخاص بـ F( س).لذلك سوف تحصل على بعض التعبيرات الطويلة الفاحشة مثل

F(x) = (1/900)(2+F(x-2) + 3+F(x-3) + ... + 59+F(x-59) + 60+F(x-60))

وهو مجموع أكثر من 900 حد، واحد لكل زوج (أ،ب) في [30]×[30].الأزواج (أ، ب) مع كل من ≥ 5 أو كليهما ≥26 لها مصطلح a+b+F(x-a-b)، والأزواج التي لها واحد ≥5 وواحد ≥26 لها مصطلح a+b+G(x-a-b)، و والباقي له مصطلح مثل (أ+ب)، لأنك لا ترمي مرة أخرى.

وبالمثل لديك

G(x) = (1/900)(-2+F(x-2) + (-3)+F(x-3) + ... + (-59)+F(x-59) + (-60)+F(x-60))

وبطبيعة الحال، يمكنك جمع المعاملات.مصطلحات F الوحيدة التي تحدث هي من F(x-60) إلى F(x-52) ومن F(x-10) إلى F(x-2) (لـ a،b≥26 أو كليهما ≥5)، و حدود G الوحيدة التي تحدث هي من G(x-35) إلى G(x-27) (لأحد a،b≥26 والآخر ≥5)، لذلك هناك مصطلحات أقل من 30 مصطلحًا.على أية حال، تعريف المتجه V(x) كـ

V(x) = [F(x-60) G(x-60) ... F(x-2) G(x-2) F(x-1) G(x-1) F(x) G(x)]

(على سبيل المثال)، لديك (من تلك التعبيرات الخاصة بـ F وG) علاقة بالشكل

V(x) = A*V(x-1) + B

للحصول على مصفوفة مناسبة A ومتجه B مناسب (والتي يمكنك حسابها)، لذا بدءًا من القيم الأولية للنموذج V(x) = [0 0] لـ x صغيرة بما يكفي، يمكنك العثور على F(x) وG(x ) لـ x في النطاق الذي تريد إغلاقه بشكل تعسفي.(و f(x)، احتمال رمي x، هو فقط F(x)-F(x-1)، بحيث يخرج أيضًا.)

قد تكون هناك طريقة أفضل.كل ما قيل وفعل، رغم ذلك، لماذا تفعل هذا؟أيًا كان نوع التوزيع الذي تريده، هناك توزيعات احتمالية لطيفة وبسيطة، مع المعلمات المناسبة، والتي لها خصائص جيدة (على سبيل المثال:تباين صغير، أخطاء من جانب واحد، أيا كان).لا يوجد سبب لاتخاذ إجراء خاص بك لإنشاء أرقام عشوائية.

نصائح أخرى

لقد قمت ببعض الإحصائيات الأساسية على عينة مكونة من 20 مليون رمية.وهنا النتائج:

Median: 17 (+18, -?) # This result is meaningless
Arithmetic Mean: 31.0 (±0.1)
Standard Deviation: 21 (+1, -2)
Root Mean Square: 35.4 (±0.7)
Mode: 36 (seemingly accurate)

تم تحديد الأخطاء تجريبيا.إن المتوسط ​​الحسابي والوضع دقيقان حقًا، ولا يبدو أن تغيير المعلمات حتى بقوة شديدة يؤثر عليهما كثيرًا.أفترض أن سلوك الوسيط قد تم شرحه بالفعل.

ملحوظة:لا تأخذ هذا الرقم للحصول على وصف رياضي مناسب للوظيفة.استخدمها للحصول بسرعة على صورة لما يبدو عليه التوزيع.بالنسبة لأي شيء آخر، فهي ليست دقيقة بما فيه الكفاية (على الرغم من أنها قد تكون دقيقة.

ربما يكون هذا مفيدًا لشخص ما.

تحرير 2:

graph

استنادا إلى قيم 991 فقط.كان بإمكاني حشر المزيد من القيم فيه، لكنهم كانوا سيشوهون النتيجة.تصادف أن هذه العينة نموذجية إلى حد ما.

تحرير 1:

فيما يلي القيم المذكورة أعلاه لنرد واحد فقط ذي ستين وجهًا، للمقارنة:

Median: 30.5
Arithmetic Mean: 30.5
Standard Deviation: 7.68114574787
Root Mean Square: 35.0737318611

لاحظ أن هذه القيم محسوبة وليست تجريبية.

الاحتمال المركب غير المحدود هو ...غير تافهة.كنت سأتعامل مع المشكلة بنفس الطريقة التي تعامل بها جيمس كوران، ولكن بعد ذلك رأيت من كود المصدر الخاص بك أنه قد يكون هناك مجموعة ثالثة من القوائم، ورابعة، وهكذا.المشكلة قابلة للحل، ولكنها تتجاوز بكثير معظم أجهزة محاكاة التدحرج.

هل هناك أي سبب محدد يجعلك بحاجة إلى نطاق عشوائي من -Inf إلى +Inf مع مثل هذا المنحنى المعقد حول 1-60؟لماذا يعتبر منحنى الجرس 2D30 غير مقبول؟إذا قمت بشرح متطلباتك، فمن المحتمل أن يتمكن شخص ما من توفير خوارزمية أبسط وأكثر حدودًا.

حسنا دعنا نري.ال ثانية رمي (الذي سيتم إضافته أو طرحه في بعض الأحيان إلى اللفة الأولى) له منحنى جرس لطيف يمكن التنبؤ به بسهولة حول 31.اللفة الأولى، بطبيعة الحال، هي المشكلة.

بالنسبة لللفة الأولى، لدينا 900 مجموعة محتملة.

  • 50 مجموعة تؤدي إلى إضافة اللفة الثانية.
  • 25 مجموعة تؤدي إلى طرح اللفة الثانية.
  • ترك 825 مجموعة تتوافق مع منحنى الجرس للفة الثانية.

ستشكل مجموعة الطرح (الطرح المسبق) منحنى جرس في النطاق (27..35).سيشكل النصف السفلي من مجموعة الإضافة منحنى جرس في النطاق (2..10)، بينما سيشكل النصف العلوي منحنى جرس في النطاق (52..60)

احتمالي ضعيف بعض الشيء، لذلك لا أستطيع تحديد القيم الدقيقة لك، ولكن يجب أن يكون واضحًا أن هذه تؤدي إلى قيم يمكن التنبؤ بها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top