Onion Knight
Onion Knight

Reputation: 19

Unbalanced random binary sequence generator

I’m trying to write a function to generate binary sequence which is unbalanced. Unbalanced means P(0) = 1/2 + bias, P(1) = 1/2 - bias, P(0) + P(1) = 1. bias can be negative

auto genenator(int length, int bias) {
       std::vector<int> result;
       ......
       return result;
}

For example, res = generator(20, 0.1).

res may = {0,0,1,0,1,0,0,1,0,1,1,0,1,1,0,0,0,1,0,0}, there are twelve 0 and eight 1, so P(0) = 12 / 20 = 0.6, P(1) = 0.4.

I only found this https://www.geeksforgeeks.org/generate-a-random-binary-string-of-length-n/

Upvotes: 0

Views: 112

Answers (1)

jpmarinier
jpmarinier

Reputation: 4733

Unfortunately, the geeksforgeeks solution you mention uses the legacy rand()/srand() functions, which are kept in the C++ language essentially for backward compatibility purposes. The quality of their output is by no means guaranteed across platforms.

For new code, you are supposed to use functions from the C++11 <random> header file. The relevant theory is exposed in the N3551 white paper.

The <random> header provides a Bernoulli distribution object, as mentioned by Evg in the comments.

A concern is that we probably do not want to “hardwire” a specific type of random engine into our generator function. To achieve this, we can make the engine type a template argument, like this:

#include  <random>

template  <class Engine>
auto generator(int length, double bias, Engine& eng) {
       std::vector<int>  result(length, 0);

       std::bernoulli_distribution  bdst(1.0 - (0.5 + bias));

       for (int i=0; i < length; i++) {
           bool  bv = bdst(eng);   // random boolean value
           int   iv = bv ? 1 : 0;
           result[i] = iv;
       }

       return result;
}

The caller has to provide some engine, for example like this:

#include  <algorithm>
#include  <random>
#include  <iostream>

int main()
{
    int                 variateCount = 1000000;
    double              bias         = 0.1;
    std::random_device  rd;
    std::mt19937        gen(rd());  // random engine seeded by OS entropy

    auto  vec = generator(variateCount, bias, gen);

    int   zeroCount = std::count(vec.begin(), vec.end(), 0);

    std::cout << "Number of zeroes: " << zeroCount << " out of "
              << variateCount << " variates." << std::endl;

    return EXIT_SUCCESS;
}

Test program output:

Number of zeroes: 599904 out of 1000000 variates.

Upvotes: 2

Related Questions