একটি সম্পূর্ণ উত্তরের জন্য প্রশ্নটি খুব বিস্তৃত, তবে আমাকে চেরি-বেছে নেওয়া কয়েকটি আকর্ষণীয় পয়েন্ট দিন:
কেন "সমান সম্ভাবনা"
মনে করুন আপনার কাছে একটি সাধারণ এলোমেলো সংখ্যা জেনারেটর রয়েছে যা সমান সম্ভাবনা সহ প্রতিটি 0, 1, ..., 10 নম্বর উত্পন্ন করে (এটিকে ক্লাসিক হিসাবে ভাবেন rand()
)। এখন আপনি 0, 1, 2 সীমাতে একটি সমান সম্ভাবনা সহ একটি এলোমেলো সংখ্যা চান। আপনার হাঁটু ঝাঁকুনির প্রতিক্রিয়া গ্রহণ করা হবে rand() % 3
। তবে অপেক্ষা করুন, অবশিষ্ট 0 এবং 1 বাকী 2 এর চেয়ে বেশি বার ঘটে, তাই এটি সঠিক নয়!
এ কারণেই আমাদের যথাযথ বিতরণগুলি দরকার , যা অভিন্ন র্যান্ডম পূর্ণসংখ্যার উত্স গ্রহণ করে এবং আমাদের পছন্দসই বিতরণে পরিণত করে, Uniform[0,2]
উদাহরণস্বরূপ। এটি একটি ভাল লাইব্রেরিতে ছেড়ে দেওয়া সেরা!
ইঞ্জিন
সুতরাং সমস্ত এলোমেলোতার কেন্দ্রবিন্দুতে একটি ভাল সিউডো-এলোমেলো সংখ্যার জেনারেটর যা একটি নির্দিষ্ট ব্যবধানে অভিন্নভাবে বিতরণ করা সংখ্যার ক্রম তৈরি করে এবং যার আদর্শভাবে খুব দীর্ঘ সময়কাল থাকে। এর স্ট্যান্ডার্ড বাস্তবায়ন rand()
প্রায়শই সেরা হয় না এবং এভাবে পছন্দ করা ভাল। লিনিয়ার-কংগ্রুয়েন্সি এবং মার্সেন টুইস্টার দুটি ভাল পছন্দ (এলজি আসলে প্রায়শই ব্যবহৃত হয় rand()
); আবার, লাইব্রেরিটি এটি পরিচালনা করতে দেওয়া ভাল।
কিভাবে এটা কাজ করে
সহজ: প্রথমে একটি ইঞ্জিন সেট আপ করুন এবং এটি বীজ করুন। বীজটি "এলোমেলো" সংখ্যার পুরো ক্রমটি পুরোপুরি নির্ধারণ করে, তাই ক /dev/urandom
) প্রতিটি সময় আলাদা আলাদা (যেমন থেকে নেওয়া) ব্যবহার করুন এবং খ) আপনি যদি এলোমেলো পছন্দগুলির ক্রম পুনরায় তৈরি করতে চান তবে বীজ সংরক্ষণ করুন।
#include <random>
typedef std::mt19937 MyRNG; // the Mersenne Twister with a popular choice of parameters
uint32_t seed_val; // populate somehow
MyRNG rng; // e.g. keep one global instance (per thread)
void initialize()
{
rng.seed(seed_val);
}
এখন আমরা বিতরণ তৈরি করতে পারি:
std::uniform_int_distribution<uint32_t> uint_dist; // by default range [0, MAX]
std::uniform_int_distribution<uint32_t> uint_dist10(0,10); // range [0,10]
std::normal_distribution<double> normal_dist(mean, stddeviation); // N(mean, stddeviation)
... এবং এলোমেলো সংখ্যা তৈরি করতে ইঞ্জিনটি ব্যবহার করুন!
while (true)
{
std::cout << uint_dist(rng) << " "
<< uint_dist10(rng) << " "
<< normal_dist(rng) << std::endl;
}
concurrency
<random>
গতানুগতিকদের চেয়ে বেশি পছন্দ করার আরও একটি গুরুত্বপূর্ণ কারণ rand()
হ'ল র্যান্ডম সংখ্যার প্রজন্মের থ্রেডসেফ কীভাবে তৈরি করা যায় তা এখন খুব স্পষ্ট এবং স্পষ্ট each ইঞ্জিন বস্তু।
বিবিধ
- টিআর 1 তে একটি আকর্ষণীয় নিবন্ধ কোডগুরুর এলোমেলোভাবে।
- উইকিপিডিয়ায় একটি ভাল সারসংক্ষেপ রয়েছে (ধন্যবাদ, জাস্টিন) in
- নীতিগতভাবে, প্রতিটি ইঞ্জিনের একটি টাইপডেফ করা উচিত
result_type
, যা বীজের জন্য সঠিকভাবে অবিচ্ছেদ্য প্রকার। আমি মনে করি আমি একজন বগী বাস্তবায়ন একবার যা আমাকে বাধ্য জন্য বীজ বলপূর্বক ছিল std::mt19937
থেকে uint32_t
x64 উপর, অবশেষে এই সংশোধন করা উচিত এবং আপনি বলতে পারেন MyRNG::result_type seed_val
এবং এইভাবে ইঞ্জিন খুব সহজেই পরিবর্তনযোগ্য ভুলবেন না।
rand
, কিছু বুনিয়াদি পরিসংখ্যান এবং আরএনজি ধারণাগুলির জন্য আপনার উইকিপিডিয়ায় তাত্ক্ষণিকভাবে নজর রাখা উচিত, অন্যথায় এটির যুক্তি<random>
এবং এর বিভিন্ন টুকরো ব্যবহার সম্পর্কে আপনাকে ব্যাখ্যা করা সত্যিই কঠিন ।