2010-06-14 9 views
10

this question के लिए शोध करते समय और random.py में स्रोत कोड पढ़ने पर, मैंने यह सोचना शुरू किया कि randrange और randint वास्तव में "विज्ञापित" के रूप में व्यवहार करते हैं। मैं बहुत ज्यादा झुका तो विश्वास करने के लिए कर रहा हूँ, लेकिन जिस तरह से मैंने इसे पढ़ा, randrange अनिवार्य रूप सेयादृच्छिक हो सकता है। रेन्डिंट (1,10) कभी वापस 11?

start + int(random.random()*(stop-start)) 

के रूप में कार्यान्वित किया जाता है (start और stop के लिए पूर्णांक मूल्यों कल्पना करते हुए), तो randrange(1, 10) 1 से 9 के बीच एक यादृच्छिक संख्या लौटना चाहिए।

randint(start, stop)randrange(start, stop+1) बुला रहा है, जिससे 1 और 10

मेरा प्रश्न के बीच एक संख्या लौटने अब है:

यदि random()1.0 वापस करने के लिए कभी भी थे, तो randint(1,10)11 वापस करेगा, है ना?

+0

वैसे, 'int (random.random() * n)' अभी भी 'रेंज (एन)' में समान रूप से वितरित पूर्णांक उत्पन्न करने का एक सही तरीका नहीं है; वहां एक पूर्वाग्रह है जो छोटे 'एन' के लिए महत्वहीन है लेकिन महत्वपूर्ण हो जाता है क्योंकि 'n' बड़ा हो जाता है। मैंने इसके लिए एक पाइथन बग खोला है http://bugs.python.org/issue9025 –

+0

@ मार्क डिकिंसन: धन्यवाद! यह आकर्षक है। –

+0

@ मार्क डिकिंसन: [यह बग आज के रूप में तय है] (http://docs.python.org/dev/whatsnew/3.2.html#random)। –

उत्तर

26

random.py और डॉक्स से:

"""Get the next random number in the range [0.0, 1.0).""" 

) इंगित करता है कि अंतराल अनन्य 1.0 है। यही है, यह कभी वापस 1.0 नहीं होगा।

यह गणित के क्षेत्र में एक सामान्य परिपाटी है, [ और ], समावेशी है, जबकि ( और ) अनन्य है, और कोष्ठक के दो प्रकार (a, b] या [a, b) के रूप में मिलाया जा सकता है। औपचारिक स्पष्टीकरण के लिए wikipedia: Interval (mathematics) पर एक नज़र डालें।

+0

मैंने उसे पकड़ा नहीं था ') '(और यदि मेरे पास भी था, तो मैं इसका अर्थ नहीं जानता था, इसलिए इस अंतर्दृष्टिपूर्ण उत्तर के लिए आपको बहुत बहुत धन्यवाद)। –

+1

@ टिम: एफवाईआई, कई अलग-अलग सम्मेलन मौजूद हैं। एक अन्य आम तौर पर इस्तेमाल किया जाने वाला सम्मेलन स्क्वायर ब्रेसिज़ को बदल रहा है, ताकि '[ए, बी ['' आधा खुला अंतराल '[ए, बी)' के बराबर होगा। –

+5

यह पर्याप्त नहीं है, क्योंकि यह स्पष्ट नहीं है कि '0.0 <= x <1.0' का अर्थ है कि' 0 <= x * n

3
अजगर प्रलेखन से

:

लगभग सभी मॉड्यूल कार्यों मूल कार्य यादृच्छिक() है, जो अर्द्ध खुले क्षेत्र [0.0, 1.0) में समान रूप से एक यादृच्छिक नाव उत्पन्न करता है पर निर्भर हैं।

फ़्लोट संख्या के लगभग हर PRNG की तरह ..

12

अन्य उत्तर ने बताया कि random() का परिणाम हमेशा होता है सख्ती से 1.0 से कम है; हालांकि, यह केवल आधा कहानी है।

