Почему srand создает одинаковые номера? - PullRequest
1 голос
/ 27 октября 2019

Я написал программу на c, которая создает случайно матрицу. Создает строку вроде этой (3, -6,2; 5,2, -9; -8,20,7). ";"вырезает каждую строку и "," каждый столбец. Теперь я написал программу ржавчины, которая делает матричное дополнение или мульт. Я называю это так:
./matrix ./test 3 3 "*" ./test 3 3

. / Matrix вызывает мою программу ржавчины, и я даю ей 3 аргумента. (Матрица 1, Оператор, Матрица2) Это работает, и вычисления в порядке, но Матрица 1 и 2 всегда равны. Я думаю, это потому, что я использую srand в зависимости от времени, и потому что я вызываю его одновременно, он создает два раза одно и то же. Я также протестировал Matrixrandomizer, не включая его в мой вызов ржавчины, и он всегда создает другую матрицу.

Здесь вы можете увидеть мой код c.

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

int main (int argc, char* argv[]) {
    // Zufallszahlengenerator initialisieren
    srand(time(NULL));

    if(argc < 3) {
        printf("Es fehlen Argumente");
    }   
    char matrix[100] = "";

    int r, c;
    r = atoi(argv[1]);
    c = atoi(argv[2]);

    if(r > 0 && c > 0) {
        for(int i = 0; i < r; i++) {
            for(int j = 0; j < c; j++){
                if(j == c - 1) {
                    int test = (1+rand()%9);
                    char buffer[50];
                    sprintf(buffer, "%d", test);
                    strcat(matrix, buffer);
                    }
                if(j < c - 1){  
                    int test = (1+rand()%9);
                    char buffer[50];
                    sprintf(buffer, "%d", test);
                    strcat(matrix, buffer);
                    strcat(matrix, ",");    
                }

            }
            if(i != r - 1) {
                strcat(matrix, ";");
            }   
        }       
    }
    printf("%s", matrix);
}

Ответы [ 2 ]

1 голос
/ 27 октября 2019

srand хочет семя в качестве аргумента. Для данного семени случайная последовательность будет равна. Поэтому, если вы вызовете srand дважды за очень короткое время с аргументом time(NULL), велика вероятность, что вы дадите одно и то же начальное число.

Использование time(NULL) в качестве начального числа - хороший способ обеспечитьвыводить каждый раз, когда вы запускаете программу в обычных условиях. Но в этом случае вам нужно добавить что-то еще. Один из способов сделать это - добавить дополнительный аргумент для работы в качестве соли (терминология, заимствованная из хеширования) следующим образом:

int salt = atoi(argv[3]);
srand(time(NULL) + salt);

И затем убедитесь, что программа вызывается с другими аргументами, например:

./test 3 3 546

Здесь 546 - номер, который вы выбираете, и он должен отличаться для двух вызовов. И я бы порекомендовал сделать их совсем другими. Если они отличаются только на один, то вы можете столкнуться с той же проблемой, если между двумя вызовами произойдет смена секунд.

Еще один способ сделать это - использовать getpid() в качестве соли. Это может быть предпочтительным, если вы не хотите изменять количество аргументов, которые вы должны отправить в программу.

0 голосов
/ 27 октября 2019

Функция srand принимает seed в качестве аргумента. Для одного и того же начального числа генератор псевдослучайных чисел всегда будет обеспечивать одинаковую выходную последовательность. Существует минимальный временной шаг, который можно распознать в любой дискретной системе, такой как компьютеры. Следовательно, вызов /matrix ./test 3 3 "*" ./test 3 3 может происходить на меньшем временном шаге, что означает, что они происходят в одно и то же время, и time(NULL) возвращает то же самое время, то же самое начальное число, следовательно, ту же самую случайную последовательность и, следовательно, те же матрицы. Быстрое решение - попробовать srand(time(NULL) + getpid()) и #include <unistd.h> в системе POSIX или srand(time(NULL) + GetCurrentProcessId()) для систем Windows. Более сложное решение состоит в том, чтобы обеспечить солью вашим исходным семенем, соль - это, по сути, ценность, которая добавляется к семени. Однако, выбор значения соли - это совсем другая тема. Вы можете найти указатели для этого здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...