एक यादृच्छिक संख्या जनरेटर का निर्माण करें जो डाइहार्ड परीक्षण पास करता है


50

जबकि यादृच्छिकता को शामिल करते हुए यहां कई कोड गोल्फ प्रश्न हैं, मैंने अभी तक एक भी नहीं देखा है जो वास्तव में एक एल्गोरिदमिक छद्म-आयामी जनरेटर का निर्माण करने के लिए कहता है। नहीं है यह एक है कि आप एक बिट स्ट्रीम उत्पन्न करने के लिए कहता है, लेकिन अनियमितता है कि एक पर प्रदान की जाती परीक्षण बहुत कठोर नहीं थे, और यह कोड गोल्फ नहीं है।

आपके द्वारा लिखे गए प्रोग्राम में एक एकल कॉल करने योग्य फ़ंक्शन होगा जो 0 से 4294967295 पर एक यादृच्छिक पूर्णांक लौटाएगा। इस फ़ंक्शन को किसी भी लाइब्रेरी या अन्य फ़ंक्शन पर कॉल नहीं करना चाहिए जो प्रोग्राम के भाग के रूप में नहीं लिखे गए थे, विशेष रूप से / देव / यादृच्छिक पर कॉल या एक भाषा की अंतर्निहित रैंड () लाइब्रेरी। विशेष रूप से, आप जिस भाषा में काम कर रहे हैं, उसके मूल संचालक तक सीमित हैं, जैसे अंकगणितीय, सरणी पहुंच और सशर्त प्रवाह नियंत्रण कथन।

आपके कार्यक्रम का स्कोर इस प्रकार है:

Score = C / R

जहाँ C वर्णों में कोड की लंबाई है, और R आपके डैनहार्ड परीक्षण की संख्या है जिसे आपका जनरेटर पास करता है (यदि आपका यादृच्छिक संख्या जनरेटर कम से कम एक Diehard परीक्षण पास नहीं करता है, तो इसका स्कोर अनंत है और यह अयोग्य है)। यदि आपका जेनरेटर एक डैनहार्ड परीक्षा पास करता है, तो यह उत्पन्न होने वाली फ़ाइल P-मानों की एक श्रृंखला प्रदान करती है जो अंतराल के साथ समान रूप से वितरित की जाती हैं [0, 1)।

आर की गणना करने के लिए, 16 एमबी बाइनरी डेटा फ़ाइल उत्पन्न करने के लिए अपने डिफ़ॉल्ट बीज के साथ अपने यादृच्छिक संख्या जनरेटर का उपयोग करें। फ़ंक्शन का प्रत्येक कॉल चार बाइट देता है; यदि आपका फ़ंक्शन बाइट्स वापस करने के लिए बहुत धीमा है, तो यह परीक्षण के लिए कितना मुश्किल है, कम स्कोर प्राप्त करने में एक व्यापार-बंद हो जाएगा। फिर, इसे डाहर्ड परीक्षणों के माध्यम से चलाएं और प्रदान किए गए पी-मूल्यों की जांच करें। (इनको स्वयं लागू करने और लागू करने की कोशिश न करें; यहां दिए गए उपयोग करें )

सबसे कम स्कोर जीतता है, बिल्कुल।


क्या वह कोड है जिसके लिए इंटरनेट कनेक्टिविटी की आवश्यकता है? (ऑनलाइन किसी रैंडम फंक्शन को एक्सेस न करें, लेकिन हो सकता है कि पिंग या किसी एपीआई कॉल के मान हों)
एलसर

"इस फ़ंक्शन को किसी भी पुस्तकालयों या अन्य कार्यों पर कॉल नहीं करना चाहिए जो कार्यक्रम के भाग के रूप में भी नहीं लिखे गए थे।" जिसमें इंटरनेट कनेक्टिविटी फ़ंक्शन शामिल हैं। आपकी पीढ़ी विशुद्ध रूप से एल्गोरिदम होनी चाहिए।
जो जे।

डाईहार्ड सुइट 10-11 एमबी की इनपुट फ़ाइलों की अपेक्षा करता है।
प्रिमो

