![]() |
|
||||||||||
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Есть потребность в многократном получении одной и той же последовательности псевдослучайных чисел, равномерно распределенных по диапазону. Скажем, от 1 до 100. При этом должно быть несколько вариантов этой последовательности, скажем, тоже штук 100.
По идее, генератор должен инициализироваться каким-то значением и потом при запросе чисел выдавать одну и ту же последовательность. При этом, при инициализации разными начальными параметрами, последовательности должны получаться разные. Может кто видел готовое решение? ЗЫ. Была идея сделать совсем тупо - нагенерить массив из 1000 случайных чисел и потом просто брать фрагменты этого массива, но может есть простое математическое решение? ЗЗЫ. Линейно-конгруэнтный метод я уже попробовал. Не понравилось. |
|
|||||
|
Цитата:
__________________
:) |
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Попробовал несколько вариантов, которые нагуглил, но при проверке ни один из них полного равномерного покрытия не обеспечил. Скажем, если рандом в интервале 1..100, то при хотелось бы иметь все 100 значений.
|
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Так Вам не случайность нужна вообще, а перемешивание.
__________________
Reality.getBounds(this); |
|
|||||
|
Все-таки хотелось бы услышать более точную формулировку задачи.
Поисковый запрос "random seed actionscript" выдает кучу вариантов. Под рукой пока, увы, нет.
__________________
9 из 10 голосов в моей голове сказали наркотикам "НЕТ" Мои ачивки: художник-паразит. |
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Более точная формулировка задачи выглядит так:
// нужен некоторый класс RandomDt, который выдает случайные числа в диапазоне от 0 // до некоторого лимита (напр., 10) в зависимости от некоторого параметра (напр., 1234567 ), // который указывается при инициализации: RandomDt.init( 10, 1234567 ) var rand1 : Array() = []; var rand2 : Array() = []; var rand3 : Array() = []; var i : int; // серия 1 RandomDt.init( 10, 1234567 ); for ( i = 0; i < 1000; i++ ) { rand1.push( RandomDt.getValue() ); } // серия 2 RandomDt.init( 10, 987654 ); for ( i = 0; i < 1000; i++ ) { rand2.push( RandomDt.getValue() ); } // серия 3 RandomDt.init( 10, 1234567 ); for ( i = 0; i < 1000; i++ ) { rand3.push( RandomDt.getValue() ); } // по итогам испытаний должно получиться: // - rand1 эквивалентен rand3 // - rand2 отличается от rand1, rand3 // - rand1, rand2, rand3 запонены числами от 0 до 9, при // этом все числа встречаются с примерно равной // частотой |
|
|||||
|
listener
|
Заполнить массив из 1000 элементов пачками [0...9], тогда числа будут присутствовать в (примерно) равной пропорции, и перемешать получившийся массив по какому-то алгоритму с параметром, имитирующему случайность перемешивания. Перемешивая массив просто случайным образом не добиться п.1. За алгоритм сейчас не скажу, думать надо
.Например, можно в пачках [0...9] перед заполнением задавать определенный порядок чисел (таких вариантов будет 10! = 3628800, если я ничего не путаю), а заполнять и перемешивать большой массив уже каким-то статическим алгоритмом (без параметра). Можно попробовать за основу взять битмап дату 1х1000 и что-то мутить с пиксельной информацией, сид как-то привязать к цвету... Последний раз редактировалось alexcon314; 08.03.2014 в 19:59. |
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Цитата:
И, видимо, так и сделаю. Единственно, не совсем понятно, почему все время всплывает тема с перемешиванием. Вот как работает штатный Math.random(): var rands:Array = []; var count:int = 1000; for ( var i:int = 0; i < count; i++ ) { var randIndex:int = int( Math.random() * 10 ); rands[randIndex] = int( rands[randIndex] ) + 1; } for ( var j:int = 0; j < 10; j++ ) { trace( j, '=>', Math.floor( rands[j] / ( count / 1000 ) ) / 10, '%' ); } Т.е., очевидно, что разброс есть, но при увеличении числа испытаний он будет нивелироваться. Мне нужно то же самое, только с возможностью начальной инициализации. |
|
|||||
|
listener
|
Вы же потребовали, чтобы был параметр инициализации, условно говоря "сид", обеспечивающий уникальность и воспроизводимость набора.
Вы не сможете удовлетворить этому требованию, если заполнять массив через random(). Не получится на 100% воспроизвести результат предыдущего заполнения. Или вы как-то иначе себе это представляете? Почему перемешивание? Потому что ваша задача по-сути комбинаторная, а не статистическая. Перемешивание - суть перестановка заранее известного неизменяемого набора элементов. По крайней мере, формулировка задачи наводит именно на такой подход. Немного раскрою свою мысль, если вы не поняли. Пачку [0...9] можно перед добавлением в массив из 1000 зараннее перемешать, одним из известных вам спосбов, назовем условно это "паттерном заполнения". Добавляем последовательно пачки в массив. Потом, 1000 элементов нужно переставить по какому-то однозначному и обратимому алгоритму, типа как это делается в случае со случайным перемешиванием, но только без рандома . Ну, переставим местами чет-нечет и потом пройдемся по каждой пачке реверсом со смещением на 3 .. или еще как-то..насколько фантазии хватит.На выходе должен получится массив из все тех же чисел, встречающихся в равной пропорции и в порядке, прямо зависящем от способа первоначального перемешивания пачки [0...9]. Т.е. удовлетворяем условиям: "непохожесть" выхлопа для двух разных паттернов заполнения и обеспечиваем воспроизводимость выхлопа при одинаковых паттернах. Ну, и внешне такой выхлоп вряд ли сильно будет отличаться от результата рандомного заполнения . При таком подходе имеем 10! возможных вариантов выхлопов.Написал, и как-то вспомнилось про криптографию. Может в эту сторону посмотреть? Последний раз редактировалось alexcon314; 09.03.2014 в 12:39. |
|
|||||
|
Ваш же код выполнен 1000 000 итераций и убрал транкейт в результате
вы хотите на 1000 итераций на 10 групп получить абсолютно равномерное распределение и при этом хотите чтобы это был рандом? чего-то вы не того хотите.
__________________
:) |
![]() |
![]() |
Часовой пояс GMT +4, время: 05:40. |
|
|
« Предыдущая тема | Следующая тема » |
|
|