Как сгенерировать матрицу mxn со случайно сгенерированными 0 и 1 с вероятностью в C - PullRequest
0 голосов
/ 27 августа 2018

Я написал C-программу, которая определила двумерную матрицу с m строками и n столбцами со случайными числами (0 или 1).Код выглядит следующим образом:

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 голосов
/ 27 августа 2018

Поскольку rand() дает вам значение от 0 до RAND_MAX, вы можете получить значение в определенном процентном соотношении, просто выбрав соответствующий порог.Например, если RAND_MAX было 999, то ожидается, что 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, вам необходимо следующее:

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.0000000000 и 0.0000000001, скорее всего, не будет существовать, если RAND_MAX не достаточно велико, чтобы иметь значение.Я сомневаюсь, что вы будете использовать такие вероятности, но я подумал, что лучше упомянуть об этом на всякий случай.

0 голосов
/ 27 августа 2018

rand() % 2 дает вам вероятность 0,5.

p - это число с плавающей точкой, поэтому вы посмотрите на Как создать случайное число с плавающей точкой в ​​C для генерации случайного числазначение в реальном диапазоне.Верхний ответ дает нам: float x = (float)rand()/(float)(RAND_MAX/a);

Мы хотим, чтобы a равнялся 1 для вероятностей.Итак, чтобы получить 0 с вероятностью p, формула будет иметь вид:

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

, который также можно записать:

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

пс: если доступно,по причинам точности вам следует отдать предпочтение arc4random() или arc4random_buf() вместо rand():

  • rand() точность равна 1 / 0x7FFFFFFF (в macOS)
  • arc4random() точность равна 1 / 0xFFFFFFFF (так в два раза лучше)

В этом случае формула будет иметь вид:

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