2012-07-03 16 views
5

की श्रेणी को संशोधित करने के लिए मुझे एक फ़ंक्शन रैंड 5() दिया जाता है जो एक समान वितरण के साथ उत्पन्न होता है, बंद अंतराल में एक यादृच्छिक पूर्णांक [1,5]। मैं rand7(), और कुछ भी नहीं, फ़ंक्शन rand7() बनाने के लिए कैसे उपयोग कर सकता हूं, जो [1,7] (फिर से, समान रूप से वितरित) में पूर्णांक उत्पन्न करता है?एक समान यादृच्छिक संख्या जनरेटर


  1. मैं stackoverflow खोज की, और इसी तरह के कई सवाल तो मिलीं लेकिन वे वास्तव में इस तरह।
  2. मेरा प्रारंभिक प्रयास rand5() + 0.5 * rand5() + 0.5 * rand5() था। लेकिन यह समान संभावना के साथ 1 से 7 तक पूर्णांक उत्पन्न नहीं करेगा। किसी भी उत्तर, या उत्तरों के लिंक, बहुत स्वागत है।
+0

अतिरिक्त नोट देता है:: - यहाँ (स्यूडोकोड में इस भयानक अजगर है) एक ही रास्ता है सामान्य रूप में, rand5() संक्षेप काम नहीं करेगा। जैसा कि हम rand5() पर योग करते हैं, हम समान वितरण से विचलन करना शुरू कर देंगे, और सामान्य वितरण के करीब आना शुरू कर देंगे। –

+2

http://stackoverflow.com/questions/10464360/use-rand5-to-generate-rand7-with-the-same-probability – Mathias

+0

@Mathias, नहीं, यह एक ही प्रश्न नहीं है, एक के लिए डुप्लिकेट की तरह दिखता है आप लिंक सी # – unkulunkulu

उत्तर

2

ठीक है, मुझे थोड़ी देर के लिए इसके बारे में सोचना पड़ा लेकिन वास्तव में यह मुश्किल नहीं है। बजाय rand5 आप rand2 जो या तो आउटपुट 0 या 1. आप बस

rand2() { 
    if(rand5() > 2.5) return 1 
    else return 0 
} 

कर अब कई बार rand2 का उपयोग करके rand5 की rand2 हमारे एक पेड़ करना rand7 प्राप्त करने के लिए कर सकते हैं के लिए किया था की कल्पना कीजिए। उदाहरण के लिए यदि आप rand7 को रैंड 2 के फेंकने के बाद [1,2,3,4,5,6,7] में शुरू कर सकते हैं जो 0 देता है तो अब आप [1,2,3,4] तक पहुंच जाते हैं और एक और फेंकने के बाद या rand2 जो 1 है जिसे आप [3,4] तक सब्सक्राइब करते हैं और 1 का अंतिम फेंक रैंड 7 का उत्पादन 4 देता है। आम तौर पर यह पेड़ चाल एक रैंड 2 लेने के लिए काम कर सकती है और मानचित्र को रैंडक्स पर ले जा सकता है जहां एक्स कोई पूर्णांक है।

+0

rand2 0 वापस आ जाएगा जब rand5 1 या 2 लौटाता है; यह 1 वापस आ जाएगा जब rand5 3, 4, या 5 देता है। आपको समान संभावना के साथ 0 या 1 को वापस करने के लिए rand2 की आवश्यकता होती है। –

+1

सच है, ठीक है, आप अभी भी रैंड 5 को फिर से चलाकर रैंड 2 फ़ंक्शन कर सकते हैं यदि यह 3 – hackartist

+0

