سؤال

لدي الكود التالي في PHP والذي يعمل بشكل جيد (يُرجع أكثر أو أقل من 10 نتائج في كل مرة يتم تشغيله):

function GetAboutTenRandomNumbers()
{
    $result = array();

    for ($i = 0; $i < 240; $i++)
    {
        if (Chance(10, 240) === true)
        {
            $result[] = $i;
        }
    }

    echo '<pre>';
    print_r($result);
    echo '</pre>';

    return $result;
}

وتكون وظيفة Chance() كما يلي:

function Chance($chance, $universe = 100)
{
    $chance = abs(intval($chance));
    $universe = abs(intval($universe));

    if (mt_rand(1, $universe) <= $chance)
    {
        return true;
    }

    return false;
}

الآن، أريد تقسيم هذه النتائج العشرة (في المتوسط) عشوائيًا إلى الأقسام الأربعة التالية:

  1. الأول له احتمال 10% * 10 = 1
  2. والثاني احتماله 20% * 10 = 2
  3. والثالث احتماله 30% * 10 = 3
  4. الرابع احتماله 40% * 10 = 4

كما ترون مجموع كل الأجزاء (1 + 2 + 3 + 4) يساوي 10، لذلك قمت بترميز الوظيفة التالية للقيام بذلك.

function GetAboutTenWeightedRandomNumbers()
{
    $result = array();

    // Chance * 10%
    for ($i = 0; $i < 60; $i++)
    {
        if (Chance(10 * 0.1, 240) === true)
        {
            $result[] = $i;
        }
    }

    // Chance * 20%
    for ($i = 60; $i < 120; $i++)
    {
        if (Chance(10 * 0.2, 240) === true)
        {
            $result[] = $i;
        }
    }

    // Chance * 30%
    for ($i = 120; $i < 180; $i++)
    {
        if (Chance(10 * 0.3, 240) === true)
        {
            $result[] = $i;
        }
    }

    // Chance * 40%
    for ($i = 180; $i < 240; $i++)
    {
        if (Chance(10 * 0.4, 240) === true)
        {
            $result[] = $i;
        }
    }

    echo '<pre>';
    print_r($result);
    echo '</pre>';

    return $result;
}

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

هل كانت مفيدة؟

المحلول

فى الحقيقة انت!

في التمريرة الثانية، ستعطيها 60 قيمة لكل تمريرة، بدلاً من 240، لذا ستحصل على حوالي ربع القيم المتوقعة في تلك التمريرة.قم بتشغيل كل منها إلى 240 واستخدم modulo 60 للحصول على نطاق القيم الذي تبحث عنه في كل حلقة.

نصائح أخرى

إذا كنت تتوقع DoIt_02() لإرجاع نفس عدد النتائج تقريبًا DoIt_01(), ، إذن نعم، أنت ترتكب خطأً رياضيًا أساسيًا.مجموع الأوزان الاحتمالية لأقسامك إلى 10 لا يعني شيئًا لأن الفرص المرجحة لا يتم تطبيقها على مجموعة 0..240 بأكملها.سيُرجع نتائج مماثلة إذا قمت بتشغيل كل احتمال مقيد على 0..240 بدلاً من 0..59، 60..119، وما إلى ذلك.

بالمناسبة، الخاص بك Chance() الدالة متوقفة قليلاً، للحصول على الاحتمالات التي يبدو أنك تحاول تحقيقها، يجب أن تكون كذلك mt_rand(1, $universe) <= $chance أو mt_rand(0, $universe - 1) < $chance.

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