Home > Back-end >  generate random elements of which x% are zero
generate random elements of which x% are zero

Time:07-22

I know that e.g. doing this

if (rand() % 2 == 0) value = 0; 
else value = (float)rand()/(float)(RAND_MAX/(abs(rand())));

will generate roughly 50% zeroes and 50% other values. But are there other implementations so that I can set the sparsity arbitrarily e.g. to 42% or so.

CodePudding user response:

Yes, you can implement a discrete distribution.

Example:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct {
    int percent;
    int value;
} pv;

#define Size(x) (sizeof (x) / sizeof *(x))

int main() {
    srand((unsigned)time(NULL));
    pv pvs[] = {{42, 0}, {58, 1}}; // 42% 0, 58% 1

    int v = rand() % 100;
    
    for(int i = 0, x = 0; i < Size(pvs);   i) {
        x  = pvs[i].percent;
        if(v < x) {
            printf("%d\n", pvs[i].value); // selected
            break;
        }
    }
}

CodePudding user response:

Since C 11, std::bernoulli_distribution from the <random> header can be used.

#include <random>
#include <iostream>

int main() {
    std::random_device rd;
    std::default_random_engine e(rd());
    std::bernoulli_distribution d(0.42); // 42% probability of true
    std::cout << std::boolalpha;
    for (int i = 0; i < 10;   i)
        std::cout << d(e) << '\n';
    return 0;
}

CodePudding user response:

You're getting 50/50 because you're using '%2'.

If you want something like 42 out of 100 values to be non-zero, then all you need is

val = ( rand() % 100 <= 42 ) ? rand() : 0;

If you need 42.5%, for instance, simply use '1000' and '425' instead.

  • Related