সি ++ 11 আপনাকে প্রচুর নতুন বিকল্প দেয় random
। এই বিষয়টির মূল প্রবন্ধটি N3551, সি ++ 11 এ র্যান্ডম নম্বর জেনারেশন হবে
কেন ব্যবহার rand()
করা সমস্যাযুক্ত হতে পারে তা দেখতে , GoingNative 2013 ইভেন্টের সময় দেওয়া স্টিফান টি। লাভভেজের র্যান্ড () বিবেচিত ক্ষতিকারক উপস্থাপনা উপাদানটি দেখুন । স্লাইডগুলি মন্তব্যে রয়েছে তবে এখানে একটি সরাসরি লিঙ্ক ।
আমি লিখিতভাবে কোডটি boost
ব্যবহারের পাশাপাশি rand
লেগ্যাসি কোডটি এখনও এর সমর্থন প্রয়োজন হতে পারে ব্যবহার করে ।
নীচের উদাহরণে cppreference সাইট থেকে চুয়ান এবং ব্যবহার করা হয় এসটিডি :: mersenne_twister_engine ইঞ্জিন এবং এসটিডি :: uniform_real_distribution যা সংখ্যার উত্পন্ন [0,10)
ব্যবধান, অন্যান্য ইঞ্জিন ও ডিস্ট্রিবিউশন আউট মন্তব্য সঙ্গে ( এটা লাইভ দেখতে পাবেন ):
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
int main()
{
std::random_device rd;
//
// Engines
//
std::mt19937 e2(rd());
//std::knuth_b e2(rd());
//std::default_random_engine e2(rd()) ;
//
// Distribtuions
//
std::uniform_real_distribution<> dist(0, 10);
//std::normal_distribution<> dist(2, 2);
//std::student_t_distribution<> dist(5);
//std::poisson_distribution<> dist(2);
//std::extreme_value_distribution<> dist(0,2);
std::map<int, int> hist;
for (int n = 0; n < 10000; ++n) {
++hist[std::floor(dist(e2))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << '\n';
}
}
আউটপুট নিম্নলিখিত মত হবে:
0 ****
1 ****
2 ****
3 ****
4 *****
5 ****
6 *****
7 ****
8 *****
9 ****
আপনি কোন ডিস্ট্রিবিউশনটি বেছে নেবেন তার উপর নির্ভর করে আউটপুট পরিবর্তিত হবে, সুতরাং আমরা যদি স্ট্যান্ড :: নরমাল_ডিজিবিউটেশন2
উভয়ের জন্য যেমন গড় এবং এসটিডিডিভের সাথে মান নির্ধারণ করি তবেdist(2, 2)
পরিবর্তে আউটপুটটি এর অনুরূপ হবে ( এটি সরাসরি দেখুন ):
-6
-5
-4
-3
-2 **
-1 ****
0 *******
1 *********
2 *********
3 *******
4 ****
5 **
6
7
8
9
নীচে উপস্থাপিত কিছু কোডের পরিবর্তিত সংস্করণ রয়েছে N3551
( এটি সরাসরি দেখুন ):
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
std::default_random_engine & global_urng( )
{
static std::default_random_engine u{};
return u ;
}
void randomize( )
{
static std::random_device rd{};
global_urng().seed( rd() );
}
int main( )
{
// Manufacture a deck of cards:
using card = int;
std::array<card,52> deck{};
std::iota(deck.begin(), deck.end(), 0);
randomize( ) ;
std::shuffle(deck.begin(), deck.end(), global_urng());
// Display each card in the shuffled deck:
auto suit = []( card c ) { return "SHDC"[c / 13]; };
auto rank = []( card c ) { return "AKQJT98765432"[c % 13]; };
for( card c : deck )
std::cout << ' ' << rank(c) << suit(c);
std::cout << std::endl;
}
ফলাফলগুলি এর মতো দেখাবে:
5H 5S AS 9S 4D 6H TH 6D KH 2S QS 9H 8H 3D KC TD 7H 2D KS 3C TC 7D 4C QH QC QD QD জেডি এইচ জেসি এসি কেডি 9D 5C 2H 4H 9C 8C JH 5D 4S 7C AD 3S 8S TS 2C 8D 3H 6C JS 7 এস 6 এস
প্রচার করা
অবশ্যই বুস্ট.র্যান্ডম হ'ল সর্বদা একটি বিকল্প, এখানে আমি বুস্ট :: এলোমেলো :: ইউনিফর্ম_আরাল_স্তরন ব্যবহার করছি :
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
int main()
{
boost::random::mt19937 gen;
boost::random::uniform_real_distribution<> dist(0, 10);
std::map<int, int> hist;
for (int n = 0; n < 10000; ++n) {
++hist[std::floor(dist(gen))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << '\n';
}
}
RAND ()
আপনার যদি অবশ্যই ব্যবহার করা হয় rand()
তবে আমরা কীভাবে ভাসমান-পয়েন্টের এলোমেলো সংখ্যা তৈরি করতে পারি তার গাইডগুলির জন্য সি এফকিউতে যেতে পারি? , যা অন্তর অন্তর একটি উত্পন্ন করার জন্য এটির অনুরূপ উদাহরণ দেয় [0,1)
:
#include <stdlib.h>
double randZeroToOne()
{
return rand() / (RAND_MAX + 1.);
}
এবং এর থেকে পরিসীমাটিতে একটি এলোমেলো সংখ্যা তৈরি করতে [M,N)
:
double randMToN(double M, double N)
{
return M + (rand() / ( RAND_MAX / (N-M) ) ) ;
}