परीक्षणों की कड़ी टूटी हुई प्रतीत होती है, यहाँ एक संभावित विकल्प है।
२०१२ आर्कम्पियन

मेरे मस्तिष्क-फ्लैक उत्तर (नीचे हटाए गए) के लिए यह कैसे करना चाहिए? मुझे लगता है कि कोड व्यावहारिक होने के लिए बहुत धीमा है
क्रिस्टोफर

जवाबों:


6

गणितज्ञ, ३२ / १५ = २.१३३

x=3;Mod[x=Mod[x^2,28!-67],2^32]&

BBS का सीधा कार्यान्वयन ।

बाइनरी फ़ाइल के साथ उत्पन्न:

f = %; (* assigns anonymous function declared in the previous expression to f *)
Export["random.bin", Array[f, 2^22], "UnsignedInteger32"];

परिणाम का सारांश:

 1. BIRTHDAY SPACINGS TEST           .684805
 2. OVERLAPPING 5-PERMUTATION TEST   .757608/.455899
 3. BINARY RANK TEST                 .369264/.634256
 4. BINARY RANK TEST                 .838396
 5. THE BITSTREAM TEST                (no summary p-value)    
 6. OPSO, OQSO and DNA                (no summary p-value)
 7. COUNT-THE-1's TEST               .649382/.831761
 8. COUNT-THE-1's TEST                (no summary p-value)
 9. PARKING LOT TEST                 .266079
10. MINIMUM DISTANCE TEST            .493300
11. 3DSPHERES TEST                   .492809
12. SQEEZE                           .701241
13. OVERLAPPING SUMS test            .274531
14. RUNS test                        .074944/.396186/.825835/.742302
15. CRAPS TEST                       .403090/.403088/.277389

random.binयहाँ पूर्ण

पूर्ण लॉग फ़ाइल यहाँ।


28!-67कुछ हद तक निषेधात्मक है। क्या कोई छोटा मूल्य है जो 64-बिट पूर्णांक में फिट होगा?
प्रिमो

@primo पाइथन की तरह, गणितज्ञ के पूर्णांक डिफ़ॉल्ट रूप से मनमानी-सटीक होते हैं, इसलिए यह समस्या का कारण नहीं बनता है।
२०१२ आर्कम्पियन

मैं सी में विशेष रूप से पोर्टेबिलिटी के लिए सोच रहा था
प्रिमो


21

पर्ल 28/13 15 2.15

sub r{$s^=~($s^=$s/7215)<<8}

लॉग फ़ाइल यहाँ

पर्ल 29/13 23 2.23

sub r{$s^=~($s^=$s<<8)/60757}

लॉग फ़ाइल यहाँ

ये एक Xorshift पर भिन्नता के कुछ हैं , एक सही बदलाव के बजाय फ्लोटिंग पॉइंट डिवीजन का उपयोग करते हैं। वे दोनों 15 में से 13 टेस्ट पास करते हैं, केवल 6 और 7 टेस्ट में फेल होते हैं।

मुझे पूरा यकीन नहीं है कि चक्र कितना लंबा है, लेकिन क्योंकि निम्न कोड किसी भी समय की अवधि में समाप्त नहीं होता है, इसलिए यह संभव है कि पूर्ण 2 32 :

$start = r();
$i++ while $start != r();
print $i;

पर्ल 39/10 = 3.9

$s=$^T;sub r{~($s=$s*$s%4294969373)||r}

नोट: यदि आप ब्लम-ब्लम-शुब-एस्क पीआरएनजी की तलाश कर रहे हैं, तो कीथ रान्डेल का समाधान इन दोनों में से कहीं बेहतर है।

