C Language
रैंडम नंबर जनरेशन
खोज…
टिप्पणियों
rand()
के दोषों के कारण, कई अन्य डिफ़ॉल्ट कार्यान्वयन वर्षों में उभरे हैं। उनमें से हैं:
-
arc4random()
(OS X और BSD पर उपलब्ध) -
random()
लिनक्स पर उपलब्ध -
drand48()
(POSIX पर उपलब्ध)
बेसिक रैंडम नंबर जनरेशन
फ़ंक्शन rand()
का उपयोग 0
और RAND_MAX
( 0
और RAND_MAX
शामिल) के बीच एक छद्म यादृच्छिक पूर्णांक मान उत्पन्न करने के लिए किया जा सकता है।
srand(int)
का उपयोग छद्म यादृच्छिक संख्या जनरेटर को बीज बनाने के लिए किया जाता है। हर बार rand()
में एक ही बीज का बीज बोया जाता है, इसे मूल्यों के समान क्रम का उत्पादन करना चाहिए। rand()
कॉल करने से पहले इसे केवल एक बार सीड किया जाना चाहिए। इसे बार-बार सीडेड नहीं किया जाना चाहिए, या हर बार जब आप छद्म यादृच्छिक संख्याओं का एक नया बैच उत्पन्न करना चाहते हैं।
मानक अभ्यास बीज के रूप में time(NULL)
के परिणाम का उपयोग करना है। यदि आपके रैंडम नंबर जनरेटर के लिए नियतात्मक अनुक्रम होना आवश्यक है, तो आप प्रत्येक प्रोग्राम शुरू होने पर उसी मूल्य के साथ जनरेटर को बीज दे सकते हैं। यह आमतौर पर रिलीज कोड के लिए आवश्यक नहीं है, लेकिन बग को प्रजनन योग्य बनाने के लिए डिबग रन में उपयोगी है।
हमेशा जनरेटर को बीज करने की सलाह दी जाती है, अगर बीज नहीं होता है, तो यह ऐसा व्यवहार करता है जैसे कि इसे srand(1)
साथ बीज दिया गया हो।
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int i;
srand(time(NULL));
i = rand();
printf("Random value between [0, %d]: %d\n", RAND_MAX, i);
return 0;
}
संभावित उत्पादन:
Random value between [0, 2147483647]: 823321433
टिप्पणियाँ:
सी मानक उत्पादित यादृच्छिक अनुक्रम की गुणवत्ता की गारंटी नहीं देता है। अतीत में, rand()
कुछ कार्यान्वयन rand()
में उत्पन्न संख्याओं के वितरण और यादृच्छिकता में गंभीर मुद्दे थे। क्रिप्टोग्राफी जैसी गंभीर यादृच्छिक संख्या पीढ़ी की जरूरतों के लिए rand()
की सिफारिश नहीं की जाती है।
अनुमति प्राप्त जेनरेटर
यहां एक स्टैंडअलोन यादृच्छिक संख्या जनरेटर है जो rand()
या इसी तरह के पुस्तकालय कार्यों पर भरोसा नहीं करता है।
आप ऐसा क्यों चाहेंगे? हो सकता है कि आपको अपने प्लेटफ़ॉर्म के बिल्ट रैंडम नंबर जनरेटर पर भरोसा न हो, या हो सकता है कि आप किसी विशेष लाइब्रेरी कार्यान्वयन से स्वतंत्र यादृच्छिकता का एक प्रतिलिपि प्रस्तुत करने योग्य स्रोत चाहते हों।
यह कोड pcg-random.org से एक PCG32 है , जो उत्कृष्ट सांख्यिकीय गुणों वाला एक आधुनिक, तेज, सामान्य प्रयोजन वाला RNG है। यह क्रिप्टोग्राफिक रूप से सुरक्षित नहीं है, इसलिए इसे क्रिप्टोग्राफी के लिए उपयोग न करें।
#include <stdint.h>
/* *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / pcg-random.org
* Licensed under Apache License 2.0 (NO WARRANTY, etc. see website) */
typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t;
uint32_t pcg32_random_r(pcg32_random_t* rng) {
uint64_t oldstate = rng->state;
/* Advance internal state */
rng->state = oldstate * 6364136223846793005ULL + (rng->inc | 1);
/* Calculate output function (XSH RR), uses old state for max ILP */
uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}
void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) {
rng->state = 0U;
rng->inc = (initseq << 1u) | 1u;
pcg32_random_r(rng);
rng->state += initstate;
pcg32_random_r(rng);
}
और यहाँ है इसे कैसे कॉल करें:
#include <stdio.h>
int main(void) {
pcg32_random_t rng; /* RNG state */
int i;
/* Seed the RNG */
pcg32_srandom_r(&rng, 42u, 54u);
/* Print some random 32-bit integers */
for (i = 0; i < 6; i++)
printf("0x%08x\n", pcg32_random_r(&rng));
return 0;
}
दी गई श्रेणी के लिए पीढ़ी को प्रतिबंधित करें
आमतौर पर यादृच्छिक संख्या उत्पन्न करते समय एक सीमा के भीतर पूर्णांक उत्पन्न करना उपयोगी होता है, या 0.0 और 1.0 के बीच एपी मान। जबकि मापांक ऑपरेशन का उपयोग बीज को कम पूर्णांक तक कम करने के लिए किया जा सकता है जो निम्न बिट्स का उपयोग करता है, जो अक्सर एक छोटे चक्र से गुजरता है, जिसके परिणामस्वरूप वितरण का थोड़ा तिरछा होना अगर एन RAND_MAX के अनुपात में बड़ा है।
स्थूल
#define uniform() (rand() / (RAND_MAX + 1.0))
०.० से १.० - एप्सिलॉन पर एपी मूल्य का उत्पादन करता है, इसलिए
i = (int)(uniform() * N)
सेट हो जाएगा i
1 - एन के लिए रेंज 0 के भीतर एक समान यादृच्छिक संख्या पर।
दुर्भाग्य से एक तकनीकी खामी है, जिसमें RAND_MAX को एक प्रकार से बड़ा होने दिया जाता है, जिसे double
का एक वेरिएबल सटीक रूप से प्रस्तुत कर सकता है। इसका अर्थ है कि RAND_MAX + 1.0
, RAND_MAX का मूल्यांकन करता है और फ़ंक्शन कभी-कभी एकता लौटाता है। यह हालांकि संभावना नहीं है।
ज़ोर्शिफ्ट जनरेशन
एक अच्छा और त्रुटिपूर्ण करने के लिए आसान विकल्प rand()
, प्रक्रियाओं xorshift, छद्म यादृच्छिक संख्या से पता चला जनरेटर का एक वर्ग है जॉर्ज मार्साग्लिया । Xorshift जनरेटर सबसे तेजी से गैर-क्रिप्टोग्राफिक रूप से सुरक्षित यादृच्छिक संख्या जनरेटर के बीच है। अधिक जानकारी और अन्य उदाहरण कार्यान्वयन xorshift विकिपीडिया पृष्ठ पर उपलब्ध हैं
उदाहरण कार्यान्वयन
#include <stdint.h>
/* These state variables must be initialised so that they are not all zero. */
uint32_t w, x, y, z;
uint32_t xorshift128(void)
{
uint32_t t = x;
t ^= t << 11U;
t ^= t >> 8U;
x = y; y = z; z = w;
w ^= w >> 19U;
w ^= t;
return w;
}