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

时间:2018-08-27 03:37:15

标签: c random probability

我编写了C程序,该程序定义了一个具有m行和n列且具有随机数(0或1)的2D矩阵。代码如下:

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;
        }
    }

有效。对于下一步,我想创建具有概率的矩阵。例如,将1写入概率为p的单元中,将0写入概率为1-p。如果可以的话,请您分享任何想法吗?

2 个答案:

答案 0 :(得分:3)

由于rand()为您提供介于0RAND_MAX之间的值,因此只需选择适当的阈值,就可以以特定的百分比获得值。例如,如果RAND_MAX999,则预计所有值的42%小于420

因此,您可以使用以下完整程序中的代码来设置适当的阈值并测试值的分布:

#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);
}

一些样本运行,具有不同的期望概率:

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%

因此,最重要的是:要实现一个拥有p概率(一个double值)和一个1 - p的概率为零的愿望,您需要: / 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.

只需记住rand()的限制,概率0.00000000000.0000000001之间的差异很可能不存在,除非RAND_MAX为足够大,可以有所作为。我怀疑您会使用合适的概率,但是我想我还是提一下,以防万一。

答案 1 :(得分:1)

rand() % 2的概率为0.5。

p是浮点型的,因此您将查看How to generate random float number in C以生成真实范​​围内的随机值。最佳答案是给我们:float x = (float)rand()/(float)(RAND_MAX/a);

我们希望a的概率等于1。因此,要以p的概率获得0,公式为:

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

也可以这样写:

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

ps:出于精确原因,如果可用,您应该选择arc4random() or arc4random_buf()而不是rand()

  • rand()的精度为1 / 0x7FFFFFFF(在macOS上)
  • arc4random()的精度为1 / 0xFFFFFFFF(因此提高了两倍)

在这种情况下,公式为:

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