नीचे मेरे मूल समाधान के रूप में, यह ब्लम ब्लम शुब का एक कार्यान्वयन भी है, जिसमें एक बड़ा अंतर है। मैं 2 32 ( M = 50971 • 84263 ) की तुलना में थोड़ा बड़ा मापांक का उपयोग करता हूं , और जब भी कोई मूल्य सामने आता है कि यह वैध 32-बिट पूर्णांक नहीं है (जो कि 2 32 से बड़ा है ), तो यह अगला मान देता है इसके बजाय रोटेशन। एसेन्स में, इन मूल्यों को समाप्त कर दिया जाता है, बाकी के रोटेशन को अधूरा छोड़ दिया जाता है, जिसके परिणामस्वरूप लगभग एक समान वितरण होता है।

लगता है मदद की है। पहले की तरह ही 9 परीक्षणों को पारित करने के अलावा, यह अब न्यूनतम दूरी की परीक्षा में भी उत्तीर्ण होता है। एक नमूना लॉग फ़ाइल यहां पाई जा सकती है


पर्ल 33/9 67 3.67 (अमान्य?)

 $s=$^T;sub r{$s=$s*$s%4294951589}

नोट: इस समाधान को अमान्य माना जा सकता है, क्योंकि सीमा का शीर्ष -तम 0.00037% कभी नहीं देखा जाएगा।

ब्लम ब्लम शुब का एक त्वरित और गंदा कार्यान्वयन । मैं निम्नलिखित परिणामों का दावा करता हूं:

 1. passed - Birthday Spacings
 2. FAILED - Overlapping Permutations
 3. passed - Ranks of 31x31 and 32x32 Matrices
 4. passed - Ranks of 6x8 Matrices
 5. FAILED - Monkey Tests on 20-bit Words
 6. FAILED - Monkey Tests OPSO, OQSO, DNA
 7. FAILED - Count the 1s in a Stream of Bytes
 8. passed - Count the 1s for Specific Bytes
 9. passed - Parking Lot Test
10. FAILED - Minimum Distance Test
11. passed - Random Spheres Test
12. FAILED - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test

एक नमूना लॉग फ़ाइल यहां मिल सकती है , किसी भी परिणाम के लिए स्वतंत्र महसूस करें। मरने के लिए फ़ाइल निम्न तरीके से बनाई जा सकती है:

print pack('N', r()) for 1..4194304

और फिर आउटपुट को फाइल में पाइप करना। मिनिमम डिस्टेंस ऐसा लगता है कि यह बीत चुका होगा, लेकिन अगर आप इसे कई बार चलाते हैं तो यह हमेशा 1.0 के बहुत करीब होता है , जो कि विफलता का संकेत देता है।


विवरण

