2013-09-26 7 views
19

की सीमा तो मैं एक यादृच्छिक वस्तु है: (एक और समारोह के माध्यम से या अन्यथा) वितरण की की ऊपरी सीमावैरी uniform_int_distribution

typedef unsigned int uint32; 

class Random { 
public: 
    Random() = default; 
    Random(std::mt19937::result_type seed) : eng(seed) {} 

private: 
    uint32 DrawNumber(); 
    std::mt19937 eng{std::random_device{}()}; 
    std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX}; 
}; 

uint32 Random::DrawNumber() 
{ 
    return uniform_dist(eng); 
} 

सबसे अच्छा तरीका है मैं भिन्न हो सकते हैं क्या है?

+0

आप पहली बार उन्हें आरंभ के बाद 'distribution' की सीमा अलग-अलग नहीं कर सकते। आपको कैसे आगे बढ़ना चाहिए, इस पर निर्भर करता है कि आप अपनी यादृच्छिक संख्याओं का उपयोग करते हैं और आपको सीमाओं को बदलने की आवश्यकता क्यों है। – us2012

उत्तर

32

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

इसके अलावा, मैंने पूछा है कि गोइंगनेट 2013 लाइव स्ट्रीम पर वितरण की सीमा को कैसे बदलना है, और स्टैंडर्ड कमेटी के एक सदस्य स्टीफन टी। लावेवज ने नए वितरण को बनाने का सुझाव दिया है, क्योंकि यह एक नहीं होना चाहिए प्रदर्शन की समस्याएं।

using uint32 = unsigned int; 

class Random { 
public: 
    Random() = default; 
    Random(std::mt19937::result_type seed) : eng(seed) {} 
    uint32 DrawNumber(uint32 min, uint32 max); 

private:   
    std::mt19937 eng{std::random_device{}()}; 
}; 

uint32 Random::DrawNumber(uint32 min, uint32 max) 
{ 
    return std::uniform_int_distribution<uint32>{min, max}(eng); 
} 
+0

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

+0

के साथ जाऊंगा, मैंने इसे बेंचमार्क किया है। ओवरहेड न्यूनतम है और इसे अनदेखा किया जा सकता है। (यह सूक्ष्म अनुकूलन नाज़ी द्वारा कहा जा रहा है)। इसके अलावा, वितरण की सीमाओं को बदलने का कोई अन्य तरीका नहीं है *। –

+0

ठीक है, बढ़िया, बहुत बहुत धन्यवाद :) मैं शायद न्यूनतम के रूप में स्थिर 0 के साथ और अधिकतम के लिए डिफ़ॉल्ट के रूप में UINT32_MAX के साथ जाऊंगा। – LordAro

5

मैं अपने उदाहरण के लिए DrawNumber समारोह public बना रही हूँ:

यहाँ कैसे मैं अपने कोड लिखने होता है। आप एक अधिभार कि एक ऊपरी बाध्य लेता है प्रदान कर सकते हैं, और उसके बाद से पारित एक नया uniform_int_distribution::param_type

param_typeuniform_int_distribution::operator() को इसी वितरण के रूप में ही तर्क का प्रयोग कर बनाया जा सकता है।

N3337 से, §26.5.1.6/9 [rand.req.dist]

D तर्क लेने वितरण के मापदंडों के लिए इसी के निर्माताओं में से प्रत्येक के लिए, P एक होगा संबंधित कन्स्ट्रक्टर एक ही आवश्यकता के अधीन है और संख्या, प्रकार, और डिफ़ॉल्ट मानों में समान तर्क ले रहा है। इसके अलावा, D के प्रत्येक सदस्य फ़ंक्शंस के लिए जो वितरण के मानकों के अनुरूप मान लौटाते हैं, P के समान नाम, प्रकार और अर्थशास्त्र के साथ संबंधित सदस्य फ़ंक्शन होगा।

जहां D एक यादृच्छिक संख्या वितरण समारोह वस्तु के प्रकार और P है param_type

#include <iostream> 
#include <random> 

typedef unsigned int uint32; 

class Random { 
public: 
    Random() = default; 
    Random(std::mt19937::result_type seed) : eng(seed) {} 

    uint32 DrawNumber(); 
    uint32 DrawNumber(uint32 ub); 

private: 
    std::mt19937 eng{std::random_device{}()}; 
    std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX}; 
}; 

uint32 Random::DrawNumber() 
{ 
    return uniform_dist(eng); 
} 

uint32 Random::DrawNumber(uint32 ub) 
{ 
    return uniform_dist(eng, decltype(uniform_dist)::param_type(0, ub)); 
} 

int main() 
{ 
    Random r; 
    std::cout << r.DrawNumber() << std::endl; 
    std::cout << r.DrawNumber(42) << std::endl; 
} 
8

आप बस एक std::uniform_int_distribution<uint32>::param_type बना सकते हैं और param() का उपयोग कर सीमा को संशोधित कर सकते प्रकार D के द्वारा नाम जुड़े है तरीका। आप decltype के साथ टेम्पलेट शोर कटौती कर सकते हैं:

decltype(uniform_dist.param()) new_range (0, upper); 
uniform_dist.param(new_range); 
संबंधित मुद्दे

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