Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > генератор случайных чисел, помогите написать |
Автор: natusik86 20.6.2009, 14:59 |
Всем привет! Подскажите, как сгенерировать случайное число в некотором диапазоне (например, от-5 до 3; от 4 до 10 и т.п.), диапазон задается пользователем. |
Автор: azesmcar 20.6.2009, 15:03 | ||
|
Автор: Данкинг 20.6.2009, 15:03 |
http://forum.vingrad.ru/index.php?showtopic=20156&view=findpost&p=135732 |
Автор: natusik86 20.6.2009, 15:52 | ||||
Задаю диапазон от -5 до 3. В итоге генерируются только числа -5, -4 и -3 и никаких других не появляется. |
Автор: natusik86 20.6.2009, 16:36 |
А для диапазона от 3 до 7 получаются числа от 5 до 9. |
Автор: Irdis 20.6.2009, 17:42 |
не так не интересно... можно например таким образом берём системное время, делаем из него число, возводим в квадрат, берём 4 цифры от получившегося (из середины ,например), делаем из них число, возводим в куб берём 4 цифры и т. д. достаточное количество подобных операций позволит сделать генератор случайных чисел |
Автор: andrew_121 20.6.2009, 18:06 |
Irdis, Теоретически - да. |
Автор: DRUID3 20.6.2009, 18:31 | ||||
Но к сожалению не с заданными нам характеристиками - функция распределения, длинна случайной последовательности etc. Это будет уже генератор истинно-случайных чисел. ![]()
Вопрос в применении стандартных функций или Вы хотите написать свой ГСЧ? Различия принципиальные - как между биохимией и кулинарией. |
Автор: andrew_121 20.6.2009, 18:38 |
Наверное, все же ГПСЧ. |
Автор: DRUID3 20.6.2009, 18:41 |
![]() ![]() |
Автор: andrew_121 20.6.2009, 19:00 |
Любопытно увидеть его реализацию. И в действии посмотреть. Может кто-то набросает? Я не возьмусь, мат база не позволяет) |
Автор: Леопольд 20.6.2009, 19:03 | ||||||||
Потому что не вычисляется диапазон. По моему, это из алгебры... ![]()
|
Автор: W4FhLF 20.6.2009, 19:04 |
Вот ГСЧ на основе шумов из звуковой карты(ZOMG! Они есть!) - http://habrahabr.ru/blogs/python/62237/ |
Автор: andrew_121 20.6.2009, 19:10 |
W4FhLF, Да, знаю. Приходилось иметь с этим дело. Еще это использовал: http://www.random.org/bitmaps/ |
Автор: GoldFinch 20.6.2009, 19:20 | ||
полнейший бред, показывающий незнание теории. взяли системное время - там допустим 20.5 случайных бит, провели с ним любое количество операций, получили либо те же 20.5 бит, либо например 18.1 бит, т.к. что потеряли. |
Автор: Леопольд 20.6.2009, 20:17 | ||||
Вы уверенны? Сколько итераций провели для выяснения? ![]() rX - число полученное от генератора. 3 + r0 % 7 = 3 3 + r6 % 7 = 9 отрезок [3,9] а не [5,9] Пока считал, нашёл ошибку у себя, надо единичку добавить, а то не получается нужный отрезок. Следовательно, правильный алгоритм такой:
abs возвращает абсолютную величину числа, если припомнить алгебру то |-7| = |7| = 7. 3 + r0 % (|7 - 3| + 1) = 3 + 0 = 3 3 + r4 % (|7 - 3| + 1) = 3 + 4 = 7 3 + r6 % (|7 - 3| + 1) = 3 + 1 = 4 все числа в заданном отрезке. На всякий случай следует попробовать с отрицательным числом [-3,7]: -3 + r0 % (|7 - (-3)| + 1) = -3 + 0 = -3 -3 + r10 % (|7 - (-3)| + 1) = -3 + 10 = 7 -3 + r11 % (|7 - (-3)| + 1) = -3 + 1 = -2 Пробуем для отрезка [3,-7] 3 + r0 % (|-7 - 3)| + 1) = 3 + 0 = 3 3 + r10 % (|-7 - 3)| + 1) = 3 + 10 = 13 Увы и ах, не фурычит. Но можно сделать так, что-бы зафурычило, уверяю Вас, но оставлю и Вам маленько, извилины поразмять... |
Автор: Леопольд 21.6.2009, 10:08 | ||||
Ладно, не буду томить. Совсем правильный алгоритм, не зависящий от порядка такой:
Вот теперь, надо тестировать, хотя тесты лучше писать до кода ![]()
|
Автор: zim22 21.6.2009, 10:22 | ||||
у вас тесты не полные. проверяются только границы диапазона. посмотрите, что получится в этом случае: ![]()
*** и неплохо бы ГПСЧ запустить
|
Автор: Irdis 21.6.2009, 12:00 | ||||
скажем так, для нужд народного хозяйства моего метода хватит
полнейший бред |
Автор: GoldFinch 21.6.2009, 12:59 |
ок, обосную. Допустим мы получаем время с точностью до 1/1024 сек, интенсивность использования ГСЧ 1 Гц, тогда в идеальном случае мы имеем 10 случайных бит, распределение будем считать равномерным. Т.е. в среднем каждую секунду запрашивая время мы получаем число у которого младшие 10 двоичных разрядов заранее неизвестны (случайны), а старшие известны и постоянно увеличиваются. Тогда отбросив старшие разряды мы получаем случайное число которое может принять одно из 1024 значений, от 0 до 1023 Проведя с ним какуюто последовательность операций, мы для каждого конкретного числа x1 получаем какоето другое число y1=f(x1). Если для каждого x, y не повторяются, то информация не теряется, и мы для 1024 разных x получаем 1024 разных y. Если какието y повторяются, например 220 одинаковых, то мы для 1024 разных x получим 804 разных y, 9.651бит, - информация потеряется. И на в каком случае, мы не получим большее количество y чем x. литература: http://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D1%8D%D0%BD%D1%82%D1%80%D0%BE%D0%BF%D0%B8%D1%8F |
Автор: Irdis 21.6.2009, 17:55 |
убедительно, но всё таки: Если мы можем получить хотя бы один байт случайной информации то из них не трудно склепать 1Гб случайной информации. ко времени можно также прибавить другие изменяющиеся данные (зависит от фантазии) также добавить в формулу рекуррентные соотношения(тогда даже если время начнёт повторяться ![]() В любом случае это не полный бред. |
Автор: Леопольд 21.6.2009, 20:04 | ||||
На самом деле, такая функция даже не сгенерит ни бита бинарного кода, потому что она бессмысленна. Думаю, даже gcc оптимизатор не пропустит ![]() Вопрос был у человека, получать числа в заданном диапазоне. Т.е. значение, возвращаемое функцией rand_range не должно выходить за него. Будет совсем не то что надо... ![]() Генератор, думаю, надо инициализировать до вызова этой функции. |
Автор: zim22 21.6.2009, 20:34 | ||||
вы тесты зачем привели? чтобы проверить, что числа находятся в нужном диапазоне, правильно? я вам привёл пример, на котором ваши тесты бесполезны. смысл тогда от них? ![]()
так осмысленней?
|
Автор: natusik86 21.6.2009, 21:02 | ||
Я даже не думала, что мой вопрос вызовет столь бурное обсуждение. Вообще говоря, пока я ждала ответов, сумела сама написать функцию. Уж не знаю кому как, но у меня работает и мне достаточно.
|
Автор: codelord 21.6.2009, 22:44 | ||||||
А если так ![]()
|
Автор: Леопольд 22.6.2009, 07:34 | ||||
Смысл очень прост - requirements verification. Стоит задача, написать функцию возвращающую рандомное значение в заданном диапазоне, а не протестировать распределение функции std::rand. Не надо усложнять. Тесты я привёл для того что-бы показать natusik86 что функциональность надо тестировать. Но я обратил более пристальное внимание на тесты и понял что хватит трёх вместо всех тех.
|
Автор: Леопольд 22.6.2009, 08:14 | ||||||||||
Чем проще функция тем лучше. Кому как, а я бы воспользовался этим ![]()
А если так, то что получится для [1,0]? Попробуйте прогнать через это:
|
Автор: codelord 22.6.2009, 11:04 | ||
Леопольд, не надо через задницу задвавать диапазон, и если ты взял логику из моей функции дописал туда swap и удалил переменную и гордится этим ты облажался со своим abs он здесь не нужен.
вот этот вариант я имею ввиду. И не надо предлагать мне использовать твои кривые тесты, писать научись. |
Автор: Леопольд 22.6.2009, 12:17 | ||||||
"Надо Федя, надо." А если оторвёшь взгляд от себя любимого, то, возможно, заметишь что эту функцию я написал раньше. Но не я изобрел алгебру и потому никак не могу обвинить тебя в плагиате...
Вот abs не нужен, не спорю, но и ошибки он не вызавал, просто подтормаживал выполнение функции. Но мне не пришлось долго напрягаться что бы это выяснить. Я просто удалил его, когда появились сомнения, и прогнал через тесты. Т.е. мне теперь не надо долго думать, что же я написал, если тесты написанны достаточно п'олно и проверяют то что мне надо. Это их единственное предназначение. Ты же облажался со swap'ом. Я бы с интересом посмотрел как ты мою фукнцию "уронишь", как я твою. Может она в распределённых системах будет вызывать ошибку? ![]() Я (как автор функции) может и не задам кривой диапазон, некоторое время. А вот через год, или два, я, теоретически, сам стану юзером своей функции, и могу забыть что я не предусмотрел того что отрезок/диапазон можно задать и справа-налево, т.е. от большему к меньшему. Или надо программировать асболютно бездумно и не учитывать что на вход могут прийти не все reqirements в силу того что их автор мог просто упустить некоторые детали? А используя свои "кривые" тесты, я значительно ускорю любое изменение. Причём, можно эти тесты подцепить к assert или к #define DEBUG. Этакий unitary testing.
Почему "кривые"? Хотелось бы услышать какое-то обоснование а не голословный тявк. Если можешь написать, то напиши "ровные", а если не можешь то просто промолчи, это лучше чем тявкать на "кривые". И съёшь что-то от "озверина", например "мышьяк" ![]() Как заключение, я не хотел бы работать с таким самодовольным типом как ты в одной команде. |
Автор: codelord 22.6.2009, 12:47 | ||||||||||
ты написал, но не то, еще раз говорю. Ты понял фишку которую увидел только в коде, который появился позже.
Ты его удалил когда увидел код который предложил я позже,.
тут не нужен swap, тут нужно иметь голову, и ни одному человеку не придет в голову ввести в параметры там где from to, значения наоборот, если ты этого не способен понять , я не буду тебе это объяснять.
Твои тесты кривы как минимум по манере их написания, это коостылеобразный код не спутаешь ни с чем. если ты вырастешь из этго кода вернись и посмотри на него может и поймешь, объяснять не собираюсь, можешь вывести на голосование и увидешь результат.
|
Автор: system 22.6.2009, 13:00 |
по моему это нужно сделать тебе. ![]() |
Автор: Леопольд 22.6.2009, 13:15 | ||||||||||
Мда... Очевидно я вернулся назад во времени...
Ничего не напоминает? Интересно, ты называешь фишкой алгебру? Конечно, ты велик и могуч, если бы не ты, я бы не знал алгебру, по любому. Уверен, работать с тобой, мало удовольствия... ![]()
Да ты, батюшка, предсказуем как три копейки... Можешь только тявкать на людей, но не объяснять. Рад что не работаю с тобой. ![]() Я знаешь ли не тестер, и на плюсах не писал серьёзного софта, изучаю потихоньку, а работать, к сожалению приходистя на другом... Причём тот язык гораздо слабже С, несравнимо, я бы сказал. Мне, для обучения, этих костылей из С++ пока хватает, они будут делать то что мне надо. Результаты голосования и меряния с тобой пиписьками меня абсолютно не интересуют. Меня интересует правильный способ тестирования. Ты меня, конечно, очень расстроил, но, знаешь ли, ты не один, кто знает алгебру или тестирование... А уж для того что бы протестировать код natusik86 эти тесты точно подойдут. И самое главное, она их поймёт! Но это расходится с твоими принципами... Добавлено @ 13:21
Я зверею только когда мне хамят. Не беси меня!!! ![]() А вообще, мне всегда казалось что подобные форумы нужны для того, что-бы обмениваться мнениями а не поливать друг-друга грязью. Но так кажется явно не всем... |
Автор: azesmcar 22.6.2009, 13:47 | ||
Развели спор на несколько страниц..вообще это я первым написал функцию rand_range и НЕ БЕСИТЕ МЕНЯ!!! ![]() Отныне все кто будет писать функцию и назовет ее rand_range должен спрашивать у меня авторские права ![]() читать как "я не тестер, но хочу им стать"?
А вам не кажется что топикстартеру это тестирование как трамваю шоколадка? |
Автор: Леопольд 22.6.2009, 14:13 | ||||
Я хочу тестировать правильно и хорошо свой код, а не чужой. Хотя, иногда, когда не уверен в чужом коде, быстрее протестировать его самому... Скорее всего она уже сюда не заглянет. Если только шоколадкой поманить... ![]() Я восстанавливал справедливость!!! ![]() |
Автор: zim22 22.6.2009, 14:17 |
я не понял, что вы хотели сказать этой фразой. уточните пожалуйста. 1) вы свой код тестируете правильно и хорошо, а сюда выложили "каку" - т.к. код чужой, а вы для него только функциональный тест написали. 2) что вам мешает тестировать "правильно", "чудесно", "обаятельно" и "хорошо"? ![]() |
Автор: Леопольд 22.6.2009, 15:12 | ||||
Я ответил на вопрос
Я выложил сюда то, как я стал бы тестировать сейчас если бы это было моя функция, потому что по другому не умею, пока. Я с большим интересом взглянул бы на Ваши тесты. А вообще, считаю правильным объясняться с людьми на их уровне понимания, когда возможно. Если они не используют в коде стандартную библиотеку, то маловерятно, что они будут переписывать уже написанный код. Правда следует учитывать что узнать что делают функции swap, abs не так сложно, как, например, bind2nd в списке аргументов transform. Рассуждать я могу только основываясь на том, сколько времени я сам потратил на понимание этих функций. На swap ушло гораздо меньше... |
Автор: system 22.6.2009, 15:13 |
жаль не могу поставить тебе минус, а так хочется ![]() |
Автор: zim22 22.6.2009, 16:25 | ||
а смысл? вот пример тестов Гугла. я раньше CPPUNIT использовал, сейчас в GoogleTest разбираюсь ![]()
|
Автор: Леопольд 22.6.2009, 16:37 | ||
Не находите что мои "кривые" тесты, гораздо понятнее новичку? ![]() |
Автор: zim22 22.6.2009, 16:57 | ||
согласен. мне они даже симпатичны ![]() единственное, я бы добавил в тесты проверку на генерацию всех чисел из диапазона
|
Автор: Леопольд 22.6.2009, 20:59 |
Я думал об этом, но мне это показалось лишним для данной задачи. Её скорее всего интересовал именно диапазон а не качество ГПСЧ. Мне показалось что она не пишет генератор, а просто пользуется библиотечным. ![]() CPPUNIT стоящая вещь? Как считаете, окупится время, потраченное не неё? |
Автор: zim22 23.6.2009, 08:28 |
попробовать поработать с ней стоит. а потом уже сами решите, что для вас лучше. |