था, मैंने इस लाइन के साथ शुरुआत की थी, और टेड होप द्वारा की गई टिप्पणी पर अटक गया था। रैंड 2() का पुन: उपयोग करने के बारे में कभी सोचा नहीं था अगर पहली फेंक ने मुझे दिया 3. उह, और दोहरी! मुझे यह दृष्टिकोण बहुत पसंद है, क्योंकि मेरे प्रश्न के पीछे सामान्यीकरण है, जैसा कि @ हाकार्टिस्ट द्वारा उल्लेख किया गया है, और यह इस अर्थ में एक सीमित प्रक्रिया है कि पीआर (प्रक्रिया कभी खत्म नहीं होती है) = 0. –

7

ध्यान दें कि एक प्रीफेक्ट समान वितरण क्योंकि के लिए हर k, draw5() आमंत्रण की एक घिरे संख्या के साथ हासिल नहीं किया जा सकता है: 5^k % 7 != 0 - ताकि आप हमेशा कुछ "अतिरिक्त" तत्वों होगा।

दो नंबर, x1, x2 ड्रा:

यहाँ draw5() उपयोग के असीम संख्या के साथ एक समाधान है। इसके लिए 5 * 5 = 25 संभावित परिणाम हैं।

ध्यान दें कि 25/7 ~ = 3.57। 3 * 7 = 21 संयोजनों का चयन करें, जैसे कि प्रत्येक संयोजन को अन्य सभी संख्याओं के लिए [1,7] में एक नंबर पर मैप किया जाएगा - रेड्रा।

उदाहरण के लिए:

(1,1),(1,2),(2,1) : 1 
(3,1),(1,3),(3,2): 2 
(3,3),(1,4),(4,1): 3 
(2,4),(4,2)(3,4): 4 
(4,3), (4,4), (1,5): 5 
(5,1), (2,5), (5,2) : 6 
(5,3), (3,5), (4,5) : 7 
(5,4),(5,5),(2,3), (2,2) : redraw 
+0

हमारे पास असीमित रूप से आकर्षित करने की संभावना है (0 की संभावना के साथ) :) हालांकि मुझे लगता है कि इस तरह के विस्तार के बिना लागू करना असंभव है :) ओह, आपके पास असंभवता के बारे में सबूत है, फिर +1 साफ़ करें :) – unkulunkulu

+0

@unkulunkulu : मेरा संपादन पढ़ें (अंतिम वाक्य) क्यों draw5 ops – amit

+0

की बाध्य संख्या के साथ एक पूर्ण वर्दी वितरण नहीं किया जा सकता है, मैं सुझाव दूंगा कि आप उस वाक्य को शुरुआत में ले जाएं क्योंकि यह लेखक उम्मीद कर रहा है (गणितीय रूप से एक आदर्श समाधान) – unkulunkulu

4

यहाँ एक आसान तरीका है:

  1. उपयोग rand5() सेट से तीन यादृच्छिक पूर्णांकों का एक दृश्य उत्पन्न करने के लिए {1, 2, 4, 5} (यानी, जेनरेट की गई किसी भी 3 को फेंक दें)।
  2. यदि सभी तीन नंबर सेट {1, 2} में हैं, तो अनुक्रम को छोड़ दें और चरण 1 पर वापस आएं।
  3. अनुक्रम में प्रत्येक संख्या के लिए, मानचित्र {1, 2} से 0 और {4, 5} 1. इन्हें 3-बिट संख्या के लिए तीन बिट मानों के रूप में उपयोग करें। चूंकि बिट्स 0 नहीं हो सकते हैं, संख्या सीमा [1, 7] में होगी। चूंकि प्रत्येक बिट बराबर संभावना के साथ 0 या 1 है, इसलिए [1, 7] पर वितरण समान होना चाहिए।
+0

अच्छा उत्तर , मुझे आश्चर्य है कि यह सामान्य कैसे होता है यदि प्रारंभिक संख्या 5 की बजाय y थी और लक्ष्य संख्या 7 की बजाय x थी ... – hackartist

+0

अमित के समाधान की तरह, यह एक सीमित प्रक्रिया होने की गारंटी नहीं है। –

+0

