std::random_shuffle дает тот же результат, даже если srand(time(0)) вызывается один раз

В функции я хочу создать список чисел в диапазоне: (Эта функция будет вызываться только один раз при выполнении программы.)

void DataSet::finalize(double trainPercent, bool genValidData)
{
    srand(time(0));
    printf("%d\n", rand());

    // indices = {0, 1, 2, 3, 4, ..., m_train.size()-1}
    vector<size_t> indices(m_train.size());
    for (size_t i = 0; i < indices.size(); i++)
        indices[i] = i;

    random_shuffle(indices.begin(), indices.end());
// Output
    for (size_t i = 0; i < 10; i++)
        printf("%ld ", indices[i]);
    puts("");

}

Результаты такие:

850577673
246 239 7 102 41 201 288 23 1 237 

Через несколько секунд:

856981140
246 239 7 102 41 201 288 23 1 237 

И больше:

857552578
246 239 7 102 41 201 288 23 1 237

Почему функция rand() работает правильно, а `random_shuffle' нет?


person Dawei Yang    schedule 19.03.2014    source источник
comment
возможный дубликат Как убедиться, что std::random_shuffle всегда дает другой результат?   -  person Jonathon Reinhart    schedule 19.03.2014
comment
Вы должны вызывать srand() только один раз, в начале вашей программы. Также см. это и это   -  person Jonathon Reinhart    schedule 19.03.2014
comment
@JonathonReinhart, а не дубликат, потому что он однажды позвонил srand. Правильно?   -  person Paul Draper    schedule 19.03.2014
comment
@PaulDraper Один раз каждый раз запускал его. Кроме того, есть много других советов по этому вопросу и другим, которые я связал. Я могу отметить только один дубликат.   -  person Jonathon Reinhart    schedule 19.03.2014
comment
@JonathonReinhart Спасибо. Я прочитал совет. Но я не могу понять, почему rand() работает, а random_shuffle() не имеет никаких ассоциаций с srand().   -  person Dawei Yang    schedule 19.03.2014
comment
Я перемещаю вызов srand() в функцию main, но результаты аналогичны.   -  person Dawei Yang    schedule 19.03.2014
comment
Можете ли вы увидеть пример здесь: cplusplus.com/reference/algorithm/random_shuffle Я попробовал это, и каждый раз он дает мне другой вектор. И он использует srand().   -  person yasouser    schedule 19.03.2014
comment
@yasouser Да, это работает. Версия лямбда-выражения: random_shuffle(begin(indices), end(indices), [](int n) { return rand() % n; }); дает другой результат, но если я изменю свой генератор случайных чисел на default_random_engine(), тогда возникнут проблемы. Таким образом, возникает вопрос, почему default_random_engine() не работает.   -  person Dawei Yang    schedule 19.03.2014
comment
@YangDawei: я изменил образец, который я цитировал, чтобы распечатать вектор после вызова random_shuffle() со встроенным генератором случайных чисел. Он также каждый раз печатает разные вектора. Я использую MinGW g++ v4.8.1 для компиляции кода на компьютере с Windows.   -  person yasouser    schedule 19.03.2014


Ответы (1)


random_shuffle() на самом деле не указано для использования rand(), поэтому srand() может не иметь никакого значения. Если вы хотите быть уверенным, вы должны использовать одну из форм C++11, random_shuffle(b, e, RNG) или shuffle(b, e, uRNG).

Альтернативой может быть использование random_shuffle(indices.begin(), indices.end(), rand());, потому что, по-видимому, ваша реализация random_shuffle() не использует rand().

person Halfdane    schedule 19.03.2014
comment
Да, я заставляю random_shuffle использовать rand(), чтобы он работал правильно. Вместо random_shuffle(indices.begin(), indices.end(), rand()) я использую random_shuffle(begin(indices), end(indices), [](int n) { return rand() % n; }), потому что предыдущий выдает ошибки. Я использую cmake, установленный macports, с флагами CXX -std=c++11. Мой g++ - clang-500.2.79, но я не знаю, какой именно компилятор используется cmake. - person Dawei Yang; 19.03.2014
comment
@YangDawei: вы можете, например, message("${CMAKE_CXX_COMPILER}") в своем CMakeLists.txt узнать, какой компилятор используется. - person lisyarus; 19.03.2014