2013-04-09 9 views
5

से छद्म-यादृच्छिक पूर्णांक उत्पन्न करना मैंने दिए गए अंतराल [lower, upper] से यादृच्छिक पूर्णांक उत्पन्न करने के लिए निम्न श्रेणी लिखी।एक बदलते अंतराल से प्रभावी रूप से

class RandomInteger { 

protected: 

    std::random_device randomDevice; 
    std::default_random_engine randomEngine; 
    std::uniform_int_distribution<> distribution; 

public: 

    RandomInteger(int64_t lower, int64_t upper); 

    virtual ~RandomInteger(); 

    virtual int64_t generate(); 
}; 


RandomInteger::RandomInteger(int64_t lower, int64_t upper) : randomEngine(this->randomDevice()), distribution(lower, upper) { 
} 

RandomInteger::~RandomInteger() { 
    // TODO Auto-generated destructor stub 
} 

int64_t RandomInteger::generate() { 
    int64_t i = this->distribution(this->randomEngine); 
    return i; 
} 

अगर अंतराल generate के लिए एक ही है और कई कॉल किए जाते हैं रहता है यह ठीक है। हालांकि, अब मेरा उपयोग मामला अंतराल से पूर्णांक उत्पन्न कर रहा है जो हमेशा बदल रहा है (ऊपरी बाउंड हर बार बढ़ता है)।

सबसे पहले और सबसे महत्वपूर्ण, यह तेज़ होना चाहिए। क्रिप्टोग्राफी के साथ इसका कोई लेना-देना नहीं है, इसलिए बहुत छद्म-यादृच्छिक संख्या ठीक है (और std::random_device शायद इसकी आवश्यकता नहीं है)। यदि संभव हो तो मैं सी शैली से बचना चाहूंगा और आधुनिक सी ++ 11 शैली का उपयोग करूंगा।

क्या आप इसे कुशलता से करने के तरीके सुझा सकते हैं?

+2

क्या वितरण को पर्याप्त कुशल नहीं बदल रहा है? 'uniform_int_distribution' एक बहुत ही पतला आवरण है, वहां कोई महत्वपूर्ण ओवरहेड नहीं होना चाहिए। साथ ही, आपकी कक्षा 'वर्चुअल' में फ़ंक्शन क्यों हैं? –

+0

@ कोनराड्रूडॉल्फ उन्हें वर्चुअल होने की आवश्यकता नहीं है। उन्हें यहां महत्वपूर्ण गतिशीलता में नॉनवर्टुअल परिणाम देगा? मैंने सीखा है कि वर्चुअल विधि कॉल के लिए ओवरहेड बहुत कम है। यह एक अजीब स्थिति है: सी ++ ओओपी भाषा होने का दावा करता है। ओओपी भविष्य में आपके कोड को विस्तारणीय और पुन: प्रयोज्य बनाने के बारे में बहुत कुछ है। हालांकि, कई सी ++ प्रोग्रामर लगातार दूसरों को ओओपी अक्षम करने की सलाह देते हैं (यानी विधियों को गैर-वर्चुअल बनाते हैं) जब तक कि अभी स्पष्ट रूप से आवश्यकता न हो। – clstaudt

+0

@ कोनराड्रूडॉल्फ "वितरण को बदलना" का मतलब विभिन्न मानकों के साथ एक नया 'std :: uniform_int_distribution' को चालू करना होगा? – clstaudt

उत्तर

2

उपयोग uniform_int_distribution::operator() का अधिभार कि स्वीकार करता है एक const param_type &:।

int64_t RandomInteger::generate(int64_t lower, int64_t upper) { 
    int64_t i = this->distribution(this->randomEngine, 
     std::uniform_int_distribution<int64_t>{lower, upper}.param()); 
    return i; 
} 

(ध्यान दें कि आप चाहिए मूल्य आरंभ कर distribution, जैसा कि आप अपने param करने में रुचि नहीं कर रहे हैं इसके अलावा, distributionint64_t साथ टेम्प्लेट की जानी चाहिए, int नहीं।)

यदि uniform_int_distribution किसी भी राज्य को संरक्षित करता है, तो यह कुशलतापूर्वक इसका उपयोग करेगा।

वास्तव में, uniform_int_distribution के अधिकांश कार्यान्वयन किसी भी राज्य को संरक्षित नहीं करते हैं; उदाहरण देखें libstdC++ random.tcc: http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01001_source.html#l00832

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