2011-03-14 7 views
8

का उपयोग कर एक गैर-वर्दी, पूर्णांक वितरण बनाकर अभी मैं एक श्रेणी के साथ पूर्णांक के समान वितरण को बनाने के लिए निम्न कोड का उपयोग करता हूं। (मैं बोने कोड बाहर ले)tr1 <random>

int random(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::uniform_int<int> dist(min, max); 
    return dist(gen); 

} 

मैं इसे संशोधित करने के लिए एक वितरण कि twords मिनट मूल्य के पक्ष में देने के लिए पैदा करता है कोशिश कर रहा हूँ, और लगभग कभी अधिकतम मूल्य के करीब पहुँचता है। मैं सभी पूर्व-निर्मित वितरण देख सकता हूं, लेकिन उनमें से कोई भी पूर्णांक नहीं है। और मैं यह भी नहीं बता सकता कि कौन सा दस्तावेज किसी भी दस्तावेज के आधार पर मेरी आवश्यकताओं को फिट करता है। के रूप में विकिपीडिया, जहां कश्मीर = 2

लेकिन मैं समझ नहीं पर दिखाया गया है, documentation कैसे पूर्णांकों के साथ इसका इस्तेमाल करने, अकेले सेट जाने के आधार पर निकटतम मैं आ गए हैं ची वितरण चुकता है के मूल्य।

उचित गैर-वर्दी, पूर्णांक वितरण का उपयोग करने के लिए मैं अपना कार्य कैसे स्थापित कर सकता हूं?


अभी भी सही distro चुनने पर काम कर रहा: यहाँ 0 से 20 से std::poisson_distribution<int> dist((max - min) * .1); के परिणाम हैं:

काफी वहाँ नहीं अभी तक, के रूप में 0 1 से अधिक बार-बार होना चाहिए, लेकिन यह मदद करनी चाहिए अगले व्यक्ति बाहर आने के बाद और अधिक परिणाम पोस्ट करेंगे। का परिणाम दे रही है

int randomDist(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::chi_squared_distribution<double> dist(2); 

    int x; 
    do 
    { 
    x = (int)(max*dist(gen)/10) + min; 
    } 
    while (x > max); 
    return x; 
} 

:


अच्छी तरह से मेरा अंतिम समाधान विधियों के संयोजन बन गया

+0

यदि आप 1 से कम पैरामीटर चुनते हैं (यह वर्तमान में (20-0) * 1 = 2) है तो एक पोइसन वितरण 0 में 1 से अधिक बार होगा। आप इसे किसी भी पैरामीटर के साथ एक ज्यामितीय वितरण के साथ भी प्राप्त करेंगे। आपको जो चुनना चाहिए वह इस बात पर निर्भर करता है कि आप मॉडलिंग कर रहे हैं: ज्यामितीय मॉडल तब तक होता है जब तक कोई घटना न हो (उदाहरण के लिए, लक्ष्य को स्कोर करने के लिए आवश्यक शॉट्स की संख्या), पोइसन संख्या के अंतराल में संख्या घटना घटनाओं को मॉडल करता है (उदाहरण के लिए, संख्या एक खेल में लक्ष्यों का)। – aaz

+1

वैसे मैं इसे वास्तविक समय आनुवांशिक एल्गोरिदम के लिए उपयोग कर रहा हूं। अलग पीढ़ी होने के बजाय, जब एक नया जीव पैदा करने का समय आता है, तो मैं उन्हें फिटनेस द्वारा क्रमबद्ध करता हूं, माता-पिता को इस वक्र के आधार पर चुनते हैं। – Zak

+0

@Zak - यदि आप ज्यामितीय वितरण का उपयोग करते हैं, तो आप # 1 बनाम (# 2 बनाम विजेता (# 3 बनाम विजेता ...) के विजेता के रूप में प्रत्येक माता-पिता के चयन का वर्णन कर सकते हैं), जहां #i जीत किसी भी #j के खिलाफ, i aaz

उत्तर

9

वहाँ अन्य पूर्णांक वितरण देखते हैं, वे तो बस नहीं है उनके नाम पर int है। उनके पास अपनी कक्षा परिभाषाओं में typedef IntType result_type है।

हैं, जो व्यवहार करते हैं जैसा कि आप का वर्णन कर रहे हैं:

  • binomial_distribution(t, p)

    इस श्रेणी की संख्याएं उत्पन्न 0 ≤ एक्सटी है, तो आप से रेंज अनुवाद करने की आवश्यकता min। मतलब टी · पी में है, इसलिए 0.

    std::binomial_distribution<int> dist(max - min, .1);
    return dist(gen) + min;

  • poisson_distribution(λ)

    के पास एक पी चुनें यह संख्या 0 ≤ एक्स < ∞, लेकिन बड़ी संख्या उत्पन्न करता है प्रगतिशील कम संभावना है। आप इसे किसी सीमा तक सीमित करने के लिए max से ऊपर कुछ भी सेंसर कर सकते हैं। पैरामीटर λ मतलब है।यह चयन पिछले उदाहरण मिलान करने के लिए:

    std::poisson_distribution<int> dist((max - min) * .1);
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

  • geometric_distribution(p)

    भी संख्या उत्पन्न 0 ≤ x < ∞, लेकिन 0 सबसे संभावित परिणाम है और प्रत्येक अनुवर्ती संख्या पिछले की तुलना में कम संभावना है।

    std::geometric_distribution<int> dist(1/((max - min) * .1 + 1));
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

तुम भी करने के लिए निरंतर वितरण के किसी भी उपयोग कर सकते हैं: फिर पैरामीटर चुनने पिछले उदाहरण के माध्य से मिलान करने के double और उसके बाद राउंड उत्पन्न करें यह int पर है।

6

वितरण के अलावा के महान जवाब @aaz में कहा, ध्यान रखें कि आप किसी भी संभावना वितरण समारोह के बारे में सोच सकते हैं करने के लिए अपने समान वितरण बदल सकता है में रखना inverse transform sampling का उपयोग कर (कि हालांकि वास्तव में संभव है केवल कुछ "अच्छे" कार्यों के लिए) या rejection sampling (किसी भी मामले में लागू किया जा सकता है, लेकिन कम्प्यूटेशनल रूप से महंगा हो सकता है)।

मुझे ऐसा लगता है कि एक वितरण कि अपनी आवश्यकताओं फिट (नकारात्मक) होगा exponential distribution:

Exponential distribution

सौभाग्य से, यह वितरण, जिसमें आप उलटा नमूने को बदलने आवेदन कर सकते हैं में से एक है, जिसका अर्थ है कि एक समान से एक नमूना होने [0, 1] वितरण, आप एक घातीय वितरण सूत्र लागू करके प्राप्त कर सकते हैं:

x = - ln(1-p)/lambda 
p साथ

एक यादृच्छिक वैल है समान वितरण और lambda से घातीय वितरण का पैरामीटर है; अधिक जानकारी के लिए here देखें।

एक बार जब आप x (जो एक double हो जाएगा), बस इसे int (या यह दौर एक समारोह के साथ की तरह:

int round(double val) 
{ 
    // warning: can give counterintuitive results with negative numbers 
    return int(val+0.5); 
} 

) डाली मिल अपने परिणाम प्राप्त करने के लिए।


संपादित

वैसे, मैं नोटिस नहीं किया था कि यहां तक ​​कि घातीय वितरण पहले से ही <random> (link) में शामिल है ... अच्छी तरह से, और भी बेहतर, तुम नहीं कोड लिखने की जरूरत है, लेकिन सिद्धांत का थोड़ा सा कभी :) बर्बाद नहीं होता है।

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