সি ++ 11 এ র্যান্ডম নম্বর জেনারেশন: কীভাবে উত্পন্ন করা যায়, এটি কীভাবে কাজ করে? [বন্ধ]


102

আমি সম্প্রতি সি ++ 11 এ এলোমেলো সংখ্যা উত্পন্ন করার জন্য নতুন উপায়ে এসে পৌঁছেছি, তবে আমি যে কাগজপত্রগুলি সম্পর্কে এটি পড়েছি তা হজম করতে পারিনি (এটি কী ইঞ্জিন , বিতরণের মতো গণিতের শব্দ , "যেখানে উত্পাদিত সমস্ত পূর্ণসংখ্যার সমান সম্ভাবনা রয়েছে ")।

সুতরাং যে কেউ দয়া করে ব্যাখ্যা করতে পারেন

  • তারা কি?
  • তারা কি মানে?
  • কিভাবে উত্পন্ন?
  • তারা কিভাবে কাজ করে?
  • ইত্যাদি

এলোমেলো সংখ্যা জেনারেশন সম্পর্কে আপনি এগুলি সমস্ত এফএকিউতে কল করতে পারেন।


6
ডিস্ট্রিবিউশন কী তা না জেনে আরএনজি সম্পর্কে জিজ্ঞাসা করা এক্সপ্রেশন কী তা না জেনে এক্সপ্রেশন পার্সারদের সম্পর্কে জিজ্ঞাসা করার মতো ... সি ++ 11 এ আরএনজি লাইব্রেরি এমন লোকদের লক্ষ্য যা কিছু পরিসংখ্যান জানে এবং তাদের দ্বারা উত্পন্ন ফ্ল্যাট বিতরণের চেয়ে বেশি প্রয়োজন rand, কিছু বুনিয়াদি পরিসংখ্যান এবং আরএনজি ধারণাগুলির জন্য আপনার উইকিপিডিয়ায় তাত্ক্ষণিকভাবে নজর রাখা উচিত, অন্যথায় এটির যুক্তি <random>এবং এর বিভিন্ন টুকরো ব্যবহার সম্পর্কে আপনাকে ব্যাখ্যা করা সত্যিই কঠিন ।
মাত্তেও ইটালিয়া

26
@ মাত্তিও: খুব কমই। একটি শিশু একটি ধারণাটি উপলব্ধি করতে পারে যে একটি ডাই একটি এলোমেলো সংখ্যার উত্পাদন করে, বন্টন কী তা বুঝতে না পেরে।
বেনজমিন লিন্ডলি

3
@ বেঞ্জামিন: এবং সেখানেই তার বোঝাপড়া থেমে গেছে যা কেবল প্রথম পদক্ষেপ (ইঞ্জিন), এমনকি কেন এটি গুরুত্বপূর্ণ যে তারা একটি সমতল বিতরণ উত্সাহ দেয় তাও বুঝতে না পেরে। অন্যান্য সমস্ত লাইব্রেরি বিতরণ এবং অন্যান্য পরিসংখ্যান ধারণাগুলি না বুঝে রহস্য হিসাবে রয়ে গেছে remains
মাত্তেও ইটালিয়া

উত্তর:


142

একটি সম্পূর্ণ উত্তরের জন্য প্রশ্নটি খুব বিস্তৃত, তবে আমাকে চেরি-বেছে নেওয়া কয়েকটি আকর্ষণীয় পয়েন্ট দিন:

কেন "সমান সম্ভাবনা"

মনে করুন আপনার কাছে একটি সাধারণ এলোমেলো সংখ্যা জেনারেটর রয়েছে যা সমান সম্ভাবনা সহ প্রতিটি 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_tx64 উপর, অবশেষে এই সংশোধন করা উচিত এবং আপনি বলতে পারেন MyRNG::result_type seed_valএবং এইভাবে ইঞ্জিন খুব সহজেই পরিবর্তনযোগ্য ভুলবেন না।

আবারও, কেরেক আমাকে যার সাথে কাজ করছে তার থেকে আরও ভাল উত্তর দিয়ে ঘুষি মারবে। +1
জাস্টিন ᚅᚔᚈᚄᚒᚔ

@ জাস্টিন: আমি নিশ্চিত যে আমি অনেকগুলি বিষয় বাদ দিয়েছি, এই বিষয়ে আরও দিকগুলি নির্দ্বিধায় যোগ করতে পারেন না! :-)
কেরেরেক এসবি

13
"একরকম জনবসতি" অংশের জন্য, আমি std::random_deviceতার চেয়ে বেশি উল্লেখযোগ্য মনে করি/dev/urandom
কুবিবি

