- •Лаба 1 Теоретическая часть о случайных и псевдослучайных числах
- •Часть 1. Генератор равномерно распределенных псевдослучайных чисел
- •Часть 2. Генераторы псевдослучайных чисел, распределенных по различным законам распределения
- •Задание к первой части
- •Задание ко второй части
- •Лаба2 Краткая теоретическая часть
Часть 2. Генераторы псевдослучайных чисел, распределенных по различным законам распределения
Нормальное распределение. Оно является одно из наиболее важных и часто используемых видов непрерывных распределений. Дадим ему соответствующее определение.
Опр. 1. Непрерывная
случайная величина
имеет нормальной распределение
вероятностей с параметрами
и
,
если ее плотность вероятностей имеет
вид
, (1)
где
- математическое ожидание
случайной величины
;
- ее среднеквадратическое отклонение.
Функция плотности вероятностей (1) имеет вид, изображенный на рис. 1.

Рис. 1. График функции плотности вероятностей нормального распределения.
Для того, чтобы разработать датчик нормально распределенных псевдослучайных чисел, достаточно знать центральную предельную теорему теории вероятностей. Смысл ее следующий.
Пусть некоторый
случайных процесс состоит из
последовательности
элементарных независимых процессов.
Длительность каждого такого процесса
- случайная величина, распределенная
по неизвестному закону с математическим
ожиданием
и имеющая конечный третий момент. Введем
случайную величину
.
При
распределение данной случайной величины
стремится к нормальному с математическим
ожиданием
и дисперсией
.
Поэтому, разработка датчика нормально
распределенных псевдослучайных чисел
сводится к следующему.
Вводится некоторая
вещественная переменная
.
Осуществляется генераций
равномерно-распределенных на интервале
псевдослучайных
чисел с последующим их суммированием
и занесением результата в переменную
.
Затем остается отцентрировать и
нормировать значение
:
.
Датчик чисел,
созданный по вышеприведенному алгоритму
выдает нормально распределенные числа
в интервале

Чтобы получить датчик псевдослучайных чисел, распределенных по экспоненциальному закону, можно воспользоваться методом обратных функций. Перед этим напомним функцию плотности вероятностей и основные числовые характеристики соответствующих случайных величин.
Функция плотности вероятностей:
(2)
Математическое
ожидание
.
Дисперсия
.
Здесь методика сводится к следующему.
Генерируется
псевдослучайное число
(с помощью датчика равномерно-распределенных
чисел). Затем осуществляется его
логарифмирование по основанию
.
Полученное значение умножается на
математическое ожидание
.
Задание к первой части
Разработать функцию rundum, которая генерирует псевдослучайные числа с помощью вышеприведенного алгоритма. Разработать программу, которая должна выполнять следующие действия:
разбиение отрезка
на
разных частей;
вызовов функции
rundum
и вычисление относительных частот
попадания получаемых псевдослучайных
чисел в соответствующую часть интервала;вывод таблицы, состоящей из
строк и трех колонок: № части интервала,
длина соответствующего отрезка,
относительная частота попадания
псевдослучайных чисел.
Задание ко второй части
Разработать датчики
генерации псевдослучайных чисел,
распределенных по нормальному и
экспоненциальному законам. Для каждого
датчика, для
испытаний построить гистограмму частот
попадания чисел в произвольно заданные
подотрезки внутри допустимого интервала.
Выполнение:
#include "stdafx.h"
#include "conio.h"
#include "math.h"
double rundum (long b){
long y;
double r;
y = b*1220703125;
if (y < 0){
y+=1073741824;
y+=1073741824;
};
r = y*0.4656613/1000000000;
return r;
};
void rm (void){
//количество рассчитанных случайных чисел
double x[1000];
//границы интервалов для равномерного распределения
double m[2][10] = {{0.0,0.1,0.15,0.20,0.21,0.3,0.46,0.64,0.7,0.91},{0.1,0.15,0.20,0.21,0.3,0.46,0.64,0.7,0.91,1}};
//сколько раз попадает в каждый интервал
int p[10] = {0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 1000; i++){
x[i] = rundum(i+267);
};
for (int i = 0; i < 1000; i++){
for (int j = 0; j < 10; j++){
if (x[i] >= m[0][j] && x[i] < m[1][j]){
p[j] = p[j] + 1;
};
};
};
printf ("Ravnomernoe:\nnum\tdlina\tchastota\n");
for (int i = 0; i < 10; i++){
printf ("%d\t%g\t%d\n", i,abs(m[1][i]-m[0][i]) ,p[i]);
};
};
void norm (void){
//количество рассчитанных случайных чисел
double x[100];
//границы интервалов для равномерного распределения
double m[2][10];
//сколько раз попадает в каждый интервал
int p[10] = {0,0,0,0,0,0,0,0,0,0};
//переменные для накопления суммы, мат ожидание, дисперсия
double a=0, M=0.5, D=0.15;
//массив с нормально распределенными числами
double s[1000];
//расчет чисел и заполнение массива
for (int j=0; j<1000; j++){
for (int i = 0; i < 100; i++){
x[i] = rundum(i*j+834);
a += x[i];
};
s[j] = M+(a-50)*D;
a=0;
}
//расчет границ интервалов
m[0][0] = 0;
m[1][9] = 1;
double shag;
shag = (m[1][9]-m[0][0])/10;
for (int i=1; i<10; i++){
m[0][i]=m[0][i-1]+shag;
};
for (int i=8; i>=0; i--){
m[1][i]=m[1][i+1]-shag;
};
//подсчет сколько чисел попадает в каждый интервал
for (int i = 0; i < 1000; i++){
for (int j = 0; j < 10; j++){
if (s[i] >= m[0][j] && s[i] < m[1][j]){
p[j] = p[j] + 1;
};
};
};
printf ("Normalnoe:\nnum\tdlina\tchastota\n");
for (int i = 0; i < 10; i++){
printf ("%d\t%g\t%d\n", i,abs(m[1][i]-m[0][i]) ,p[i]);
};
};
void exp (void){
//количество рассчитанных случайных чисел
double x[1000];
//границы интервалов
double m[2][10];
//сколько раз попадает в каждый интервал
int p[10] = {0,0,0,0,0,0,0,0,0,0};
//лямбда
double l = 10;
//мат ожидание и дисперсия
double M=1/l;
double D=1/l;
//расчет и заполнение массива
for (int i = 0; i < 1000; i++){
x [i] = -log(rundum(i+67))*M;
};
//расчет границ интервалов
m[0][0] = 0;
m[1][9] = 1;
double shag;
shag = (m[1][9]-m[0][0])/10;
for (int i=1; i<10; i++){
m[0][i]=m[0][i-1]+shag;
};
for (int i=8; i>=0; i--){
m[1][i]=m[1][i+1]-shag;
};
for (int i = 0; i < 1000; i++){
for (int j = 0; j < 10; j++){
if (x[i] >= m[0][j] && x[i] < m[1][j]){
p[j] = p[j] + 1;
};
};
};
printf ("Expotencialnoe:\nnum\tdlina\tchastota\n");
//printf ("%f\n%f", m[0][4], m[1][4]);
for (int i = 0; i < 10; i++){
printf ("%d\t%g\t%d\n", i,abs(m[1][i]-m[0][i]) ,p[i]);
};
};
int _tmain(int argc, _TCHAR* argv[])
{
rm();
norm();
exp();
getchar();
return 0;
}
Результат:

Гистограммы:
1) для нормального распределения

2) для экспоненциального распределения