सामान्य तौर पर, ब्लम ब्लम शुब एक भयानक PRNG है, लेकिन यह एक अच्छा मापांक चुनकर प्रदर्शन में सुधार किया जा सकता है। जिस एम को मैंने चुना है वह 7027 • 611207 है । ये दोनों प्रमुख कारक, p और q , में मॉड्यूलर रेसिड्यू 3 (mod 4) , और gcd (φ (p-1), 1 (q-1) = 2 है , जो जितना हो सके उतना कम है।

हालाँकि ये विकि पृष्ठ पर सूचीबद्ध एकमात्र मानदंड हैं, लेकिन यह पर्याप्त प्रतीत नहीं होता है। लगभग सभी modulo मैंने कोशिश की हर परीक्षण में विफल रहा। लेकिन एक मुट्ठी भर है जो कुछ परीक्षणों को पारित करेगा, और जो मैंने चुना है वह असाधारण रूप से अच्छा लगता है, जो भी कारण हो।

अंतिम नोट के रूप में, टेस्ट 5 अपने आप में एक अच्छा संकेतक प्रतीत होता है कि PRNG कितना अच्छा है। यदि यह टेस्ट 5 को लगभग पास नहीं करता है , तो यह उनमें से बाकी को शानदार तरीके से विफल कर देगा।


बोनस: ६२ / १४ US ४.४३

$t=$^T;sub r{$t|=(($s=$s/2|$t%2<<31)^($t/=2))<<31for 1..37;$t}

बस गीकरी के लिए, यह एनईएस के लिए मूल टेट्रिस में उपयोग किए गए PRNG का 32-बिट संस्करण है। आश्चर्यजनक रूप से, यह 15 में से 14 परीक्षण पास करता है!

 1. passed - Birthday Spacings
 2. passed - Overlapping Permutations
 3. passed - Ranks of 31x31 and 32x32 Matrices
 4. passed - Ranks for 6x8 Matrices
 5. passed - Monkey Tests on 20-bit Words
 6. passed - Monkey Tests OPSO, OQSO, DNA
 7. FAILED - Count the 1s in a Stream of Bytes
 8. passed - Count the 1s for Specific Bytes
 9. passed - Parking Lot Test
10. passed - Minimum Distance Test
11. passed - Random Spheres Test
12. passed - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test

नमूना लॉग फ़ाइल यहाँ से पहले कर सकते हैं

बेशक, 1..37बिट एक सटीक प्रतिलेखन नहीं है। मूल संस्करण में, एन्ट्रापी रूटीन को प्रति सेकंड 60 बार अपडेट किया जाता है, और फिर यादृच्छिक अंतराल पर, बड़े पैमाने पर उपयोगकर्ता इनपुट पर निर्भर होता है। जो कोई भी रॉम को डिसाइड करना चाहता है, उसके लिए एंट्रॉपी रूटीन शुरू होता है 0xAB47

पायथन-शैली छद्म कोड:

carry = entropy_1 & 1
entropy_1 >>= 1
entropy_2 = (entropy_2 >> 1) | (carry << 31)
carry = (entropy_1 & 1) ^ (entropy_2 & 1)
entropy_1 |= carry << 31

हाँ, मैंने देखा कि आपका एल्गोरिथ्म बिटस्ट्रीम परीक्षण "विफल" हुआ, लेकिन वास्तव में 0.999999 से नीचे कुछ मूल्य थे। फिर भी, आपके परीक्षण सटीक लगते हैं।
जो जेड

हालाँकि, एक समस्या है, और वह यह है कि 4294951589 से 4294967295 तक की संख्या घटित होने की कोई संभावना नहीं है (हालाँकि मुझे लगता है कि यह कारण है कि यह कुछ हद तक डेडहार्ड परीक्षणों में विफल रहा है)।
जो जे।

1
@ जोज़ेंग हाँ, यह एक समस्या है। यह टेस्ट 5 में सबसे स्पष्ट है: पहले रन में 151k लापता शब्द हैं, और उनमें से केवल 143k लापता हैं। एक समाधान 2 ^ 32 की तुलना में थोड़ा बड़ा मापांक चुनना होगा, और उन मानों को अनुमति दे सकते हैं जो शून्य के चारों ओर लपेटने के लिए बहुत बड़े हैं, लेकिन मैं उस एक को खोजने में सक्षम नहीं था जो अच्छी तरह से काम करता है। अगर मैं करता हूं, तो मैं पोस्ट को अपडेट करूंगा।
प्रिमो

7

पायथन, 46/15 = 3.0666

v=3
def R():global v;v=v**3%(2**32-5);return v

यादृच्छिकता उत्पन्न करने के लिए मॉड्यूलर घातांक का उपयोग करता है। 2 ** 32-5 2 ^ 32 से कम सबसे बड़ा अभाज्य है। (टेस्ट # 2 चलाने में सक्षम नहीं होने के साथ एक ही सौदा।)


क्या आप एक लॉग फ़ाइल पेस्ट कर सकते हैं?
प्रिमो

यहाँ लॉग इन करें: codepad.org/ZWhoGe0t
कीथ रान्डेल

1
बेवकूफ विंडोज। यह की सभी आवृत्तियां परिवर्तित किया गया था \rऔर \nकरने के लिए \r\nहै, जो स्पष्ट रूप से परिणाम संबंध रखते हैं। फिक्स सीधे का उपयोग कर फ़ाइल लिखने के लिए है f = open('file.bin', 'wb')और f.write
प्राइमो

यह नया स्कोर पिछले स्कोर को रेखांकित करता है, इसलिए अब स्वीकृत उत्तर है।
जो जेड

यह नया स्कोर अभी तक फिर से चल रहा था, इसलिए मैंने स्वीकृत उत्तर को बदल दिया है।
जो जेड।

4

रूबी, 32/15 = 2.1333

रूबी में लागू कीथ रान्डेल का यह समाधान है।

$v=3;def R;$v=$v**3%(2**32-5)end

@JoeZ यह सबसे नया उत्तर प्रतीत होता है, जो ब्रांड-न्यू मैथमेटिका के उत्तर के साथ जुड़ा हुआ है।
Riking

3

सी # 144/15 = 9.6

uint a=15,b=26,y;uint q(int n){y=(a*1414549U+876619U)^(b*889453U+344753U);b=a;a=y>>12;return(a%256)<<n;}uint r(){return q(24)|q(16)|q(8)|q(0);}

इसने सभी परीक्षणों को पारित कर दिया।

बहुत अधिक पात्रों के साथ यह TestU01 नहीं गुजरता है।

परिणाम: http://codepad.org/iny6usjV

    uint a = 15;
    uint b = 26;

    byte prng8()
    {
        uint y = ((a * 1414549U + 876619U) ^ (b * 889453U + 344753U)) >> 12;
        b = a;
        a = y;
        return (byte)y;
    }

    uint prng32()
    {
        return ((uint)prng8() << 24) | ((uint)prng8() << 16) | ((uint)prng8() << 8) | (uint)prng8();
    }

2

सी # - 103/14 = 7.36

double j=999;uint N(){uint i=0,n=0;for(;i++<4;n=n*256+(uint)j%256)for(j/=277;j<100000;j*=j);return n;}

परिणाम

परीक्षण # 6 को छोड़कर सभी पास है http://codepad.org/k1NSoyQW
पर परिणाम देखें

व्याख्या

सी # बस हमेशा की तरह, रूखेपन के लिए रूबी और पायथन के साथ प्रतिस्पर्धा नहीं कर सकता है, लेकिन मुझे कोशिश करने में मज़ा आया। निश्चित रूप से अन्य मूल्य हैं जो बस के रूप में अच्छी तरह से काम करेंगे (यानी, जे = 999 के लिए प्रारंभिक मूल्य, और भाजक = 277)। संक्षिप्त प्रयोग के बाद मैंने इन्हें चुना।

फ़ाइल-सृजन आवरण के साथ

class R
{
    public static void Main(string[] args)
    {
        var r = new R();
        using (var f = new System.IO.FileStream(".\\out.bin", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read))
        using (var b = new System.IO.BinaryWriter(f))
        {
            for (long i = 0; i < 12 * 1024 * 1024; i += 4)
            {

                b.Write(r.N());
            }
        }
    }

    double j = 999;

    uint N()
    {
        uint i = 0, n = 0;
        for (; i++ < 4; n = n * 256 + (uint)j % 256)
            for (j /= 277; j < 100000; j *= j) ;
        return n;
    }

}

1

पायथन, 41/15 = 2.73333

v=0
def R():global v;v=hash(`v`);return v

किंडा का उपयोग कर धोखाधड़ी में निर्मित हैश समारोह है, लेकिन यह है निर्मित है, इसलिए जैसे अन्य builtins का उपयोग कर, से अधिक नहीं धोखाधड़ी len। दूसरी तरफ, यह मेरे global v;बयान के लिए भुगतान करने के लिए दर्द होता है ...

सभी डेडहार्ड परीक्षण पास करता है (मुझे परीक्षण # 2 के साथ एक समस्या थी, यह मेरे OSX मशीन पर SEGVs है। मेरे स्कोर के लिए, मुझे लगता है कि यह पास हो जाएगा)।

यहाँ 16MB फ़ाइल जनरेट करने के लिए एक ड्राइवर है:

import sys
for i in xrange(1<<22):
  r=R()
  sys.stdout.write('%c%c%c%c'%(r&255, r>>8&255, r>>16&255, r>>24&255))

"इस फ़ंक्शन को किसी भी लाइब्रेरी या अन्य फ़ंक्शन पर कॉल नहीं करना चाहिए जो प्रोग्राम के भाग के रूप में भी नहीं लिखे गए थे, विशेष रूप से / देव / यादृच्छिक या भाषा की अंतर्निहित रैंड () लाइब्रेरी में कॉल करते हैं।" मुझे क्षमा करें, लेकिन यह आपकी प्रविष्टि को अयोग्य घोषित करता है।
जो जेड।

स्पष्ट होने के लिए, "लेन" भी आपकी प्रविष्टि को अयोग्य घोषित करेगा।
जो ०

आपने पंक्ति को कहां खींचा था? है +एक अंतर्निहित समारोह है, और इसलिए अयोग्य घोषित कर दिया?
कीथ रान्डेल

6
लेकिन बहुत सारी भाषाओं में, ऑपरेटर और फ़ंक्शन समान हैं। देखें +और __add__अजगर में, या ऑपरेटर c ++ में ओवरलोडिंग। मुझे पता है कि मैं बालों को विभाजित करने की तरह हूं, इसलिए इस उदाहरण पर विचार करें। अजगर में मैं इस तरह से एक नक्शा बना सकता हूं {'a':5}:? आप शायद हां कहेंगे, लेकिन फिर विचार करें कि कवर के तहत, hash('a')जब आप ऐसा करते हैं तो कॉल किया जाता है।
कीथ रान्डेल

2
मुझे लगता है कि जब आप उस तरह से फ़ंक्शन को संदर्भित करने की आवश्यकता होती है तो मैं रेखा खींचता हूं। यदि आप पायथन में एक हैक पा सकते हैं जो आपको सीधे "हैश" फ़ंक्शन का संदर्भ दिए बिना मानचित्र पते तक पहुंचने की अनुमति देगा, तो मैं इसे स्वीकार कर सकता हूं।
जो जेड।

1

सी, 38/15 = 2.533

long long x;f(){return(x+=x*x+9)>>32;}

मैं अपने मशीन पर काम करने वाले डाहार्ड परीक्षण नहीं कर सका, लेकिन यह 8 जीबी तक के उत्पादन के लिए प्रैक्ट्रैंड सूट से गुजरता है, इसलिए मुझे लगता है कि यह उन सभी को पारित करेगा।


0

ब्रेन-फ्लैक , 344 / (लंबित)

<>((()()){})<> push the amount of iterations to do for the PRNG
(((((((((((((((((((((((((((((((((((()()()){}()){})){}{}){()()()()({}[()])}{})){}{})){}{})()){}{})()){}{})){}{})){}{}){}())){}{})){}{})()){}{})()){}{})){}{})){}{})()){}{})()){}{}) push M (one of the values for the Blum Blum Shub PRNG
((((((((((((()()()){}){}){})){}{}){()({}[()])}{}){}())){}{})()){}{}) push s see above
<>{({}[()])<>starts the loop
(({({})({}[()])}{}) squares the current number
(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]({}))mods by M
<>}{}<>loop ends

इसे ऑनलाइन आज़माएं!

यह ठीक काम करता है लेकिन डेडहार्ड परीक्षण लिंक सभी टूटे हुए हैं :( इसलिए जब तक हम नए नहीं मिलते हैं तब तक मेरे पास अंतिम स्कोर नहीं है

यह ब्लम ब्लम शुब PRNG का उपयोग करता है इसलिए इसे अधिकांश मामलों को पारित करना चाहिए। उपयोग की जाने वाली संख्या काफी बड़ी है कोई 16 पैटर्न परीक्षण मामलों के भीतर दिखाई देंगे


अगर यह अमान्य है तो मुझे बताएं
क्रिस्टोफर

1
मैं 344 गिनता हूं। प्रमेय: कोई भी पूरी तरह से गोल्फ ब्रेन-फ्लैक प्रोग्राम में विषम संख्या में बाइट्स नहीं हैं।
user202729

0

उद्देश्य-सी, 40/1 = 40

बहुत चालाक दृष्टिकोण, .hashकुछ हद तक यहाँ धोखा देने के लिए, लेकिन मुझे यह पसंद है

for(int v=9;v=@(v).hash;printf("%i",v));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.