Название: Random в Qt Отправлено: splpwn от Мая 08, 2012, 17:30 Добрый вечер, друзья.
Подскажите. Как реализовать случайную выборку из фиксированного набора чисел без повторений? Название: Re: Random в QT Отправлено: kambala от Мая 08, 2012, 17:50 qrand(), QSet или QHash. хотя не совсем понятно зачем тут использовать Qt - STL будет вполне достаточно.
Название: Re: Random в QT Отправлено: splpwn от Мая 08, 2012, 18:09 Непонятно, приведите пример с тремя числами без повторений пожалуйста.
Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 18:17 Непонятно, приведите пример с тремя числами без повторений пожалуйста. Вот например банальный пример:Код
Название: Re: Random в QT Отправлено: Igors от Мая 08, 2012, 18:35 Код
Вот например банальный пример: Не много ли он жрет ресурсов?Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 19:04 Так написал-же банальный пример, а не высокопроизводительный идеальный =). Я даже мозг не включал, его жара плавит =(, хочу кондиционер...
Только я что-то не понял в твоем алгоритме: Первым я выбрал количество чисел: 4, дальше указал число выбираемых чисел: 3, дальше указывал номер выбираемого числа, но что то в результате получил 0, 0, 1. С какого оно повторило 0, да в алгоритм не вникал, лениво =). Код
Название: Re: Random в QT Отправлено: kambala от Мая 08, 2012, 19:08 Непонятно, приведите пример с тремя числами без повторений пожалуйста. Код пользуемся тем, что все элементы QSet уникальны. считаем, что src.size() > n, иначе в коде нет особого смысла. если использовать QHash вместо QSet, то можно ещё индекс сохранять. ну так попросили же пример на Qt :D Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 19:18 Код пользуемся тем, что все элементы QSet уникальны. считаем, что src.size() > n, иначе в коде нет особого смысла. если использовать QHash вместо QSet, то можно ещё индекс сохранять. Название: Re: Random в QT Отправлено: Igors от Мая 08, 2012, 19:29 да в алгоритм не вникал, лениво =). Там я сначала перепутал деление, должно быть * limit / numSel; (как сейчас)пользуемся тем, что все элементы QSet уникальны. считаем, что src.size() > n, И что будет для выборки 3 элементов из исходных (7, 7, 7, 1) ? Также никто не говорил что можно менять порядок следованияну так попросили же пример на Qt :D Стремление задействовать как можно больше "мощных тулзлов" и написать "как можно короче" выдает начинающего с головой :)Ладно, вот более интересная задачка на ту же тему. Все то же самое + доп условия - исходный массив отсортирован (выборка тоже должна быть сортирована) - разница между любыми 2 соседними значениями выборки не должна быть меньше заданного N Название: Re: Random в QT Отправлено: Igors от Мая 08, 2012, 19:33 Мой банальный тупой алгоритм отработал за 1-2 секунды. А твой пришлось прибить после 15 секунд, лень дальше ждать =). Вспомнился старый мультфильм в котором (кажется) мышонок на пне под гитару пел что-то типаЦитировать какой хороший Я :)и песенка моя Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 19:42 Вспомнился старый мультфильм в котором (кажется) мышонок на пне под гитару пел что-то типа Да ладно, что лулзы нельзя уже половить =). Я как увидел цикл с неопределенным количеством итераций, так не удержался. Цитировать какой хороший Я :)и песенка моя Ты свой алгоритм тестировал? У меня тоже самое 0 0 1. Название: Re: Random в QT Отправлено: Igors от Мая 08, 2012, 20:00 Ты свой алгоритм тестировал? У меня тоже самое 0 0 1. То у Вас с copy/paste проблемы, у меня все норм (0, 1, 3) или (0, 1, 2)Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 20:12 Ты свой алгоритм тестировал? У меня тоже самое 0 0 1. То у Вас с copy/paste проблемы, у меня все норм (0, 1, 3) или (0, 1, 2)Название: Re: Random в QT Отправлено: Igors от Мая 08, 2012, 20:46 Да действительно. Теперь другая проблема, нам нужны случайные числа, а в твоем алгоритме у меня постоянно первым 0 идет. Я что-то не догоняю смысла алгоритма. Елы-палы, что ж тут "не догнать"? Делим на примерно равные интервалы, из каждого выбираем случайное число.По поводу первого нуля. Во-первых взять число элементов побольше напр не 4 а 24. А во-вторых да, что-то у них с qrand - первое возвращаемое всегда маленькое если привести к [0..1]. Поэтому лучше использовать остаток от деления (исправил) Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 20:56 Да действительно. Теперь другая проблема, нам нужны случайные числа, а в твоем алгоритме у меня постоянно первым 0 идет. Я что-то не догоняю смысла алгоритма. Елы-палы, что ж тут "не догнать"? Делим на примерно равные интервалы, из каждого выбираем случайное число.По поводу первого нуля. Во-первых взять число элементов побольше напр не 4 а 24. А во-вторых да, что-то у них с qrand - первое возвращаемое всегда маленькое если привести к [0..1]. Поэтому лучше использовать остаток от деления (исправил) Название: Re: Random в QT Отправлено: m_ax от Мая 08, 2012, 21:19 генератор случайных уникальных чисел (весьма известный пример):
Код
Название: Re: Random в QT Отправлено: Igors от Мая 08, 2012, 21:24 Это получается не очень и случайные числа. При 3 из 4 первым числом будет либо 1(1 вариант из RAND_MAX) либо 0. Ну явно не годится. Работать должно на любых числах. Я думаю ему в идеале нужны все числа из диапазона но в случайном порядке. Такая выборка называется stratified (типа "слоистая"). Как правило порядок следования должен быть сохранен. Если по каким-то причинам нужно наоборот, это решается перемешиванием исходных данныхКод
Название: Re: Random в QT Отправлено: Igors от Мая 08, 2012, 21:44 генератор случайных уникальных чисел (весьма известный пример): Я так вижу что когда человек писал "это" он хотел показать себя грамотным- operator () - владение STL - private (мол, хороший тон) Но вот о том как это работает - ни хрена он не думал. - создание доп контейнера и операции с ним (совсем недешевые) - сколько же потребуется qrand() чтобы в конце-концов попасть на последний элемент из 1000? Поэтому сколько "синтаксического сахара" не добавляй - говнокод остается говнокодом :) Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 21:52 Как правило порядок следования должен быть сохранен. Как условие диктует так и надо =). В данном случае нужно случайное значение =). А если как "правило", то вообще можно попробовать взять полином и замутить псевдо-случайную последовательность =).Название: Re: Random в QT Отправлено: m_ax от Мая 08, 2012, 22:02 генератор случайных уникальных чисел (весьма известный пример): Я так вижу что когда человек писал "это" он хотел показать себя грамотным- operator () - владение STL - private (мол, хороший тон) Но вот о том как это работает - ни хрена он не думал. - создание доп контейнера и операции с ним (совсем недешевые) - сколько же потребуется qrand() чтобы в конце-концов попасть на последний элемент из 1000? Поэтому сколько "синтаксического сахара" не добавляй - говнокод остается говнокодом :) Или вы как то по другому представляете себе генератор уникальных (не повторяющихся) чисел? Квази не повторяющихся? А rand можно заменить на что-нить более быстрое.. Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 22:25 Или вы как то по другому представляете себе генератор уникальных (не повторяющихся) чисел? Квази не повторяющихся? Я пока что вижу два выхода: либо использовать список, либо полиномы. Правда насколько производительным будет вариант на полиномах...Название: Re: Random в QT Отправлено: m_ax от Мая 08, 2012, 22:28 Или вы как то по другому представляете себе генератор уникальных (не повторяющихся) чисел? Квази не повторяющихся? Я пока что вижу два выхода: либо использовать список, либо полиномы. Правда насколько производительным будет вариант на полиномах...Вариант с URandGen на самом деле не очень хорош, с точки зрения производительности и т.д, как заметил igors, но это всего лишь пример.. Название: Re: Random в QT Отправлено: V1KT0P от Мая 08, 2012, 23:09 На полиномах это как? Смысл строится регистр на основе полинома с несколькими обратными связями. Через определенный период(когда все варианты числ закончатся) последовательность будет повторяться. Но нам то как раз и нужно из определенного количества выбрать случайные числа. Тут просто в начале надо случайно выбрать обратные связи.Вариант с URandGen на самом деле не очень хорош, с точки зрения производительности и т.д, как заметил igors, но это всего лишь пример.. В общем это из схемотехники, там это все красиво, а вот как это на С++ будет выглядеть... Название: Re: Random в QT Отправлено: Igors от Мая 09, 2012, 10:52 Или вы как то по другому представляете себе генератор уникальных (не повторяющихся) чисел? Квази не повторяющихся? Ну а почему бы просто не создать массив последовательных чисел, перемешать его и брать подряд из перемешанного? Минус - хранение доп массива, пусть на порядок дешевле std::set. Если это не устраивает по памяти - придется читать теорию.Как условие диктует так и надо =). В данном случае нужно случайное значение =). Если порядок не важен, то, как уже говорилось, мешаем массив - и все делаА если как "правило", то вообще можно попробовать взять полином и замутить псевдо-случайную последовательность =). "Случайные числа" и "случайная последовательность" - это 2 большие разницы :) Как раз последовательность гарантирует что не будет чисел слишком близких друг к другу. Статейку про "полиномы" лучше спрячьте - ее писал лох который не удосужился открыть книжки.Название: Re: Random в QT Отправлено: splpwn от Мая 09, 2012, 11:55 Код Почему то всегда одинаковую последовательность выдаёт. Название: Re: Random в QT Отправлено: m_ax от Мая 09, 2012, 12:30 Цитировать Ну а почему бы просто не создать массив последовательных чисел, перемешать его и брать подряд из перемешанного? Да. пожалуй, так..Вот пример: Код
Код
Название: Re: Random в QT Отправлено: Igors от Мая 09, 2012, 13:17 Ну static счетчик не годится - тогда 2 экземпляра заклинят. А вот массив объявить static - есть смысл.
Также цыганщина с оператором () здесь ни к чему, гибче так Код
Название: Re: Random в QT Отправлено: V1KT0P от Мая 09, 2012, 13:27 "Случайные числа" и "случайная последовательность" - это 2 большие разницы :) Как раз последовательность гарантирует что не будет чисел слишком близких друг к другу. Статейку про "полиномы" лучше спрячьте - ее писал лох который не удосужился открыть книжки. Да ничего не гарантирует, что в случайных чисел что в случайной последовательности могут попадаться моменты когда несколько чисел будут идти подряд, ибо случайность =). Даже если взять какой-нибудь идеальный генератор случайных чисел, есть вероятность что он выдаст несколько раз одно и то-же значение. Вероятность конечно будет нереально мала, но все-таки она есть =).Вот твой алгоритм делит на части и из частей вытягивает числа. Тогда проверим насколько он хорош. Возьмем 16 значений из которых нужно взять 4-ре. Получается что твой алгоритм будет выдавать 1 из 256 вариантов. Тогда как тот-же тупой алгоритм со списком будет выдавать 1 из 43680 вариантов. Согласись разница слишком большая. Представим что автор темы хочет применить алгоритм в игре, тогда получится что с твоим алгоритмом будет много повторов, а некоторые комбинации(которых много) вообще небудет. А если автор попробует использовать в шифровании, то на твоем алгоритме он станет очень уязвимым =). Название: Re: Random в QT Отправлено: m_ax от Мая 09, 2012, 13:30 Цитировать Также цыганщина с оператором () здесь ни к чему, гибче так Это не цыганщина, скорее дело вкуса. Плюс ко всему, с оператором() объект этого класса можно будет использовать в stl алгоритмах, например std::generate и т.д. Название: Re: Random в QT Отправлено: Igors от Мая 09, 2012, 15:02 Да ничего не гарантирует, что в случайных чисел что в случайной последовательности могут попадаться моменты когда несколько чисел будут идти подряд, ибо случайность =). Даже если взять какой-нибудь идеальный генератор случайных чисел, есть вероятность что он выдаст несколько раз одно и то-же значение. Вероятность конечно будет нереально мала, но все-таки она есть =). Если какой-то генератор выдает случайные числа одно за одним - это еще не имеет никакого отношения к "последовательности случайных чисел" - то своя песня, если интересно разгуглите. Вот твой алгоритм делит на части и из частей вытягивает числа. Тогда проверим насколько он хорош. Возьмем 16 значений из которых нужно взять 4-ре. Получается что твой алгоритм будет выдавать 1 из 256 вариантов. Тогда как тот-же тупой алгоритм со списком будет выдавать 1 из 43680 вариантов. Согласись разница слишком большая. А кто сказал что требования именно такие? Они могут быть (и часто бывают) совсем другими. Напр ф-ция описана 16 значениями, но можем хранить только 4. Как ни странно, взять просто "каждое 4-е значение" оказывается плохо :)По поводу "тупо - это хорошо". Прикинем во что обойдется резвое removeAt всего на 10k элементов 10.000 / 2 = 5.000 Т.е. чтобы получить 1 случайное число смувили в среднем 5 тысяч int, перекачали 20k байт. Что Вы можете сказать о технике и классе программиста предложившего такое решение? :) Название: Re: Random в QT Отправлено: V1KT0P от Мая 09, 2012, 15:13 Т.е. чтобы получить 1 случайное число смувили в среднем 5 тысяч int, перекачали 20k байт. Что Вы можете сказать о технике и классе программиста предложившего такое решение? :) Ну так приведи код которые делает это лучше, быстрее, требует памяти памяти. Но с условием что вероятность выпадения всех последовательностей одинакова, и алгоритм обеспечивает появление всех комбинаций. Вот когда покажешь тогда и послушаю.Но только не оптимизируй тот тупой алгоритм, я и так знаю что там можно очень сильно оптимизировать. Например можно устранить тасовку памяти используя связный список, при чем введя кое-какие оптимизации поиск по связному списку можно очень сильно сократить за счет увеличения потребления памяти на несколько процентов. Предложи свой алгоритм который не уступает по свойствам тупому =). Название: Re: Random в QT Отправлено: Igors от Мая 09, 2012, 15:40 Предложи свой алгоритм который не уступает по свойствам тупому =). "Свой" здесь неуместно, все это вещи известные. Как достичь "той же тупизны" уже дважды приводилось (в постах #16 и #25). Ладно, еще разКод Вы уж сравните с Вашим по скорости :) Название: Re: Random в QT Отправлено: m_ax от Мая 09, 2012, 15:43 Так вроде свояли же уже достаточно быстрый генератор)
Осталось сравнить с какой-нить другой реализацией: Пример теста: Код
Осталось подставить вместо URandGen другую реализацию и всё станет ясно) Хотя сделать что-то быстрее будет ооочень не просто) Название: Re: Random в QT Отправлено: V1KT0P от Мая 09, 2012, 15:54 Вы уж сравните с Вашим по скорости :) Так вроде свояли же уже достаточно быстрый генератор) Да действительно, мне такое почему-то в голову не пришло =(. Хотя вариант на полиномах выиграет по занимаемой памяти(ему там вообще мизер нужен) =). |