eXeL@B —› Программирование —› алгоритмы автовыбора |
Посл.ответ | Сообщение |
|
Создано: 13 июля 2012 19:41 · Поправил: albatros · Личное сообщение · #1 |
|
Создано: 13 июля 2012 19:47 · Личное сообщение · #2 |
|
Создано: 13 июля 2012 20:13 · Личное сообщение · #3 albatros В смысле в "медиа-проигрывателях"? Там по списку, по обратному списку, рандом, причем на большинстве дерьмовый, тот же winamp может несколько раз подрят одну и туже дорожку проиграть. В общем пиши что тебе нужно, точнее что хочешь получить, случайность, процент случайности типа, как в игровых автоматах. |
|
Создано: 13 июля 2012 22:36 · Личное сообщение · #4 |
|
Создано: 13 июля 2012 23:13 · Личное сообщение · #5 |
|
Создано: 14 июля 2012 00:05 · Личное сообщение · #6 |
|
Создано: 16 июля 2012 13:51 · Личное сообщение · #7 |
|
Создано: 16 июля 2012 14:36 · Личное сообщение · #8 |
|
Создано: 16 июля 2012 22:59 · Личное сообщение · #9 ну а можно составить массив и когда рандомом выбераешь помечать чтобы исключить дубли. Будет рандом без повторов ----- z+Dw7uLu5+jqLCDq7vLu8PvpIPHs7uMh | Сообщение посчитали полезным: ClockMan |
|
Создано: 17 июля 2012 01:08 · Личное сообщение · #10 Есчо вариант если без сортировки списка то когда проигрывается первая случайная дорожка, заносишь int в какой нибудь vector и во время проигрывания генеришь есчо одно число и проверяешь в векторе если нет то нор, ибо если список большой может появиться неслабый оверхед из за проверок на повторы и будут тормаза при переключении, а если сортировать список, то нужно генерить сразу массив и по нему раскидать список воспроизведения, хотя упомянутый aimp часто помирает на этом деле, а winamp делает это долго и слабое распределение ибо делает это частично, все из за того же оверхеда, мало кто будет ждать N минут пока он отсортирует, уныло в общем. |
|
Создано: 17 июля 2012 16:31 · Личное сообщение · #11 |
|
Создано: 17 июля 2012 17:13 · Личное сообщение · #12 |
|
Создано: 17 июля 2012 17:27 · Личное сообщение · #13 VodoleY Все просто, генератор ограничен числом дорожек, пример: Code:
Прогони несколько раз и увидишь кучу дублей, уже приводил в пример winamp с его случайным воспроизведением которое одну дорожку может три раза подряд проиграть, факт из личной практики. Если проверять на дубли и большой список воспроизведения то появляется оверхед. Оптимально, как предложил SWR разбивать на группы. | Сообщение посчитали полезным: DimitarSerg |
|
Создано: 17 июля 2012 17:38 · Личное сообщение · #14 F_a_u_s_t для справки.. генерация стойкого рандома это отдельное подразделение математики. Винамп не показатель. алгоритмов масса, я сори, не спец по рандомам. но "совершенный код, майкрософт пресс" советую почитать, там отдельная глава на эту тему. ----- Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме.... |
|
Создано: 17 июля 2012 18:28 · Личное сообщение · #15 VodoleY Если речь об этой книге: М.Ховард Д.Лебланк - Защищенный код то я ее читал и там нет противоречия моим словам, там так и написано что стандартный random из crt это уг, а более надежные дают неслабый оверхед, а так же выше писал что все числа можно поместить в vector с проверкой на уникальность, но при большом списке будет оверхед, тут дело не в надежности, а в скорости. |
|
Создано: 18 июля 2012 15:11 · Личное сообщение · #16 |
|
Создано: 18 июля 2012 15:35 · Поправил: ARCHANGEL · Личное сообщение · #17 А почему не генерировать список всех треков, допустим, изначально их 100, например. Список будет содержать 100 элементов. Потом рандомом получаем номер от 0 до 99, например, выпало 11. Проиграли двенадцатый трек и удалили его из списка. Теперь списко сократился, и в нём уже можно найти элементы по номерам от 0 до 98. Опять рандомный номер, например, опять 11 (если хреновый генератор псевдослучайных чисел), но теперь проигрываться будет трек, который в первоначальном списке был 12, т.е. нет повторов. А, допустим, через 20 проигранных треков заново добавим удалённые в конец списка. Так убивается сразу несколько зайцев. Во-первых, не надо гонять рандомный псевдогенератор. Даже если он - полное фуфло, мы избежим повторов и получим-таки элемент случайности. Во-вторых, один раз сгенерировав служебный список, нам не нужно каждый раз его перестраивать, ведь мы не будем полностью удалять элементы списка, а будем лишь разрушать ссылки элементов друг на друга. В-третьи, получается очень экономично по затрачиваемой памяти, если сделать так, чтоб представить элементы двумя списками, объединёнными в один. Т.е., элемент находится в памяти в единственном экземпляре, но имеет два указателя на другие элементы. Так сказать, у нас будет два односвязных списка. Первый указатель связывает элементы так, как они изначально были заданы в плейлист (например, когда вы открываете винамп, то видите там чёткий порядок, хотя они и могут проигрываться случайно), а второй указывает и положение для списка проигрывания. И разрушая вторые ссылки, мы оставляем первые, что позволит добавлять во второй список элементы, проходя по первому. Надеюсь, не слишком туманно объяснил. Подумал... Можно модифицировать алго, упростив его. Предположим, мы составили список всех треков, которые должны проигрываться в случайном порядке. У нас есть переменная, в которой хранится общее число таких треков. Плюс к этому - у нас есть константа, которая показывает минимальное число треков, проигрываемых без повторения. Допустим, у нас в плей-листе 100 песен, при этом мы хотим, чтоб как минимум 20 раз подряд темы не проигрывались повторно, ь.е. если проигрался трек номер 1, то после него должны прозвучать ещё 19 других треков перед тем, как он, возможно, проиграется вновь. С постановкой задачи определились. Теперь в плане реализации. У нас также есть некий генератор случайных чисел, который позволяет худо-бедно генерировать псевдослучайные числа в заданном диапазоне. Допустим, нам нужно сгенерировать число в диапазоне [0,99]. он генерирует 45 (например). Мы проигрываем трек № 45, и перемещаем (!!!) его в конец списка, счётчик же всех элементов уменьшаем на 1. Так мы делаем столько раз, сколько указано в нашей константе. В примере выше указано 20 раз. Получается, что на каждой последующей итерации мы уменьшаем счётчик, который одновременно является верхней границей диапазона случайных чисел. Поэтому он не может сгенерировать номер, соответствующий уже проигранным трекам. Когда же цикл завершится, добавляем значение константы к уменьшенному в результате работы цикла значению счётчика, и он снова равен числу всех элементов списка. Плохо будет лишь в том случае, если генератор вообще дерьмовый и генерирует числа в диапазоне Верхняя_граница - Константа. Тогда всё время будет слушать всё то же количество треков, равных константе. Но такого не будет в случае с тем же rand(), т.к. это не совсем фуфло. ----- Stuck to the plan, always think that we would stand up, never ran. |
|
Создано: 20 июля 2012 23:34 · Личное сообщение · #18 |
|
Создано: 21 июля 2012 00:00 · Личное сообщение · #19 Isaev пишет: можно составить массив и когда рандомом выбераешь помечать чтобы исключить дубли. Будет рандом без повторов Поддержу этот вариант. Классический алгоритм тасовки колоды карт в компьютерных играх: каждой карте присваивается случайный индекс, затем колода (массив) упорядочивается по этому индексу, например, по возрастанию. В случае с плеером выполняется сортировка треков, затем воспроизведение идет уже по этому списку. При достижении конца списка операция сортировки повторяется. Гарантированно никаких повторов, всегда доступна информация о следующем и предыдущем треке. | Сообщение посчитали полезным: obfuskator |
|
Создано: 21 июля 2012 10:10 · Личное сообщение · #20 F_a_u_s_t Первый вариант - как-бы частный случай второго, во втором тоже самое достигается, если значение константы равно количеству треков в списке, т.е. он более гибкий. ManHunter Проблемой таких алгоритмов является плохая реализация генератора псевдослучайных чисел, в случае, если он генерирует одно и тоже число несколько раз подряд. ----- Stuck to the plan, always think that we would stand up, never ran. |
|
Создано: 21 июля 2012 10:28 · Личное сообщение · #21 F_a_u_s_t пишет: aimp часто помирает на этом деле, а winamp делает это долго и слабое распределение ибо делает это частично, все из за того же оверхеда, мало кто будет ждать N минут пока он отсортирует, уныло в общем. Либо у вас плейлисты на 100500 миллионов песен, либо в плеерах мега-индусский код. Хоть сортировка хоть перемешивание десятка тысяч строк занимает доли секунды на самых стандартных контейнерах и алгоритмах. Хинт: std::vector, std::string, std::sort, std::random_shuffle ARCHANGEL пишет: роблемой таких алгоритмов является плохая реализация генератора псевдослучайных чисел, в случае, если он генерирует одно и тоже число несколько раз подряд. Хинт: #include <random>, std::random_device, std::mt19937 ----- PGP key | Сообщение посчитали полезным: obfuskator |
|
Создано: 21 июля 2012 10:52 · Личное сообщение · #22 ARCHANGEL пишет: генератора псевдослучайных чисел На то ини и псевдо что повторяютя при каждом первом запуске Небольшой код на delphi генерирующий псевдо случайное число Code:
при длине генератора ключа 10 первое значение будет всегда 3EQlyJSNTv при включение генератора случайных чисел получить одиннаковую строку сводится к обычному нулю Code:
выполнений рандомной кучи длиною в 100 строк проходит за несколько милисекунд ----- Чтобы правильно задать вопрос, нужно знать большую часть ответа. Р.Шекли. |
|
Создано: 21 июля 2012 11:44 · Личное сообщение · #23 ClockMan пишет: На то ини и псевдо что повторяютя при каждом первом запуске Та нет, не потому. А потому что под псевдо подразумевается наличие некоей не случайной зависимости. Т.е. в первом приближении элементы такого пседослучайного ряда представляют собой рекуррентное соотношение. И при одном и том же начальном элементе имеем один и тот же ряд. Естественно, библиотечные функции заточены под генерацию разных последовательностей. ----- Stuck to the plan, always think that we would stand up, never ran. |
|
Создано: 21 июля 2012 14:48 · Личное сообщение · #24 ntldr Смотрим реализацию random_shuffle и видим там rand() который нормально работает с time(0), потом пилим семпл примерно такого содержания - Code:
И выскакивают одни и те же числа, random_device и плей лист как то слабо сочетаются, ибо ограничено размером листа и число от фонаря не катит, а нужно от 0 до MAX_LIST. О минутах было сказано в контексте winamp и aimp первый долго сортирует (глазуальный список), а второй иногда помирает на этом деле. А так, есчо есть boost с кучей алгоритмов это не является каким то откровением, а по поводу списка то у меня иногда добегает до 6к дорожек. Ну и о скорости, тот же SQLite сортирует 1м записей несколько секунд. Есчо я выпил и в коде мог накосячить, ну да ладно кому надо тот поймет. |
|
Создано: 21 июля 2012 15:28 · Личное сообщение · #25 Смотрим Пример: Code:
Учимся юзать стандартную библиотеку господа. ----- PGP key |
|
Создано: 21 июля 2012 15:59 · Поправил: F_a_u_s_t · Личное сообщение · #26 ntldr пишет: Смотрим --> документацию <-- на random_shuffle Спасибо конечно за ссылку, но у меня есть стандарт: Code:
Add: В голове не много прояснилось, теперь к сути, так как не известен язык написания то задача решается в контексте C и Delphi - rand, srand и randomize, random... vector мной упомянут, так как в delphi есть его аналог TList, а вот аналога random_shuffle там нет, а так можно взять boost и не ипать себе моск. |
|
Создано: 21 июля 2012 19:36 · Личное сообщение · #27 ARCHANGEL пишет: Проблемой таких алгоритмов является плохая реализация генератора псевдослучайных чисел, в случае, если он генерирует одно и тоже число несколько раз подряд. Что мешает сделать проверку на повтор предыдущего числа? Код увеличивается всего на пару строчек. Начальная задача же стоит, как я понимаю, не в написании самого удачного и не повторяющегося генератора ПСЧ, а в наиболее эффективной сортировке плей-листа, чтобы в нем не было повторов и был максимальный разброс. Конкретно эта задача решается именно упорядочиванием списка по случайному индексу. | Сообщение посчитали полезным: DimitarSerg |
|
Создано: 29 июля 2012 21:49 · Личное сообщение · #28 Ничего себе, напридумывали. Заметили, что тс с 14 июля тут не отписывался? К вопросу о ГСЧ и shuffle в музыкальном проигрывателе - у меня тоже возникали какие-то мысли относительно алгоритма. Включая очередь с приоритетами, вычисляемыми на основании того, какие песни дослушали до конца, а какие переключили. Насчет того, что поиск по массиву займет много времени - это просто смешно. Сколько песен надо добавить в плейлист, чтобы поиск по соответствующему массиву занял хотя бы секунду? Однако, если поставить себе цель сделать случайную выборку без повторов с сохранением истории, наиболее быстрым будет алгоритм, предложенный ARCHANGEL, со сложностью поиска следующей песни - O(1), кратко: 1. M = число песен 2. Случайно выбрать песню из первых M элементов массива 3. Переставить выбранную песню и M-1й элемент массива (нумеруем с 0) 4. Уменьшить M. 5. Проиграть выбранную песню 6. Если M = 0, перейти на 1, иначе на 2. С точностью до констант, как-то так. В результате, в конце массива окажется перевёрнутая история, и повторов не будет. Но кому это надо?) |
eXeL@B —› Программирование —› алгоритмы автовыбора |