Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
16
Добавлен:
20.06.2014
Размер:
182.27 Кб
Скачать

6. Программирование датчика случайных чисел

Запрограммируем датчик случайных чисел для нормального распределения по методу «Преобразование Бокса – Мюллера». Этот точный метод используется для моделирования стандартных нормально распределённых случайных величин.

Метод «Преобразование Бокса – Мюллера»:

  1. Пусть r и f – независимые случайные величины, равномерно распределённые на интервале (0, 1]. Вычислим z0 и z1 по формулам:

,

.

Тогда z0 и z1 будут независимы и распределены нормально с математическим ожиданием 0 и дисперсией 1.

  1. После получения стандартной нормальной случайной величины z, можно легко перейти к величине ξ=N(μ,σ2), распределённой нормально с математическим ожиданием μ и стандартным отклонением σ по формуле:

ξ = μ + σz.

Это уже не является частью преобразования Бокса – Мюллера, но позволяет завершить генерацию нормальной случайной величины.

Рис. 6 – Гистограмма сгенерированных значений.

7. Код программы с комментариями

Программа на языке C#:

using System;

using System.IO;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Lab_0

{

class Program

{

static void Main(string[] args)

{

#region чтение из файла

StreamReader streamReader = new StreamReader("v16.txt");

string str = "";

while (!streamReader.EndOfStream)

{

str += streamReader.ReadLine() + '&';

}

str = str.Replace('.', ',');

StringBuilder builder = new StringBuilder(str);

builder[str.Length-1] = '0';

str = builder.ToString();

string [] sNumbers = str.Split('&');

//массив чисел

double [] dNumbers = new double[sNumbers.Length];

for (int i = 0; i < sNumbers.Length; i++)

{

dNumbers[i] = double.Parse(sNumbers[i]);

}

#endregion

#region бустреп-выборки

StreamWriter sw = new StreamWriter("res16.txt");

sw.WriteLine(".........Бутстреп - метод..........");

//число бутстреп-выборок

int numB = 1000;

Random randValue = new Random();

int min = (int) Math.Floor(dNumbers.Min())-1;

int max = (int) Math.Ceiling(dNumbers.Max());

double[,] dPInterval = new double[numB, max - min];

double[] dInterv = new double[max - min];

double[] a = new double[numB];

double[] dValues = new double[dNumbers.Length];

double[] disp = new double[numB];

double sum, sumA, dispA;

sw.WriteLine(min + " " + max);

//цикл по числу бутстреп-выборок

sumA = 0;

dispA = 0;

for (int i = 0; i < numB; i++)

{

sum = 0;

for (int j = 0; j < dNumbers.Length; j++)

{

dValues[j] = dNumbers[(int)Math.Round((double)randValue.NextDouble()*(dNumbers.Length-1))];

sum += dValues[j];

//определение попадания в интервал

dPInterval[i, (int) Math.Floor(dValues[j] - min)]++;

}

for (int j = 0; j < max - min; j++)

{

dPInterval[i, j] /= dNumbers.Length;

}

a[i] = sum / dNumbers.Length;

//мат.ожидание

sumA += a[i];

sum = 0;

for (int j = 0; j < dNumbers.Length; j++)

{

sum += Math.Pow(dValues[j], 2);

}

disp[i] = (sum / dNumbers.Length) - Math.Pow(a[i], 2);

//дисперсия

dispA += disp[i];

}

dispA /= numB;

sumA /= numB;

sw.WriteLine("---------------------------------");

for (int i = 0; i < max-min; i++)

{

for (int j = 0; j < numB; j++)

{

dInterv[i] += dPInterval[j, i];

}

dInterv[i] /= numB;

sw.WriteLine(dInterv[i]);

}

sw.WriteLine("Мат.ожидание: " + sumA + " Дисперсия:" + dispA);

#endregion

#region генератор

sw.WriteLine("-------Генератор--------");

double z=0;

double[] dInterval = new double[max - min];

for (int i = 0; i < numB*100000; i++)

{

//z-случайное значение по нормальному закону распределения

z = sumA + Math.Sqrt(dispA) * (Math.Cos(2 * Math.PI * randValue.NextDouble()) * Math.Sqrt(-2 * Math.Log(randValue.NextDouble())));

if(z>min && z<max)

dInterval[(int)Math.Floor(z - min)]++;

}

for (int i = 0; i < max - min; i++)

{

dInterval[i] /= numB * 100000;

sw.WriteLine(dInterval[i]);

}

sw.Close();

#endregion

//Console.ReadLine();

}

}

}