Zufallszahlen fuer Bitset, ist das so richtig?



  • Hallo,

    ich versuche Zufallszahlen fuer ein Bitset zu generieren. Am Anfang wird geprueft wieviele Bits per block erhalten sind. Spaeter moechte ich dann mit std::uniform_int_distribution<>d(0,std::pow(2.0f,bpb)-1); den Bereich festlegen aus dem die Zufallszahlen generiert werden sollen. Leider stuerzt das Program in der Zeile ab. Wenn ich die Zeile auskommentiere funktioniert es.
    Was mache ich falsch?

    std::random_device rd;
    boost::dynamic_bitset<> generate(int n)
    { 
       std::mt19937 gen(rd());
       const int bpb  = boost::dynamic_bitset<>::bits_per_block; 
       std::vector<boost::dynamic_bitset<>::block_type>arr;
       arr.resize(n%bpb ? n/bpb+1 : n/bpb); 
       //std::uniform_int_distribution<>d(0,std::pow(2.0f,bpb)-1); 
       // auto gen = std::bind(d, rng); 
       std::generate(arr.begin(), arr.end(), gen); 
       boost::dynamic_bitset<> ret(std::begin(arr), std::end(arr)); 
       return ret; 
    }
    


  • Edit: Nicht richtig geguckt.



  • Sorry, wenn ich es auskommentiere muss man Sachen umbennennen:

    boost::dynamic_bitset<> generate(int n)
    { 
       static std::random_device rd;
       std::mt19937 rng(rd());
       const int bpb  = boost::dynamic_bitset<>::bits_per_block; 
       std::vector<boost::dynamic_bitset<>::block_type>arr;
       arr.resize(n%bpb ? n/bpb+1 : n/bpb); 
       std::uniform_int_distribution<>d(0,std::pow(2.0f,bpb)-1); 
       auto gen = std::bind(d, rng); 
       std::generate(arr.begin(), arr.end(), gen); 
       boost::dynamic_bitset<> ret(std::begin(arr), std::end(arr)); 
       return ret; 
    }
    


  • Sorry, wenn ich es auskommentiere muss man Sachen umbennennen:

    boost::dynamic_bitset<> generate(int n)
    { 
       static std::random_device rd;
       std::mt19937 rng(rd());
       const int bpb  = boost::dynamic_bitset<>::bits_per_block; 
       std::vector<boost::dynamic_bitset<>::block_type>arr;
       arr.resize(n%bpb ? n/bpb+1 : n/bpb); 
       std::uniform_int_distribution<>d(0,std::pow(2.0f,bpb)-1); 
       auto gen = std::bind(d, rng); 
       std::generate(arr.begin(), arr.end(), gen); 
       boost::dynamic_bitset<> ret(std::begin(arr), std::end(arr)); 
       return ret; 
    }
    


  • std::pow(2.0f,bpb)-1
    

    ­čś« Ô×í

    (1u << bpb) - 1
    

    Und anderes. Wieso ein vorzeichenbehaftete Typen?

    Aber verstehe ich dich richtig, du willst ein zuf├Ąlliges Bitset mit N Bits erzeugen?
    Ich w├╝rde da pauschal einfach

    boost::dynamic_bitset<> generate(boost::dynamic_bitset<>::size_type N) // size_t statt int
    {
        boost::dynamic_bitset<> ret{N};
    
        static std::independent_bits_engine<std::minstd_rand, 1, uint32_t> engine(std::chrono::system_clock::now().time_since_epoch().count()); // Ich nehm mal nicht random_device, mein MinGW hat noch den Bug
    
        for( boost::dynamic_bitset<>::size_type ct = 0; ct < ret.size(); ++ct )
            ret[ct] = engine();
    
        return ret;
    }
    

    Nehmen, was auch funktioniert, aber vielleicht brauchst du ja was spezielles.
    Edit: Hmm, eine bernoulli_distribution geht auch, ist auch sch├Âner. Ich will jetzt nicht noch extra zwei Engines benutzen, aber sonst w├Ąre das besser.



  • Solltest du nicht lieber uniform_int_distribution<block_type>(0,block_type(-1)) verwenden?
    Edit: Besser w├Ąr's noch, wenn man direkt sagen k├Ânnte, wieviele Bits man haben will. Scheint's ja auch zu geben, wenn ich mir Sone's code angucke.

    Das ist std::pow sieht zerbrechlich aus. 2.0f ist float, floats haben typischerweise eine 24-Bit-Mantisse aus. Was kommt bei pow(2.0f,32) raus? Float oder double? Wenn float und block_type ist > als std::uint32_t, dann h├Ąttest du hier ein Problem.

    Versuch mal die Standardbibliothek im Debug-Modus zu betreiben. Die Toolchain von Microsoft erlaubt das, die GCC auch. Stichwort "safe iterators". Ich seh' da spontan nicht, warum da etwas abst├╝rzen sollte. Schmei├č den Debugger an, verwende s├Ąmlilche Debug-Modi und geh da Schritt f├╝r Schritt durch ...

    BTW: n%bpb ? n/bpb+1 : n/bpb kann man auch (n+bpb-1)/bpb schreiben.



  • Sone schrieb:

    std::pow(2.0f,bpb)-1
    

    ­čś« Ô×í

    (1u << bpb) - 1
    

    Und anderes. Wieso ein vorzeichenbehaftete Typen?

    Aber verstehe ich dich richtig, du willst ein zuf├Ąlliges Bitset mit N Bits erzeugen?
    Ich w├╝rde da pauschal einfach

    boost::dynamic_bitset<> generate(boost::dynamic_bitset<>::size_type N) // size_t statt int
    {
        boost::dynamic_bitset<> ret{N};
    
        static std::independent_bits_engine<std::minstd_rand, 1, uint32_t> engine(std::chrono::system_clock::now().time_since_epoch().count()); // Ich nehm mal nicht random_device, mein MinGW hat noch den Bug
    
        for( boost::dynamic_bitset<>::size_type ct = 0; ct < ret.size(); ++ct )
            ret[ct] = engine();
    
        return ret;
    }
    

    Nehmen, was auch funktioniert, aber vielleicht brauchst du ja was spezielles.
    Edit: Hmm, eine bernoulli_distribution geht auch, ist auch sch├Âner. Ich will jetzt nicht noch extra zwei Engines benutzen, aber sonst w├Ąre das besser.

    Danke fuer den Hinweis. std::independent_bits_engine kannte ich noch nicht.
    Aber verstehe ich das richtig das die For-Schleife ueber alle Bits einzeln itertiert und fuer jedes Bit eine eigen Zufallszahl generiert?

    @kr├╝melkacker
    Ich bekomme die Meldung: R6010 - abort() has benn called



  • PartisanBelgrad schrieb:

    Aber verstehe ich das richtig das die For-Schleife ueber alle Bits einzeln itertiert und fuer jedes Bit eine eigen Zufallszahl generiert?

    Es geht nat├╝rlich direkter:

    boost::dynamic_bitset<> generate(boost::dynamic_bitset<>::size_type N) // size_t statt int
    {
        typedef boost::dynamic_bitset<> bitset;
    
        bitset ret;
    
        static std::independent_bits_engine<std::minstd_rand, bitset::bits_per_block, bitset::block_width_type> engine{std::chrono::system_clock::now().time_since_epoch().count()};
    
        while( ret.size() < N )
            ret.append( engine() );
        ret.resize(N);
    
        return ret;
    }
    

    Aber da arbeite ich mit append und nicht mit einem Puffer wie du. ­čśë


Log in to reply