简体   繁体   English

如何在C中以概率随机生成0和1的mxn矩阵

[英]How to generate mxn matrix with randomly generated 0 and 1 with probability in C

I wrote C program that defined a 2D matrix with m rows and n columns with random numbers (Either 0 or 1). 我编写了C程序,该程序定义了一个具有m行和n列且具有随机数(0或1)的2D矩阵。 The code is as following: 代码如下:

int i,j;
    int original_matrix[m][n];
    for (i=0; i<=m-1; i++){
        for (j=0; j<=n-1; j++){
            original_matrix[i][j] = rand() % 2;
        }
    }

It worked. 有效。 For the next step, I want to create the matrix with a probability. 对于下一步,我想创建具有概率的矩阵。 For example, 1 is written into a cell with probability p and 0 is written with probability 1-p. 例如,将1写入概率为p的单元中,将0写入概率为1-p。 Could you please share any ideas on this if you have? 如果可以的话,请您分享任何想法吗?

Since rand() gives you a value between 0 and RAND_MAX , you can get a value at particular perentage simply by choosing an appropriate threshold. 由于rand()为您提供0RAND_MAX之间的值,因此您只需选择适当的阈值即可获得特定百分比的值。 For example, if RAND_MAX was 999 , 42% of all values would be expected to be less than 420 . 例如,如果RAND_MAX999 ,则所有值的42%将小于420

So you can use code like in the following complete program, to set up an appropriate threshold and test the distribution of your values: 因此,您可以使用以下完整程序中的代码来设置适当的阈值并测试值的分布:

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

int main(int argc, char *argv[]) {
    // Get threshold (defaults to ~PI%), seed random numbers.

    double percent = (argc > 1) ? atof(argv[1]) : .0314159;
    int threshold = round(RAND_MAX * percent);
    srand(time(0));

    // Work out distribution (millions of samples).

    int below = 0, total = 0;
    for (int i = 0 ; i < 1000000; ++i) {
        ++total;
        if (rand() < threshold) ++below;
    }

    // Output stats.

    printf("Using probability of %f, below was %d / %d, %f%%\n",
        percent, below, total, below * 100.0 / total);
}

Some sample runs, with varying desired probabilities: 一些样本运行,且具有不同的所需概率:

Using probability of 0.031416, below was 31276 / 1000000, 3.127600%
Using probability of 0.031416, below was 31521 / 1000000, 3.152100%

Using probability of 0.421230, below was 420936 / 1000000, 42.093600%
Using probability of 0.421230, below was 421634 / 1000000, 42.163400%

Using probability of 0.175550, below was 175441 / 1000000, 17.544100%
Using probability of 0.175550, below was 176031 / 1000000, 17.603100%

Using probability of 0.980000, below was 979851 / 1000000, 97.985100%
Using probability of 0.980000, below was 980032 / 1000000, 98.003200%

Using probability of 0.000000, below was 0 / 1000000, 0.000000%
Using probability of 1.000000, below was 1000000 / 1000000, 100.000000%

So, the bottom line is: to acheive your desire of one having a probabilty p (a double value) and zero having the probability 1 - p , you need the following: 因此,最重要的是:要实现一个具有概率pdouble精度值)的零和一个具有概率1 - p零的愿望,您需要:

srand(time(0));                               // done once, seed generator.
int threshold = round(RAND_MAX * p);          // done once.
int oneOrZero = (rand() < threshold) ? 1 : 0; // done for each cell.

Just keep in mind the limits of rand() , the difference between (for example) probabilities 0.0000000000 and 0.0000000001 will most likely be non-existent, unless RAND_MAX is large enough to make a difference. 只需记住rand()的限制, rand()例如)概率0.00000000000.0000000001之间的差值很可能是不存在的,除非RAND_MAX足够大以产生差值。 I doubt you'll be using probabilities that fine but I thought I'd better mention it just in case. 我怀疑您会使用合适的概率,但是我想我还是提一下,以防万一。

rand() % 2 gives you a probability of 0.5. rand() % 2的概率为0.5。

p is a float, so you'll look at How to generate random float number in C to generate a random value in a real range. p是浮点数,因此您将了解如何在C中生成随机浮点数以生成实数范围内的随机值。 The top answer gives us: float x = (float)rand()/(float)(RAND_MAX/a); 最重要的答案是: float x = (float)rand()/(float)(RAND_MAX/a);

We want a equal to 1 for probabilities. 我们想要a等于1的概率。 So, to get 0 with a probability of p , the formula is: 因此,要获得概率为p 0,公式为:

int zeroWithAProbabilityOfP = (float)rand()/(float)RAND_MAX <= p;

Which can be also be written: 也可以这样写:

int zeroWithAProbabilityOfP = rand() <= p * RAND_MAX;

ps: if available, for precision reasons, you should favor arc4random() or arc4random_buf() instead of rand() : ps:如果可用,出于精度原因,您应该偏爱arc4random()arc4random_buf()而不是rand()

  • rand() precision is 1 / 0x7FFFFFFF (on macOS) rand()精度为1 / 0x7FFFFFFF(在macOS上)
  • arc4random() precision is 1 / 0xFFFFFFFF (so twice better) arc4random()精度为1 / 0xFFFFFFFF(因此要好两倍)

In that case, formula would be: 在这种情况下,公式为:

int zeroWithAProbabilityOfP = arc4random() <= p * UINT32_MAX;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM