2009-11-13 11 views
8

मुझे बिनोमियल (एन, पी) वितरण से यादृच्छिक संख्याएं उत्पन्न करने की आवश्यकता है।सी #: द्विपदीय वितरण से संख्याएं उत्पन्न करने के लिए संख्यात्मक एल्गोरिदम

ए बिनोमियल (एन, पी) यादृच्छिक चर एन वर्दी चर के योग है जो संभाव्यता पी के साथ 1 लेता है। छद्म कोड में, x=0; for(i=0; i<n; ++i) x+=(rand()<p?1:0); एक द्विपक्षीय (एन, पी) उत्पन्न करेगा।

मुझे इसे छोटे और साथ ही वास्तव में बड़े एन के लिए उत्पन्न करने की आवश्यकता है, उदाहरण के लिए n = 10^6 और p = 0.02। क्या इसे उत्पन्न करने के लिए कोई तेज संख्यात्मक एल्गोरिदम है?

संपादित करें -

public long Binomial(long n, double p) { 
     // As of now it is an approximation 
     if (n < 1000) { 
      long result = 0; 
      for (int i=0; i<n; ++i) 
       if (random.NextDouble() < p) result++; 
      return result; 
     } 
     if (n * p < 10) return Poisson(n * p); 
     else if (n * (1 - p) < 10) return n - Poisson(n * p); 
     else { 
      long v = (long)(0.5 + nextNormal(n * p, Math.Sqrt(n * p * (1 - p)))); 
      if (v < 0) v = 0; 
      else if (v > n) v = n; 
      return v; 
     } 
    } 

+0

क्या पोइसन वितरण 'n * p <10' या' n * (1 - p) <10' के लिए अच्छा काम करता है? आप कैसे वितरण चुनते हैं? – HelloGoodbye

+0

हां, बड़े एन के लिए। द्विपदीय (एन, लैम्ब्डा/एन) पोइसन (लैम्ब्डा) में परिवर्तित होता है, क्योंकि एन अनंत तक जाता है। – KalEl

उत्तर

4

यदि आप भुगतान करना चाहते हैं, तो NMath पर सेंटरस्पेस पर एक नज़र डालें।

अन्यथा, आंकड़े प्रोग्राम आर द्वारा उपयोग किया गया सी कोड here है, और पोर्ट को सी # के लिए सीधा होना चाहिए।

संपादित करें: जैक जू द्वारा Practical Numerical Methods with C# के पी 178 पर इसके लिए एक विधि बनाने के लिए विवरण (इंक कोड) हैं।

किसी अन्य संस्करण: A free C# library जो आप चाहते हैं वह करता है।

3

कोई स्पष्ट रास्ता नहीं है -

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

+0

मैं वास्तव में कुछ एथोक सिक्योरेशन रूटीन का उपयोग कर रहा हूं जिसे मैंने लिखा है जो पोइसन और सामान्य वितरण का उपयोग करता है। हालांकि मुझे यकीन नहीं है कि यह कितनी दूर उत्पन्न करता है, यह सांख्यिकीय रूप से एक वास्तविक द्विपदीय से होगा। मैंने अपना कोड एक संपादन के रूप में जोड़ा है। – KalEl

4

एक और विकल्प सामान्य या पोइसन से नमूना करना होगा जैसा कि आप करते हैं और फिर अपने नमूना को स्वीकार या अस्वीकार करने के लिए Metropolis-Hastings चरण जोड़ें। यदि आप स्वीकार करते हैं कि आप कर चुके हैं, यदि आप अस्वीकार करते हैं, तो आपको फिर से पूरी तरह से फिर से नमूना करना होगा। मेरा अनुमान है कि अनुमान लगभग इतना करीब है, आप लगभग हमेशा एक स्वीकार्य कदम प्राप्त करेंगे, एक समय में आप अस्वीकार कर सकते हैं।

Luc Devroye's book में बिनोमियल नमूनाकरण के लिए कुछ महान एल्गोरिदम हैं।

पीएस यदि आप एक अच्छा एल्गोरिदम के साथ समाप्त होते हैं; क्या आप इसे Math.Net Numerics पर साझा करना चाहते हैं?

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