2008-09-29 19 views
11

के लिए आरएनजी के रूप में यादृच्छिक मेरे पास एक प्रोग्राम है जो boost :: random से mt19937 यादृच्छिक संख्या जनरेटर का उपयोग करता है। मुझे एक random_shuffle करने की आवश्यकता है और इस साझा स्थिति से होने के लिए यादृच्छिक संख्याएं उत्पन्न होनी चाहिए ताकि वे मेर्सन ट्विस्टर के पहले जेनरेट किए गए नंबरों के संबंध में निर्धारिती हो सकें।बूस्ट का उपयोग करना :: std :: random_shuffle

मैं कुछ इस तरह की कोशिश की:

void foo(std::vector<unsigned> &vec, boost::mt19937 &state) 
{ 
    struct bar { 
     boost::mt19937 &_state; 
     unsigned operator()(unsigned i) { 
      boost::uniform_int<> rng(0, i - 1); 
      return rng(_state); 
     } 
     bar(boost::mt19937 &state) : _state(state) {} 
    } rand(state); 

    std::random_shuffle(vec.begin(), vec.end(), rand); 
} 

लेकिन मैं एक टेम्पलेट त्रुटि रैंड साथ random_shuffle बुला मिलता है। हालांकि यह काम करता है:

unsigned bar(unsigned i) 
{ 
    boost::mt19937 no_state; 
    boost::uniform_int<> rng(0, i - 1); 
    return rng(no_state); 
} 
void foo(std::vector<unsigned> &vec, boost::mt19937 &state) 
{ 
    std::random_shuffle(vec.begin(), vec.end(), bar); 
} 

शायद क्योंकि यह वास्तविक कार्य कॉल है। लेकिन जाहिर है यह राज्य को मूल मेर्सन ट्विस्टर से नहीं रखता है। क्या देता है? क्या वैश्विक वैरिएबल के बिना मैं क्या करने की कोशिश कर रहा हूं?

+0

एक बार जब आप इसे बाहर का परीक्षण, आपने सही कोड पोस्ट करें सकता है , वंशावली के लिए? धन्यवाद –

+0

ग्रेग: मैंने आपके परिवर्तन को वापस कर दिया है। यदि आप मार्कडाउन कोड ब्लॉक (इंडेंट प्रत्येक पंक्ति 4 रिक्त स्थान) का उपयोग करने के इच्छुक हैं, तो आपको अपने कोड में HTML वर्णों से बचने की ज़रूरत नहीं है। –

+0

बस कोड को हाइलाइट करें, और "010 101" बटन पर क्लिक करें। –

उत्तर

11

सी ++ 03 में, आप फ़ंक्शन-स्थानीय प्रकार के आधार पर टेम्पलेट को तुरंत चालू नहीं कर सकते हैं। यदि आप रैंड क्लास को फ़ंक्शन से बाहर ले जाते हैं, तो इसे ठीक काम करना चाहिए (अस्वीकरण: परीक्षण नहीं किया गया है, अन्य भयावह बग भी हो सकते हैं)।

यह आवश्यकता सी ++ 0x में आराम कर दी गई है, लेकिन मुझे नहीं पता कि परिवर्तन अभी तक जीसीसी के सी ++ 0x मोड में लागू किया गया है, और मैं किसी अन्य कंपाइलर में इसे ढूंढने के लिए बेहद आश्चर्यचकित हूं ।

+0

स्ट्रक्चर को बाहर ले जाने का परीक्षण किया गया, और काम करता है। –

+1

जब आप संरचना को वैश्विक स्तर पर ले जा रहे हैं, तो इसे भी std :: unary_function से प्राप्त करने के लिए स्वतंत्र महसूस करें। :-) –

13

टिप्पणियों में, रॉबर्ट गोल्ड भावी पीढ़ी के लिए काम कर रहे संस्करण के लिए पूछा:

#include <algorithm> 
#include <functional> 
#include <vector> 
#include <boost/random.hpp> 

struct bar : std::unary_function<unsigned, unsigned> { 
    boost::mt19937 &_state; 
    unsigned operator()(unsigned i) { 
     boost::uniform_int<> rng(0, i - 1); 
     return rng(_state); 
    } 
    bar(boost::mt19937 &state) : _state(state) {} 
}; 

void foo(std::vector<unsigned> &vec, boost::mt19937 &state) 
{ 
    bar rand(state); 
    std::random_shuffle(vec.begin(), vec.end(), rand); 
} 
+0

संयोग से, यह नहीं है कि मैं कोड कैसे प्रारूपित करता हूं (मैं "foo & bar" पसंद नहीं करता, न कि "foo & bar"), लेकिन मैंने सोचा कि मुझे इसे अकेला छोड़ देना चाहिए, सिर्फ उन लोगों के लिए जो सोचते हैं कि इस तरह के संपादन "एक अंतर डाल सकते हैं "। –

+0

जिज्ञासा से unary_function से विरासत में क्या लाभ मिलता है? यह ऑपरेटर से स्पष्ट है() इनपुट और आउटपुट क्या हैं ... –

+0

यह फ़ैक्टर को अधिक संगत बनाता है। यानी, यह कुछ टाइपिफ़ी प्रदान करता है जो आपके मज़ेदार से अन्य मज़ेदारों को आसान बनाते हैं। मुझे आपके लिए एक लिंक तलाशने दो .... –

5

मैं बजाय tr1 बढ़ावा :: यहाँ यादृच्छिक का उपयोग कर रहा है, लेकिन ज्यादा बात नहीं करना चाहिए।

निम्नलिखित कुछ मुश्किल है, लेकिन यह काम करता है।

#include <algorithm> 
#include <tr1/random> 


std::tr1::mt19937 engine; 
std::tr1::uniform_int<> unigen; 
std::tr1::variate_generator<std::tr1::mt19937, 
          std::tr1::uniform_int<> >gen(engine, unigen); 
std::random_shuffle(vec.begin(), vec.end(), gen); 
+0

यह वास्तव में काम नहीं करता है एक-एक-एक त्रुटि। जैसा कि लिखा गया है, 'जीएन' '0' से 'एन' के माध्यम से' एन' के माध्यम से 'एन'' के माध्यम से 'एन'' के माध्यम से' std :: random_shuffle() 'के रूप में आवश्यक पूर्णांक उत्पन्न करता है। – Spire

+0

@Spire: uniform_int :: ऑपरेटर (इंजन, एन) एक संख्या [0, एन) (यानी 0 और एन -1 के बीच) देता है। तो यह मुश्किल है, वास्तव में काम करता है। – baol

1

मैंने सोचा कि यह उनका कहना है कि यह अब केवल मानक पुस्तकालय का उपयोग करने में सी ++ 11 बिल्कुल स्पष्ट है लायक था:

#include <random> 
#include <algorithm> 

std::random_device rd; 
std::mt19937 randEng(rd()); 
std::shuffle(vec.begin(), vec.end(), randEng); 
संबंधित मुद्दे