2
একটি উদাহরণ এখানেstd::random_device পাওয়া যাবে
ডব্লু কেএস

1
উইকিপিডিয়া নিবন্ধের কোডটি বগি। এলোমেলো এবং এলোমেলো 2 অভিন্ন। কোড স্নিপেটের মন্তব্যগুলি থেকে এটি স্পষ্ট যে << র্যান্ডম> এ বৈশিষ্ট্যগুলি কীভাবে ব্যবহার করতে হয় তা লেখক বুঝতে পারেন না।
ব্যবহারকারী515430

3

একটি এলোমেলো সংখ্যা জেনারেটর একটি সমীকরণ যা একটি নম্বর দেওয়া, আপনাকে একটি নতুন নম্বর দেবে। সাধারণত আপনি হয় প্রথম নম্বর সরবরাহ করেন বা এটি সিস্টেম সময়ের মতো কিছু থেকে টানা হয়।

প্রতিবার আপনি একটি নতুন নম্বর চাইলে সমীকরণটি চালাতে পূর্ববর্তী নম্বরটি ব্যবহার করে।

এলোমেলো সংখ্যার জেনারেটর খুব ভাল বলে বিবেচিত হয় না যদি অন্য সংখ্যার তুলনায় প্রায় একই সংখ্যার উত্পাদন করার প্রবণতা থাকে। উদাহরণস্বরূপ, যদি আপনি এক থেকে 5 এর মধ্যে একটি এলোমেলো সংখ্যা চান এবং আপনার এই সংখ্যার বিতরণ ছিল:

  • 1: 1%
  • 2: 80%
  • 3: 5%
  • 4: 5%
  • 5: 9%

2 অন্যান্য সংখ্যার তুলনায় অনেক বেশি এয়ার এয়ার উত্পাদিত হয়, সুতরাং এটি অন্যান্য সংখ্যার তুলনায় বেশি উত্পাদন হওয়ার সম্ভাবনা। সমস্ত সংখ্যা যদি সমান হয় তবে আপনার কাছে প্রতিবার প্রতিটি সংখ্যা পাওয়ার 20% সুযোগ থাকবে। এটি অন্যভাবে বলতে গেলে, উপরোক্ত বিতরণটি খুব অসম কারণ 2 টি পছন্দসই। সমস্ত 20% এর সাথে একটি বিতরণ সমান হবে।

সাধারণত, আপনি যদি সত্যিকারের এলোমেলো নম্বর চান তবে আপনি এলোমেলো সংখ্যা জেনারেটরের পরিবর্তে আবহাওয়া বা অন্য কোনও প্রাকৃতিক উত্সের মতো ডেটা টানবেন।


8
বেশিরভাগ এলোমেলো সংখ্যার জেনারেটর ভাল এমনকি বিতরণও জেনারেট করে। এগুলি কেবল এলোমেলো নয়; সমস্যাটি সেগুলি গণনা করা হয় এবং সুতরাং অনুক্রমের পর্যায়ে যথেষ্ট পরিমাণে পরবর্তী নম্বরটি আপনি অনুমান করতে পারেন (এই সত্যটি তাদের সুরক্ষার জন্য খারাপ করে তোলে যেখানে সত্যিকারের এলোমেলো সংখ্যার প্রয়োজন হয়)। গেমস এবং স্টাফের জন্য আপনার ভাল হওয়া উচিত।
মার্টিন ইয়র্ক 21

5
আমি নিশ্চিত যে ওপেন সি ++ <র্যান্ডম> শিরোনামে সরবরাহ করা সুবিধাগুলি সম্পর্কে সুনির্দিষ্ট তথ্য জিজ্ঞাসা করছে pretty এই উত্তরটি এমনকি প্রোগ্রামিংকে সি ++ ছেড়ে দেয় না।
বেনজমিন লিন্ডলি 21 ই

1
@ মার্টিন: সুরক্ষার জন্য সত্যই এলোমেলো সংখ্যার উত্স প্রয়োজন হয় না। কাউন্টার মোডে থাকা এইএস (উদাহরণস্বরূপ) এটি নির্বিচারবাদী হওয়া সত্ত্বেও বেশ সুন্দরভাবে করতে পারে। এটিতে চাবিতে একটি যুক্তিসঙ্গত পরিমাণ এনট্রপি দরকার, তবে কোনও সত্যিকারের এলোমেলো নয়।
জেরি কফিন 21

@ বেঞ্জামিন লিন্ডলি: কিছুই নয়। কেবল পুনরায় পড়া এবং বুঝতে পেরেছিলাম যে আমি ভুল ছিল।
এন_এ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.