expRandom.
декабря 12, 2007
Иногда бывает нужно, чтобы случайное число с большей вероятностью выпадало ближе к минимальным, или максимальным значениям.
Простой пример - Слот машина.
Бонусные символы должны выпадать гораздо реже обычных символов.
Существует масса способов реализовать такой рандом, о них, к примеру была речь на форуме flash-mx
Вот и мне тут понадобилась такая функция.
Некогда мною было написано некоторое количество игр для казино, все они быи завязаны на сервер, который нынче мертв. Жалко мне стало игрушек - красивые были, вот я сейчас и пишу аля-эмулятор сервера со всей логикой игры. Как раз тут вопрос и возник.
Более того мне необходимо, что бы числа возвращались в жестко заданном диапазоне.
Немного мозгового скрипа дало мне вот такую функцию.
1 2 3 4 5 6 | function expoRandom(range:Number,w:Number):Number { w = Math.max(w,1); w = Math.min(w,709); return Math.log(1+Math.random()*(Math.exp(w)-1))*(range/w); } |
В функцию передается два параметра - собственно диапазон, и, не знаю как это правильно обозвать, степень разброса. От это степени зависит насколько сильно выпадающие значения будут тесниться к максимальному краю. Чем больше степень, тем ближе к краю.
В функцию вставлена небольшая проверка - чтобы ширина не была меньше 1 (в этом случае мы получим обычный рандом) и не была больше 709 (в этом случае выражение Math.exp(w) даст нам infinity). Их собсвенно можно убрать, дабы не забивать процессор лишней работой.
Вся магия тут завязана на простой принцип - есть график логарифма. Мы берем случайное число по оси X и находим его логарифм по оси Y. Немного корректируем под наш диапазон - и результат на лице.
Вот к примеру такой:
http://bbexp.ru/blog/_stuff/random.html
Entry Filed under: ActionScript, Math, fx
3 комментария Add your own
1. bsdemon | февраля 1, 2008 at 16:35
Добрый день! На самом деле можно просто взять любую функцию - которую мы будем считать за плотность вероятности, можно даже со скачками, главное чтобы интеграл от неё по всей прямой был равен 1. Тогда найдя для неё обратную функцию и применив её на Math.random() - получим случ. величину с заданным распределением. Таким образом если мы хотим чтобы наибольшую вероятность имело число 1, то нужно взять функцию с max в 1, например Нормальное распределение с мат. ожиданием (значение в среднем, наиболее врерятное) в 1 и дисперсией например 1 (как раз дисперсия и характеризует степень отклонения от мат. ожидания). Вот… )
2. murejib | февраля 1, 2008 at 16:44
Вот именно поэтому я и стал искать решение поставленной задачи, и именно поэтому опубликовал его в блоге ))
Потому что “просто взять любую функцию … плотности вероятности… дисперсия…. степень отклонения от мат. ожидания” - это все звучит как древнее проклятие ))) И просто оказывается не просто )) Несмотря на то что, в школе я учился в физико-мат-классе, и неплохо учился, так получилось, что знание алгебро-геометрии испарилось за пять лет обучения в АБСОЛЮТНО гуманитарном направлении )))
Теперь чтение подобных слов вызывает у меня окостенение мозга и паническую боязнь окружающих )))
3. bsdemon | июля 8, 2008 at 13:38
Очень жаль… меня просто убивает когда в книгах по as я вижу главы про тригонометрию…
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed