Показать сообщение отдельно
Старый 07.06.2013, 10:22
KumoKairo вне форума Посмотреть профиль Отправить личное сообщение для KumoKairo Найти все сообщения от KumoKairo
  № 7  
Ответить с цитированием
KumoKairo
 
Аватар для KumoKairo

Регистрация: Jan 2013
Сообщений: 550
Записей в блоге: 1
Чем больше переменных тем ближе к нормальному распределению)
В самой теореме вообще говорится о бесконечном ряде несвязанных значений

Способ товарища Парка Миллера не впечатлил, там выдаются рандомные значения с математическим ожиданием равным 0 и непонятной дисперсией. То есть выдает случайные числа от минус пяти-шести до пяти-шести с плюсом

Учитывая это, числа еще придется приводить к диапазону (0, 1), с мат. ожиданием 0.5, а это дополнительные вычисления
Со всем вышесказанным получаем такую картину:
Сравнение реализации Парка Миллера с реализацией expl (Синим - Парк Миллер)
Нажмите на изображение для увеличения
Название: rasp.png
Просмотров: 124
Размер:	7.5 Кб
ID:	29627
Код AS3:
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;
		}
	}
}
Класс ParkMiller находится по ссылке из второго поста
в функции генерации мат ожидание равно 400, стандартная дисперсия умножена на 100

С учетом всех преобразований и условностей (проверка на выход за границы массива) получаем следующее время выполнения:
способ Парка Миллера - 111 мс
Способ, реализованный товарищем expl (с тремя значениями) - 173 мс
Первый способ, которым я воспользовался (4 переменные) - 98 мс

Сравнение моей реализации с Парком Миллером (синим - Парк Миллер):
Нажмите на изображение для увеличения
Название: rasp1.png
Просмотров: 117
Размер:	7.9 Кб
ID:	29628
Код функции:
Код AS3:
		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;
		}
При увеличении количества переменных (до 10) растет время выполнения (163 мс) и уменьшается дисперсия:
Нажмите на изображение для увеличения
Название: rasp2.png
Просмотров: 142
Размер:	7.6 Кб
ID:	29629

В общем, сдается мне, надо смотреть в сторону Алгоритма Зиггурата, про который написано в конце статьи)


Последний раз редактировалось KumoKairo; 07.06.2013 в 11:12.