C ++ 11 आपको कई नए विकल्प देता है random
। इस विषय पर विहित कागज N3551, सी ++ 11 में रैंडम नंबर जनरेशन होगा
यह देखने के लिए कि rand()
समस्याग्रस्त का उपयोग क्यों किया जा सकता है रैंड () गोइंगनेटिव 2013 ईवेंट के दौरान दिए गए स्टेपहान टी। लवविज द्वारा हानिकारक प्रस्तुति सामग्री पर विचार करें । स्लाइड्स टिप्पणियों में हैं, लेकिन यहां एक सीधा लिंक है ।
मैं इसका boost
उपयोग करने के साथ-साथ rand
विरासत कोड को अभी भी इसके समर्थन की आवश्यकता कर सकता हूं ।
नीचे दिए गए उदाहरण को cppreference साइट से डिस्टिल्ड किया गया है और std :: mersenne_twister_engine इंजन और std का उपयोग करता है :: वर्दी_ 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 ****
उत्पादन, इसलिए यदि हम साथ जाने का फैसला किया है जो वितरण आप चुनते हैं पर निर्भर करती है std :: normal_distribution के एक मूल्य के साथ 2
दोनों के लिए मतलब और stddev जैसे 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 JD AH JC AC केडी 9D 5C 4H 9C 8C 8C JC 5D 7C 7C 7S 8S TSC 2C 8D 3C 7 एस 6 एस
बढ़ावा
बेशक Boost.Random हमेशा एक विकल्प के रूप में अच्छी तरह से है, यहाँ मैं बढ़ावा का उपयोग कर रहा हूँ :: यादृच्छिक :: वर्दी_real_distribution :
#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()
तो हम एक गाइड के लिए सी एफएक्यू पर जा सकते हैं मैं फ्लोटिंग-पॉइंट यादृच्छिक संख्या कैसे उत्पन्न कर सकता हूं? , जो मूल रूप से अंतराल पर उत्पन्न करने के लिए इसके समान एक उदाहरण देता है [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) ) ) ;
}