LINUX.ORG.RU

Рандом при каждом запуске выводит одинаковое значение

 


0

1

#include <iostream>
#include <random>
using namespace std;


int main()
{
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<int> uid(0, 50);
    cout << uid(gen) << endl;//При каждом запуске выводит одинаковое значение
    return 0;
}

На какой системе и компиляторе это всё творится? Запустите под strace, поищите ошибки доступа к urandom (у меня эта программа открывает urandom и успешно выводит разные числа при разных запусках), системного вызова getrandom (Linux), getentropy (OpenBSD) или ещё какого-то.

anonymous ()
Ответ на: комментарий от I-Love-Microsoft

Я ХЗ как это сделано, но в интернетах пишутЬ что рандом_генератор юзает реальную энтропию (нажатия клавиш, всякий шум от проца и пр) - но на некоторых системах не работает.

А сид или его аналог должен быть в mt19937

AntonI ()

Насколько я знаю, стандарт не запрещает такое поведение. Можно указать некий «токен», который зависит от реализации, например random_device rd("/dev/random"), токен, который имеет смысл на некоторых системах

anonymous ()

Рандом вроде как и должен выдавать одинаковое значение при каждом запуске софтины на одном и том же железе. Обусловлено принципом генерации - это псевдослучайные числа.

Если нужен совсем совсем рандом - там плясать нужно с кодом, а не просто штатный рандомизатор сгенерить.

Столкнулся с этим еще лет 15 назад, когда впервые в делфи рандомом число генерил и каждый раз одно и тоже получал.

Zhbert ★★★★★ ()
Последнее исправление: Zhbert (всего исправлений: 1)

https://en.cppreference.com/w/cpp/numeric/random/random_device

Как тут уже ответили это баг в компиляторе.

Чинить уже сказали как, инициализировать генератор не одним rd(), а несколькими источниками случайности.

#include <iostream>
#include <random>
#include <ctime>
using namespace std;


int main(int, char const* argv[])
{
    random_device rd;
    mt19937 gen(rd()+(unsigned)argv + (unsigned)time(nullptr));
    uniform_int_distribution<int> uid(0, 50);
    cout << uid(gen) << endl;
}
fsb4000 ★★★★ ()

Мало того что это бажный функционал, так еще толком ни под какие платформы он и не работает кроме линукса на clang++/g++ от 6 версии и компилятор icc, еще под arm на g++. Все остальные платформы из того что есть на godbolt не переваривают такой код. Дергай старые функционал из С или пользуйся boost/qt. У boost реализация подозрительно похожа на std, видимо кто-то у кого-то слизал код.

anonymous ()

Прочитайте https://codingnest.com/generating-random-numbers-using-c-standard-library-the-problems/. Там описано устройство всех трёх ходовых реализаций (ms, gnu, libc++). TLDR:

std::random_device might not be random, and there is no way to check

d_a ★★★★★ ()
Последнее исправление: d_a (всего исправлений: 1)
Ответ на: комментарий от anonymous

так еще толком ни под какие платформы он и не работает кроме линукса на clang++/g++ от 6 версии и компилятор icc,

Норкоман?

>cl.exe /EHsc 15852205.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.20.27508.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

15852205.cpp
Microsoft (R) Incremental Linker Version 14.20.27508.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:15852205.exe
15852205.obj

>type 15852205.cpp
#include <iostream>
#include <random>
using namespace std;


int main()
{
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<int> uid(0, 50);
    cout << uid(gen) << endl;
    return 0;
}
LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

да msvc тоже работает вроде судя по godbolt, просто опустил этот момент в виду того, что не удалось от msvc на godbolt получить именно вывода работы, хотя собирает он без ошибок. У тебя не вижу результатов работы, так что наркоман тут ты, а не я. Собрать не значит получить корректную программу, в общем-то молодец что побежал проверять, теперь еще вывод дай, хотя можешь не давать, исходя из того что эта часть stdlib описана в документации от ms, скорее всего все работает как надо.

Сlang armv7-a например не работает, avr не работает, misp не работает, arduino uno/mega не работает, то есть по факту половина компиляторов под половину представленных платформ с этим кодом не будут работать, разве что со сторонней реализацией в виде boost или qt или дописывание нужных реализаций самому, кому это надо если можно просто получить тоже самое сторонней библиотекой или как удовлетворится тс генерацией на основе таймера, тогда уж можно было и просто пару srand, rand взять и не мучить жопу.

anonymous ()
Ответ на: комментарий от invy

он это знает прекрасно, это был просто пример того чем можно заменить объект генерирующий случайную последовательность. Странно что ТС удовлетворился этим ответом.

anonymous ()