आप randrange(n)int(random() * n) के रूप में कंप्यूटिंग रहे हैं, तो आप भी किसी भी अजगर नाव x0.0 <= x < 1.0 संतुष्ट करने के लिए पता है की जरूरत है कि, और किसी भी सकारात्मक पूर्णांक n, यह सच है कि 0.0 <= x * n < n, ताकि int(x * n) है सख्ती से n से कम है।

दो चीजें हैं जो यहां गलत हो सकती हैं: सबसे पहले, जब हम x * n, n की गणना करते हैं तो पूरी तरह से एक फ्लोट में परिवर्तित हो जाता है। पर्याप्त n के लिए, यह रूपांतरण मूल्य को बदल सकता है।लेकिन यदि आप पाइथन स्रोत को देखते हैं, तो आप देखेंगे कि यह केवल विधि n2**53 से छोटा है (यहां और नीचे मुझे लगता है कि प्लेटफ़ॉर्म आईईईई 754 युगल का उपयोग करता है), जो कि सीमा है n एक फ्लोट के लिए सूचना खोने की गारंटी नहीं है (क्योंकि n बिल्कुल एक फ्लोट के रूप में प्रदर्शित किया जा सकता है)।

दूसरी बात जो गलत हो सकती है यह है कि गुणा x * n (जो अब फ्लोट्स के उत्पाद के रूप में किया जा रहा है, याद है) का परिणाम शायद बिल्कुल प्रतिनिधित्व नहीं किया जाएगा, इसलिए इसमें कुछ गोल शामिल होंगे। यदि x1.0 पर पर्याप्त है, तो यह अनुमान है कि राउंडिंग परिणाम n तक ही हो जाएगी।

यह देखने के लिए कि यह नहीं हो सकता है, हमें केवल x के लिए सबसे बड़ा संभव मान माना जाना चाहिए, जो कि (लगभग सभी मशीनें जो पाइथन चलती हैं) 1 - 2**-53। तो हमें अपने सकारात्मक पूर्णांक n के लिए (1 - 2**-53) * n < n दिखाने की आवश्यकता है, क्योंकि यह हमेशा सत्य होगा कि random() * n <= (1 - 2**-53) * n

सबूत (स्केच) k अद्वितीय पूर्णांक k ऐसी है कि 2**(k-1) < n <= 2**k बनें। फिर n से अगले फ्लोट n - 2**(k-53) है। हमें यह दिखाने की ज़रूरत है कि n*(1-2**53) (यानी, वास्तविक, अबाध, उत्पाद का मूल्य) n - 2**(k-53) के करीब n से अधिक है, ताकि यह हमेशा गोल हो जाए। लेकिन थोड़ा अंकगणितीय दिखाता है कि n*(1-2**-53) से n की दूरी 2**-53 * n है, जबकि n*(1-2**-53) से n - 2**(k-53) की दूरी (2**k - n) * 2**-53 है। लेकिन 2**k - n < n (क्योंकि हम k ताकि 2**(k-1) < n चुना है), इसलिए तो यह पूर्णांक हो जाएगी उत्पाद ,n - 2**(k-53) के करीब है (यह मानते हुए, कि है, कि मंच दौर करने वाली निकटतम के कुछ फार्म कर रही है) ।

तो हम सुरक्षित हैं। ओह!


परिशिष्ट (2015/07/04): ऊपर आईईईई 754 binary64 गणित, राउंड संबंधों करने वाली भी राउंडिंग मोड के साथ हो जाती है। कई मशीनों पर, यह धारणा काफी सुरक्षित है। हालांकि, x86 मशीनों पर जो फ्लोटिंग-पॉइंट के लिए x87 एफपीयू का उपयोग करते हैं (उदाहरण के लिए, 32-बिट लिनक्स के विभिन्न स्वाद), गुणा में double rounding की संभावना है, और यह random() * n के लिए से n तक संभव बनाता है उस मामले में जहां random() सबसे बड़ा संभव मूल्य देता है। इस तरह के सबसे छोटे n जिसके लिए यह हो सकता है n = 2049 है। अधिक के लिए http://bugs.python.org/issue24546 पर चर्चा देखें।

संबंधित मुद्दे