C ++ генерирует одинаковый случайный результат [дубликат]

Я столкнулся с этим сегодня, с модальным position: fixed, который я использовал повторно. Я не смог сохранить его display: none, а затем оживить его, поскольку он просто вскочил на внешний вид, а также z-index (отрицательные значения и т. Д.) Тоже сделали странные вещи.

Я также использовал height: 0 до height: 100%, но он работал только тогда, когда появился модальный. Это то же самое, что если вы использовали left: -100% или что-то в этом роде.

Тогда мне показалось, что был простой ответ. Et voila:

Во-первых, ваш скрытый модальный. Обратите внимание, что height есть 0, и проверьте декларацию height в переходах ... у него есть 500ms, , который длиннее моего opacity перехода . Помните, что это влияет на переход к постепенному исчезновению: возвращение модального состояния в состояние по умолчанию.

#modal-overlay {
    background: #999;
    background: rgba(33,33,33,.2);
    display: block;
    overflow: hidden;
    height: 0;
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    opacity: 0;
    z-index: 1;
    -webkit-transition: height 0s 500ms, opacity 300ms ease-in-out;
       -moz-transition: height 0s 500ms, opacity 300ms ease-in-out;
            -ms-transition: height 0s 500ms, opacity 300ms ease-in-out;
         -o-transition: height 0s 500ms, opacity 300ms ease-in-out;
        transition: height 0s 500ms, opacity 300ms ease-in-out;
}

Во-вторых, ваш видимый модальный. Предположим, вы устанавливаете .modal-active на body. Теперь height - 100%, и мой переход также изменился. Я хочу, чтобы height был немедленно изменен, а opacity - 300ms.

.modal-active #modal-overlay {
    height: 100%;
    opacity: 1;
    z-index: 90000;
    -webkit-transition: height 0s, opacity 300ms ease-in-out;
       -moz-transition: height 0s, opacity 300ms ease-in-out;
        -ms-transition: height 0s, opacity 300ms ease-in-out;
         -o-transition: height 0s, opacity 300ms ease-in-out;
            transition: height 0s, opacity 300ms ease-in-out;
}

Вот и все, это работает как прелесть.

0
задан Anwesha 14 October 2015 в 17:23
поделиться

2 ответа

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

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

Обычно генераторы случайных чисел имеют внутренний значение, которое они ставят через алгоритм, и то, что алгоритм выплевывает, - это то, что они возвращают для случайного числа. Затем это число сохраняется для следующей итерации алгоритма. Так мы получаем случайную последовательность.

Если мы используем одно и то же семя, мы получим одну и ту же последовательность вывода, начиная с того же числа. В вашем случае ваше семя будет меняться каждый раз, когда chrono::steady_clock::now() продвигается, и ваш цикл работает быстрее, чем вы, чтобы вы получали одно и то же время (семя) для каждого вызова.

6
ответ дан NathanOliver 24 August 2018 в 04:41
поделиться

Одна важная вещь, чтобы знать о генераторах псевдослучайных чисел, состоит в том, что они производят последовательность чисел, а «случайность» - это качество, для которого проверяется последовательность . То есть вы не можете сказать, что конкретное число является случайным или нет ( есть «4» случайное число? ). Вместо этого вы говорите, является ли последовательность чисел случайной или нет.

Когда вы «засеиваете» pRNG, вы обычно выбираете одну из последовательностей, которые она может генерировать, и эти числа являются случайными по отношению к остальной части последовательность. Поэтому, если вы хотите «случайность», вы хотите сначала выбрать определенную последовательность, а затем использовать последовательные числа из этой конкретной случайной последовательности.

В вашем коде без static вы выбираете последовательность на каждой итерации цикла, а затем используя одно число из этой последовательности. Поскольку вы не используете много значений из одной и той же последовательности, не удивительно, что результат не выглядит случайным.

Когда вы добавляете static, двигатель больше не высевается на каждой итерации петля. Вместо этого он высевается один раз, и каждая итерация цикла использует последовательные значения из этой последовательности, как и вы должны делать. И это означает, что static означает переменные с ограниченным блоком: это означает, что переменная живет извне к блоку, в котором он объявлен, и что он будет инициализирован только в первый раз.

static исправляет ваши проблема, однако я бы сказал, что это нехорошее решение. static имеют некоторое сходство с глобальными переменными и вызывают некоторые из тех же проблем. Вместо этого я бы рекомендовал вам явно перемещать двигатель за пределы цикла. Например:

int random (int lim, default_random_engine &dre)
{
    uniform_int_distribution<> uid(1,lim);
    return uid(dre);
}

int main()
{
    default_random_engine dre (chrono::steady_clock::now().time_since_epoch().count());

    for (int i = 0; i < 10; ++i)
    {
        cout << random(100, dre) << " ";
    }
}

Теперь состояние явно управляется и передается в функцию random(), что лучше, чем полагаться на скрытое и неявное поведение переменной static с блочным диапазоном


Также в целом я бы не рекомендовал использовать время как единственный источник данных семян. Часы с низким разрешением могут не обеспечивать новые семена достаточно часто, и программа, выполняемая в разных местах одновременно, может использовать одно и то же семя.

Моя рекомендация для посева:

std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);

(Нет необходимости, чтобы новички знали, что такое mt19937 или любой другой бит. Они просто должны знать, чтобы вставить это в соответствующее место и как использовать eng. В вашем коде вам нужно будет замените каждое использование default_random_engine на mt19937.)

1
ответ дан bames53 24 August 2018 в 04:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: