مولد قيم عشوائية حقيقيّة
لإنشاء قيم عشوائية حقّا (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
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.