اذهب إلى المحتوى

توليد الأعداد العشوائية في Cpp


محمد بغات

مولد قيم عشوائية حقيقيّة

لإنشاء قيم عشوائية حقّا (generate true random) يمكن استخدامها في التشفير، يجب استخدام ‎std::random_device‎ كمُولِّد.

#include <iostream>
#include <random>

int main() {
    std::random_device crypto_random_generator;
    std::uniform_int_distribution < int > int_distribution(0, 9);

 int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0}; 

    for (int i = 0; i < 10000; i++) {
        int result = int_distribution(crypto_random_generator);
        actual_distribution[result]++;
    }
    for (int i = 0; i < 10; i++) {
        std::cout << actual_distribution[i] << " ";
    }

    return 0;
}

تُستخدم std::random_device بنفس طريقة استخدام مولّد القيم العشوائية الزائفة (pseudo random value).

ورغم ذلك فيمكن تنفيذ ‎std::random_device‎ انطلاقًا من محرّك أعداد عشوائية زائفة تُحدد وفق التنفيذ في حال لم يتوفّر مصدر غير حتمي (non-deterministic) مثل جهاز خاص بتوليد القيم العشوائية لاستخدامه في التنفيذ.

يمكن الكشف عن مثل هذه التنفيذات من خلال الدالة التابعة ‎entropy‎ (التي تعيد 0 في حال كان المولد حتميًّا تمامًا)، لكنّ العديد من المكتبات الشائعة (مثل libstdc++‎ و LLVM's libc++‎) تعيد دائمًا القيمة 0، حتى عند استخدام مولّدات عشوائية خارجية عالية الجودة .

توليد عدد عشوائي زائف

تنشئ مولّدات الأعداد شبه العشوائية قيمًا يمكن تخمينها استنادًا إلى القيم التي تم توليدها سابقًا، هذا يعني أنها حتمية. ولا تستخدم مولّدات الأعداد شبه العشوائية في الحالات التي تستلزم أعدادًا عشوائية حقًّا.

#include <iostream>
#include <random>

int main() {
    std::default_random_engine pseudo_random_generator;
    std::uniform_int_distribution < int > int_distribution(0, 9);

    int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0}; 

    for (int i = 0; i < 10000; i++) {
        int result = int_distribution(pseudo_random_generator);
        actual_distribution[result]++;
    }
    for (int i = 0; i <= 9; i++) {
        std::cout << actual_distribution[i] << " ";
    }

    return 0;
}

تنشئ هذه الشيفرة مولّدَ أعدادٍ عشوائية زائفة، وتوزيعًا يولّد أعدادًا صحيحة في نطاق [0،9] باحتمال متساوي، ويحسب المولّد بعد ذلك عدد مرّات إنشاء كل نتيجة.

يحدّد معامل القالب std::uniform_int_distribution<T>‎ نوع العدد الصحيح الذي يجب إنشاؤه. استخدم ‎std::uniform_real_distribution<T>‎ لتوليد الأعداد العشرية (floats) والأعداد العشرية المزدوجة (doubles).

استخدام المولد مع عدة توزيعات

من الممكن استخدام مولّد الأعداد العشوائية مع عدة توزيعات، ويجب ذلك حقيقة.

#include <iostream>
#include <random>

int main() {
    std::default_random_engine pseudo_random_generator;
    std::uniform_int_distribution < int > int_distribution(0, 9);
    std::uniform_real_distribution < float > float_distribution(0.0, 1.0);
    std::discrete_distribution rigged_dice({1,1,1,1,1,100}); 

    std::cout << int_distribution(pseudo_random_generator) << std::endl;
    std::cout << float_distribution(pseudo_random_generator) << std::endl;
    std::cout << (rigged_dice(pseudo_random_generator) + 1) << std::endl;

    return 0;
}

عرّفنا في هذا المثال مولِّدًا واحدًا فقط، ثمّ استخدمناه لإنشاء أعداد عشوائية في ثلاثة توزيعات مختلفة، وسيولّد التوزيع ‎rigged_dice‎ قيمة بين 0 و 5، لكن سيولّد في الأغلبية الساحقة من الحالات ‎5‎، لأنّ احتمال إنشاء ‎5‎ يساوي ‎100 / 105‎.

هذا الدرس جزء من سلسلة دروس عن C++‎.

ترجمة -بتصرّف- للفصل Chapter 65: Random number generation من كتاب C++ Notes for Professionals


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...