Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> random и остаток от деления 
V
    Опции темы
borisbn
Дата 29.4.2014, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Здравствуйте.

Недавно на СОшке мне посоветовали делать не так:
Код
rand() % N;

а так
Код
rand() / (double)RAND_MAX * N;

Где-то ещё встречал аналогичный совет.

Вопрос: посоветуйте, пожалуйста, где почитать про разницу, про то, почему второе лучше, и т.д.

Спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Static
Дата 29.4.2014, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: 1
Всего: 2



Второе равномернее.
В этом дурацком треде можно видеть разницу наглядно.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
borisbn
Дата 29.4.2014, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Static, Спасибо. Тред и правда немного дурацкий)) Но..
1) впечатлила эта картинка
user posted image
2) то, что распределение менее равномерное при остатке от деления, я, в общем-то, догадывался, но вот почему - главный для меня вопрос - я пока не пойму.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
baldman88
Дата 29.4.2014, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 3
Всего: 7



Насколько мне помниться из разъяснений преподавателя, то генераторы псевдослучайных чисел работают по определенному алгоритму (ну это понятно), и соответственно периодичность повторения значений младших битов выше, чем старших. Остаток от деления как раз и берет значения этих младших битов. В противовес операция деления, которая хоть и более ресурсоемка, вследствии использования чисел с плавающей точкой, но зависит от значения старших битов. Как следствие более высокая, так сказать, псевдослучайность.
На полноту ответа не претендую, но суть, думаю, уловить можно.
PM MAIL   Вверх
borisbn
Дата 29.4.2014, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



> соответственно периодичность повторения значений младших битов выше, чем старших
Вот как-то для меня не "соответственно"...
Интуитивно мне понятно, что старшие биты "лучше", чем младшие, но почему (ключевое слово) - не понятно


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
baldman88
Дата 29.4.2014, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 3
Всего: 7



Если на пальцах, иначе ничего не приходит в голову, то когда используется операция получения остатка, то старшие биты просто отсекаются. То есть вероятность получения псевдослучайного числа определяется делителем (например, если делитель равен 10, то вероятность получения любого из чисел в диапазоне от 0 до 9 будет 1/10).
Когда мы используем деление, то на результат влияет весь диапазон от 0 до RANDOM_MAX. Понятно, что дальше все это усекается, но согласитесь, что вероятность выпадения одного числа из, допустим, 32768 много меньше чем для одного из 10. Ну а чем меньше вероятность, тем выше случайность. Как-то так ...
PM MAIL   Вверх
borisbn
Дата 30.4.2014, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(baldman88 @  29.4.2014,  23:19 Найти цитируемый пост)
вероятность получения псевдослучайного числа определяется делителем (например, если делитель равен 10, то вероятность получения любого из чисел в диапазоне от 0 до 9 будет 1/10).

В
Код
rand() / (double)RAND_MAX * N

при N, равном 10, вероятность получения любого целого числа от 0 до 9 будет также 1/10. Однако в случае остатка от деления распределение этой самой вероятности явно отличается от варианта с приведением к диапазону от 0 до 1, умножением на N и отбрасыванием дробной части. Вот откуда берётся отличие в распределении вероятности мне и не понятно.

Цитата(baldman88 @  29.4.2014,  18:58 Найти цитируемый пост)
операция деления, которая хоть и более ресурсоемка,

при вычислении остатка от деления также используется деление)) Правда целочисленное, но всё же... Да и потом - вопрос, ессно, не в затратах процессора, а в разности полученных результатов

Это сообщение отредактировал(а) borisbn - 30.4.2014, 08:53


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
vinter
Дата 30.4.2014, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



отсюда начался крестовый поход против rand(). Насколько я помню, Стефан объясняет в чем проблема.
Тут дискуссия. Ну и еще одна ссылка


--------------------
Мой блог
PM MAIL WWW   Вверх
borisbn
Дата 2.5.2014, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



vinter, спасибо. Крайне полезные ссылки. Но больше всего мне стало понятно из ответа господина dr jimbob на SO
Цитата
With 64-bit ints and using 100 numbers as output, the numbers 0-16 are represented with 1.00000000000000000455 % of the numbers (an relative accuracy to identically distributed of 1% by about 10-18), while the numbers 17-99 are represented with 0.99999999999999999913 % of the numbers. Yes, not perfectly distributed, but a very good approximation for small spans.

Насколько я понял - проблема не в операции остатка от деления, а в конкретной реализации функции rand(). Правильно ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
vinter
Дата 2.5.2014, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



borisbn, наоборот, проблема в манипуляциях над тем, что возвращает rand(). В нём самом нет проблемы. В видео объясняется, с примерами, почему существует проблема. К примеру, когда ты делишь(%) на 100 результат rand()  у тебя получается следующая ситуация. Некоторые числа более вероятны, т.к. 32767 не делится нацело на 100. Поэтому, к примеру, появление чисел от 67 до 99 имеет меньшую вероятность, чем от 0 до 67. Вроде так.


--------------------
Мой блог
PM MAIL WWW   Вверх
borisbn
Дата 3.5.2014, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



vinter, ещё раз спасибо. Я не посмотрел видео, а надо было. Насколько я понял если брать остаток от деления на 2^x, то распределение останется нормальным, т.к. максимальное число, возвращаемое rand'ом как раз является степенью двойки. Во всех остальных случаях распределение изменяется. Правильно?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
vinter
Дата 3.5.2014, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



borisbn, да, насколько я понимаю. По крайней мере я не вижу каких-либо проблем если использовать rand() mod 2^x


--------------------
Мой блог
PM MAIL WWW   Вверх
vinter
Дата 3.5.2014, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



точнее не совсем. Всё таки небольшой минус даже в таком подходе есть. Т.к. нумерация начинается с 0, то RAND_MAX всё равно не будет делится на 2^x, а это даст небольшое преимущество некоторым числам.


--------------------
Мой блог
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1153 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.