0Pricing
C++ Academy · درس

المولّدات العشوائية

ولّد بتات عشوائية

المولّدات العشوائية درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

لماذا نستخدم <random>؟

إن rand() القديم منخفض الجودة ويصعب التحكم فيه. وتقسم مكتبة <random> العشوائية إلى محركات (مصادر للبتات العشوائية) وتوزيعات (أشكال المخرجات).

#include <iostream>
#include <random>

int main() {
    std::mt19937 engine(42);
    std::cout << "engine produced a value\n";
    unsigned int v = engine();
    std::cout << (v != 0 ? "non-zero" : "zero") << '\n';
    return 0;
}

Mersenne Twister

يُعد std::mt19937 المحرك الأكثر شيوعًا: سريعًا وعالي الجودة وذا دورة طويلة. ويمثل الرقم حجم حالته بالبتات.

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(1);
    unsigned int a = gen();
    unsigned int b = gen();
    std::cout << (a != b ? "two different values" : "same") << '\n';
    return 0;
}

المحركات حتمية

عند إعطائه البذرة نفسها، ينتج المحرك دائمًا التسلسل نفسه. وهذا ما يجعل النتائج قابلة لإعادة الإنتاج.

#include <iostream>
#include <random>

int main() {
    std::mt19937 a(123), b(123);
    std::cout << std::boolalpha << (a() == b()) << '\n';
    std::cout << (a() == b()) << '\n';
    return 0;
}

استدعاء المحرك

المحرك قابل للاستدعاء. ويعيد كل استدعاء لـ engine() العدد الصحيح العشوائي الخام التالي ضمن نطاقه.

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(7);
    for (int i = 0; i < 3; ++i) {
        unsigned int v = gen();
        std::cout << (v % 100) << ' ';
    }
    std::cout << '\n';
    return 0;
}

نطاق المحرك

يعرض min() وmax() نطاق القيم الخام التي يمكن للمحرك إصدارها.

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen;
    std::cout << "min: " << gen.min() << '\n';
    std::cout << "max: " << gen.max() << '\n';
    return 0;
}

محركات أخرى

تقدم المكتبة عدة محركات:

  • minstd_rand: مولّد توافقي خطي صغير.
  • mt19937: المحرك الافتراضي للأغراض العامة.
  • ranlux48: جودة أعلى وسرعة أقل.
#include <iostream>
#include <random>

int main() {
    std::minstd_rand lcg(5);
    std::mt19937 mt(5);
    std::cout << (lcg() % 10) << ' ' << (mt() % 10) << '\n';
    return 0;
}

محرك 64 بت

استخدموا std::mt19937_64 عندما تحتاجون إلى قيم عشوائية بحجم 64 بت، مثل استخدامه في التجزئات الكبيرة أو النطاقات الهائلة.

#include <iostream>
#include <random>

int main() {
    std::mt19937_64 gen(99);
    unsigned long long v = gen();
    std::cout << "got a 64-bit value: " << (v != 0 ? "yes" : "no") << '\n';
    return 0;
}

المحرك مقابل التوزيع

تكون مخرجات المحرك الخام موزعة بالتساوي على نطاق هائل. وللحصول على قيم مفيدة مثل نتيجة رمي النرد، مرّروا المحرك إلى توزيع.

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(2024);
    std::uniform_int_distribution<int> die(1, 6);
    std::cout << "rolled " << die(gen) << '\n';
    return 0;
}

التخلص من القيم

يقدّم discard(n) المحرك بمقدار n من الخطوات دون إنتاج مخرجات، وهو مفيد لتجاوز جزء من التسلسل.

#include <iostream>
#include <random>

int main() {
    std::mt19937 a(10), b(10);
    b.discard(2);
    a(); a();
    std::cout << std::boolalpha << (a() == b()) << '\n';
    return 0;
}

إعادة استخدام محرك واحد

أنشئوا محركًا واحدًا وأعيدوا استخدامه لكل العشوائية في برنامجكم. إذ إن إنشاء محرك جديد في كل مرة يهدر الموارد وقد يقلل الجودة.

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(2026);
    std::uniform_int_distribution<int> d10(1, 10);
    int total = 0;
    for (int i = 0; i < 5; ++i) total += d10(gen);
    std::cout << "sum of 5 rolls: " << total << '\n';
    return 0;
}

مشكلة البذرة الافتراضية

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

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen; // default seed: same every run
    std::cout << "first value mod 1000: " << (gen() % 1000) << '\n';
    return 0;
}

اختبار سريع

اختبروا فهمكم لمحركات العشوائية.

خلاصة

لقد تعلمتم محركات العشوائية:

  • تفصل <random> بين المحركات (البتات) والتوزيعات (الشكل)
  • يُعد std::mt19937 المحرك الأساسي المفضل؛ وهو حتمي عند استخدام بذرة معينة
  • أعيدوا استخدام محرك واحد، وزوّدوه ببذرة مناسبة للحصول على تنوع حقيقي

بعد ذلك، ستشكلون مخرجات المحرك باستخدام التوزيعات.

الأسئلة الشائعة

هل درس «المولّدات العشوائية» مجاني؟

نعم — نص درس «المولّدات العشوائية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «المولّدات العشوائية»؟

ولّد بتات عشوائية تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «المولّدات العشوائية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. المولّدات العشوائية
  2. التوزيعات
  3. التهيئة ببذرة بطريقة صحيحة
  4. أمثلة عملية
← العودة إلى C++ Academy