PCG, A बेहतर रैंडम नंबर जनरेटर को लागू करने की तुलना में PCG.SE के लिए बेहतर समस्या क्या है ? यह नया पेपर एक तेज़, हार्ड-टू-प्रेडिक्ट, छोटे, सांख्यिकीय रूप से इष्टतम यादृच्छिक संख्या जनरेटर पेश करने का दावा करता है।
इसका न्यूनतम C कार्यान्वयन सिर्फ नौ लाइनों के बारे में है:
// *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));
}
(से: http://www.pcg-random.org/download.html )
सवाल यह है: क्या आप बेहतर कर सकते हैं?
नियम
एक प्रोग्राम लिखें या एक फ़ंक्शन को परिभाषित करें जो पीसीजी को 32-बिट अहस्ताक्षरित पूर्णांक पर लागू करता है। यह काफी व्यापक है: आप एक अनंत अनुक्रम को प्रिंट कर सकते हैं, एक pcg32_random_r
फ़ंक्शन और संबंधित संरचना आदि को परिभाषित कर सकते हैं ।
आप निम्नलिखित सी फ़ंक्शन के लिए अपने यादृच्छिक संख्या जनरेटर के बराबर बीज देने में सक्षम होना चाहिए:
// pcg32_srandom(initstate, initseq)
// pcg32_srandom_r(rng, initstate, initseq):
// Seed the rng. Specified in two parts, state initializer and a
// sequence selection constant (a.k.a. stream id)
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);
}
(से pcg_basic.c:37
:)
पहले बिना नंबर के रैंडम नंबर जनरेटर को कॉल करना अपरिभाषित व्यवहार है।
आसानी से अपने सबमिशन की जाँच करने के लिए, यह सत्यापित करें कि, कब initstate = 42
और किसके साथ initseq = 52
, आउटपुट है 2380307335
:
$ tail -n 8 pcg.c
int main()
{
pcg32_random_t pcg;
pcg32_srandom_r(&pcg, 42u, 52u);
printf("%u\n", pcg32_random_r(&pcg));
return 0;
}
$ gcc pcg.c
$ ./a.out
2380307335
स्कोरिंग
मानक स्कोरिंग। बाइट्स में मापा जाता है। निम्नतम सबसे अच्छा है। टाई के मामले में, पहले सबमिशन जीत जाता है। मानक खामियां लागू होती हैं।
नमूना समाधान
gcc -W -Wall
सफाई के तहत संकलन (संस्करण 4.8.2)।
यह सुनिश्चित करने के लिए अपने सबमिशन की तुलना करें कि आपको समान अनुक्रम प्राप्त हो।
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
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);
}
int main()
{
size_t i;
pcg32_random_t pcg;
pcg32_srandom_r(&pcg, 42u, 52u);
for (i = 0; i < 16; i++)
{
printf("%u\n", pcg32_random_r(&pcg));
}
return 0;
}
अनुक्रम:
2380307335
948027835
187788573
3952545547
2315139320
3279422313
2401519167
2248674523
3148099331
3383824018
2720691756
2668542805
2457340157
3945009091
1614694131
4292140870