|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Нормальный закон распределения случайных чисел
Задался таким, собственно, вопросом
Кто-нибудь уже реализовывал/сталкивался с нормальным распределением случайных чисел в AS3? Погуглив, нашел только очень приближенные реализации или же ссылки на теоремы (мол, разбирайтесь и реализуйте сами). Может кто-то знаком с легковесными библиотеками, или делал что-то сам? =============== Пока наиболее оправданным найденным решением оказалсь реализация "Центральной предельной теоремы".Но там не понятно как задавать дисперсию Последний раз редактировалось KumoKairo; 05.06.2013 в 14:51. |
|
|||||
Википедия подсказывает о преобразовании Бокса-Мюллера. Ну а гугол по предыдущей фразе и добавлением магических "as3" дал ссылку: http://blog.controul.com/2009/04/sta...bution-in-as3/
|
|
|||||
Ух, отличная статейка! Там еще и равномерное распределение есть!
Сам автор пишет что самым простым и недорогим способом реализации будут таблицы со значениями.. Однако реализация интересная) Интересно сравнить с реализацией той центральной предельной теоремы) Отпишусь как сделаю Спасибо за ответ! |
|
|||||
Регистрация: Sep 2006
Сообщений: 145
|
Равномерное распределение получается простым рандомом
Нормальное распределение получается с помощью среднего значения от обычного рандома и энтропийного Что то такого рода Последний раз редактировалось iNils; 06.06.2013 в 14:50. |
|
|||||
Оно уже и при 3-х неэнтропийных похоже получается (и симметричнее выглядит):
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; public class Main extends Sprite { private static const COUNT:int = 800; public function Main() { var counts:Vector.<int> = new Vector.<int>(COUNT); var i:int; var j:int; var index:int; for (i = 0; i < COUNT; i++) { counts[i] = 0; } var bd:BitmapData = new BitmapData(COUNT, 500); for (i = 0; i < 100000; i++) { index = rand3(COUNT); counts[index]++; bd.setPixel(index, int(counts[index] * .5), 0xff0000); } addChild(new Bitmap(bd)); } private function rand1(n:int):int { var r:int = Math.floor(Math.random() * n); return r; } private function rand3(n:int):int { var r:int = Math.floor((rand1(n) + rand1(n) + rand1(n)) / 3); return r; } } } |
|
|||||
Чем больше переменных тем ближе к нормальному распределению)
В самой теореме вообще говорится о бесконечном ряде несвязанных значений Способ товарища Парка Миллера не впечатлил, там выдаются рандомные значения с математическим ожиданием равным 0 и непонятной дисперсией. То есть выдает случайные числа от минус пяти-шести до пяти-шести с плюсом Учитывая это, числа еще придется приводить к диапазону (0, 1), с мат. ожиданием 0.5, а это дополнительные вычисления Со всем вышесказанным получаем такую картину: Сравнение реализации Парка Миллера с реализацией expl (Синим - Парк Миллер) package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; public class Main extends Sprite { private static const COUNT:int = 800; private var parkMiller:ParkMiller; public function Main() { parkMiller= new ParkMiller(); var counts:Vector.<int> = new Vector.<int>(COUNT); var countsParkMiller:Vector.<int> = new Vector.<int>(COUNT); var i:int; var j:int; var index:int; for (i = 0; i < COUNT; i++) { counts[i] = 0; countsParkMiller[i] = 0; } var bd:BitmapData = new BitmapData(COUNT, 500); var bdParkMiller:BitmapData = new BitmapData(COUNT, 500); for (i = 0; i < 100000; i++) { index = rand3(COUNT); counts[index]++; bd.setPixel(index, int(counts[index] * .5), 0xff0000); } for (i = 0; i < 100000; i++) { index = Math.abs(randParkMiller(COUNT)); index = index >= 800 ? 799: index; index = index < 0 ? 0 :index; countsParkMiller[index]++; bdParkMiller.setPixel(index, int(countsParkMiller[index] * .5), 0x0000ff); } addChild(new Bitmap(bd)); var bPark:Bitmap = new Bitmap(bdParkMiller); bPark.y = 300; addChild(bPark); } private function rand1(n:int):int { var r:int = Math.floor(Math.random() * n); return r; } private function rand3(n:int):int { var r:int = Math.floor((rand1(n) + rand1(n) + rand1(n)) / 3); return r; } private function randParkMiller(n:int):int { var r:int = this.parkMiller.standardNormal() * 100 + 400; return r; } } } в функции генерации мат ожидание равно 400, стандартная дисперсия умножена на 100 С учетом всех преобразований и условностей (проверка на выход за границы массива) получаем следующее время выполнения: способ Парка Миллера - 111 мс Способ, реализованный товарищем expl (с тремя значениями) - 173 мс Первый способ, которым я воспользовался (4 переменные) - 98 мс Сравнение моей реализации с Парком Миллером (синим - Парк Миллер): Код функции: private function rand4(n:Number):int { var r1:Number = Math.random() * n; var r2:Number = Math.random() * n; var r3:Number = Math.random() * n; var r4:Number = Math.random() * n; var ret:Number = Math.round((r1 + r2 + r3 + r4) / 4); return ret; } В общем, сдается мне, надо смотреть в сторону Алгоритма Зиггурата, про который написано в конце статьи) Последний раз редактировалось KumoKairo; 07.06.2013 в 11:12. |
|
|||||
Мне надо было рандомно расположить цветочки, но таким образом, чтобы к центру экрана их плотность была бы больше, чем к краям)
В итоге от реализации с нормальным распределением (и от размещения в центре) отказался, сделал совсем по-другому (расположил цветочки по трем направляющим с равномерным разбросом). Но вопрос оказался интересным Последний раз редактировалось KumoKairo; 07.06.2013 в 17:17. |
Часовой пояс GMT +4, время: 15:48. |
|
« Предыдущая тема | Следующая тема » |
|
|