@ hackartist - मुझे लगता है कि इस तरह के अस्वीकृति नमूनाकरण किसी भी श्रेणी की किसी भी जोड़ी को सामान्यीकृत करना बहुत आसान होना चाहिए। –

2

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

हमें कम से कम एक बार (स्पष्ट रूप से!) रैंड 5() को कॉल करना होगा, लेकिन अगर हम उस बुरी चीजों पर शाखा करते हैं तो हम चतुर नहीं होते हैं। तो बजाय 7 संभावनाओं से प्रत्येक के लिए एक बार इसे कहते हैं: जाहिर है

In [126]: import random 

In [127]: def r5(): 
    .....:  return random.randint(1, 5) 
    .....: 

In [128]: [r5() for i in range(7)] 
Out[128]: [3, 1, 3, 4, 1, 1, 2] 

इन शर्तों में से प्रत्येक के लिए समान रूप से इन नंबरों में से किसी होने की संभावना थी .. लेकिन उनमें से केवल एक, 2 हुआ तो हमारे शासन करता है, तो "जो भी शब्द रैंड 5() 2 के लिए 2 देता है" का चयन किया गया था, तो यह काम करता। या 4, या जो भी हो, और अगर हम बस इतना लंबा हो जाएंगे कि ऐसा होगा। तो काम करने वाली किसी चीज़ के साथ आने का बहुत सारे तरीके हैं।

import random, collections 

def r5(): 
    return random.randint(1, 5) 

def r7(): 
    left = range(1, 8) 
    while True: 
     if len(left) == 1: 
      return left[0] 
     rs = [r5() for n in left] 
     m = max(rs) 
     how_many_at_max = rs.count(m) 
     if how_many_at_max == len(rs): 
      # all the same: try again 
      continue 
     elif how_many_at_max == 1: 
      # hooray! 
      return left[rs.index(m)] 
     # keep only the non-maximals 
     left = [l for l,r in zip(left, rs) if r != m] 

जो

In [189]: collections.Counter(r7() for _ in xrange(10**6)) 
Out[189]: Counter({7: 143570, 5: 143206, 4: 142827, 2: 142673, 6: 142604, 1: 142573, 3: 142547}) 
+0

एक बहुत ही रोचक दृष्टिकोण है, लेकिन: मैं काफी नहीं देखते कि इसे क्यों काम करना चाहिए (मेरा मतलब है, हम कुछ विशेष संख्याओं को फेंकने के बजाय अन्य सुझाए गए एल्गोरिदम में से एक में केवल 7 संख्याओं में से एक के रूप में गिन सकते हैं, उदाहरण के लिए, इसके परिणामस्वरूप वर्दी वितरण, लेकिन यादृच्छिक नहीं है, इसलिए यह नमूना कुछ साबित नहीं करता है। साथ ही, यह समाधान दूसरों की तुलना में और भी संख्याओं को फेंकने लगता है। – unkulunkulu

+0

@unkulunkulu: मैंने दक्षता का कोई दावा नहीं किया। दृष्टिकोण के बारे में आपको क्या परेशान कर रहा है, यद्यपि? प्रत्येक पुनरावृत्ति पर, प्रत्येक शब्द के पास लौटने या निकालने का बराबर मौका होता है। – DSM

+0

मुझे क्या बग है कि एल्गोरिदम जटिल है, सबसे पहले आप एक बुनियादी विचार (जो कि बहुत स्पष्ट नहीं है) खींचते हैं, फिर आप साबित करने की कोशिश किए बिना कोड का एक टुकड़ा प्रस्तुत करते हैं कि यह काम करेगा। और मुझे इन जटिलताओं का कोई कारण नहीं दिख रहा है: यह तेज़ नहीं है, यह आसान नहीं है, यह सीमित समय में लौटने की गारंटी नहीं है। यह पूरी तरह से दिलचस्प है क्योंकि यह स्पष्ट नहीं है कि यह सही है या नहीं। – unkulunkulu

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