ГУАП
КАФЕДРА №41
ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ
ПРЕПОДАВАТЕЛЬ
ассистент |
|
|
|
М.Н. Шелест |
|
|
|
|
|
|
|
|
|
|
должность, уч. степень, звание |
|
подпись, дата |
|
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №2
ДАТЧИКИ СЛУЧАЙНЫХ ЧИСЕЛ. ПОСТРОЕНИЕ ГИСТОГРАММ
по курсу: Имитационное моделирование
РАБОТУ ВЫПОЛНИЛ
СТУДЕНТ ГР. №
подпись, дата |
|
инициалы, фамилия |
Санкт-Петербург 2022
Цель работы
Изучение алгоритмов получения на ЭВМ чисел с заданным законом распределения
и построения гистограмм.
Индивидуальный вариант
Индивидуальный вариант номер 10 в соответствии с таблицей 1.
Таблица 1 – Индивидуальный вариант задания
Номер варианта |
Закон распределения |
Параметры закона |
10 |
Нормальный |
µ = -1, σ = 5 |
Ход работы
1.Формула и график моделируемого закона распределения.
Нормальное распределение описывается следующей формулой:
|
1 |
− |
( − )2 |
||
( ) = |
22 |
||||
|
|
√2
График нормального распределения для нашего варианта при µ = -1, σ = 5 в
соответствии с рисунком 1.
Рисунок 1 – График нормального распределения Полученное соотношение из нормального распределения:
, где Ri и Ri+1 две независимые случайные величины.
2
2. Описание разработанных программ для моделирования нормального закона распределения.
Список использованных переменных функции plotiong_norm_hist () в соответствии с таблицей 2.
Таблица 2 – Список используемых переменных функции plotiong_norm_hist()
Название |
Описание |
|
переменной |
||
|
||
mu |
Математическое ожидание для генерации значений нормального |
|
распределения |
||
|
||
sigma |
СКО для генерации значений нормального распределения |
|
intervals_cnt |
Количество интервалов для построения гистограммы |
|
step |
Количество значений, которые добавляются на каждом шаге генерации |
|
выборки нормального распределения |
||
|
||
|
Минимальное количество значений, принадлежащих одному интервалу |
|
minNi |
необходимое для достижения правильной генерации нормального |
|
|
распределения |
|
A |
Массив для хранения значений выборки нормального распределения |
|
x_max |
Хранит верхнюю границу выборки |
|
x_min |
Хранит нижнюю границу выборки |
|
delta |
Хранит длительность интервалов для построения гистограммы |
|
N |
Количество значений в выборке A |
|
Ni |
Список количества значений, принадлежащих каждому из интервалов |
|
гистограммы |
||
|
||
matexp |
Список значений математического ожидания, рассчитанных на каждом |
|
этапе генерации нормального распределения при разных N |
||
|
||
disp |
Список значений дисперсии, рассчитанных на каждом этапе генерации |
|
нормального распределения при разных N |
||
|
||
|
Список значений N для которых рассчитывались математическое |
|
N_array |
ожидание и дисперсия, необходим для корректного построения |
|
|
графиков зависимости рассчитанных величин от объема выборки |
|
Y |
Список значений плотности вероятности для каждого интервала |
|
гистограммы |
||
|
Для генерации случайных чисел нормального распределения была использована функция norm_random(mu, sigma, N) в соответствии с листингом 1.
Листинг 1 – Функция генерации значений нормального распределения
def norm_random(mu, sigma, N):
'''Функция создающая случайные числа для нормального распределения'''
alpha = [] # Список сгенерированных чисел for i in range(0, N//2+1):
R1 = np.random.uniform(0,1) # Случайная величина R[i]
R2 = np.random.uniform(0,1) # Случайная величина R[i+1] alpha.append(mu+sigma*np.sqrt(-2*np.log(R1))* \
np.sin(2*np.pi*R2)) alpha.append(mu+sigma*np.sqrt(-2*np.log(R1))* \
np.cos(2*np.pi*R2))
return alpha[:N]
3
Код программы в соответствии с листингом 2.
Листинг 2 – Функция создание набора данных выборки для построения графика
def plotiong_norm_hist(mu, sigma, intervals_cnt = 10, step = 1, minNi=100):
'''Создание набора данных выборки для построения графика'''
A = [] |
# Массив выборки - пустой |
|
x_max, x_min = 0, 0 |
# Верхняя и |
нижняя границы |
delta = 0 |
# Длительность интервалов |
|
N = 0 |
# Кол-во элементов выборки |
|
intervals = [x_min, x_max] |
# Интервалы |
|
Ni = [0] |
# Элементов |
попалов интервал |
matexp, disp = [], [] # Список МО и Дисперсии при разных N N_array = [] # Список N для которых расчитаны МО и Дисперсии
while True: N += step
A_new = norm_random(mu, sigma, step) A.extend(A_new)
# Добавление новых элементов в соответствующии им интервалы for i in range(len(intervals) - 1):
Ni[i] += sum(True for x in A_new if intervals[i] < x <= intervals[i+1])
# Проверка процента чисел выходящих за пределы текущих интервалов if (N - sum(Ni)) / N > 0.01:
intervals, Ni, x_min, x_max, delta = \ slicearray(A, intervals_cnt)
#Считаем МО и Дисперсию matexp.append(np.mean(A)) disp.append(np.var(A)) N_array.append(N)
# print(N, Ni, np.mean(A), np.var(A)) # Тестовый вывод
#Проверка что все интервалы содержат минимум minNi элементов if min(Ni) >= minNi: break
print(N, Ni, intervals, sep='\n')
# определение значений плотности вероятности для интервалов
Y = [cnt / (N * delta) for cnt in Ni] ploting_normal_distribution(mu, sigma, intervals, Y) return matexp, disp, N_array
4
3. |
Табличное представление результатов анализа сформированной выборки в |
|||||||||||
соответствии с таблицей 3. |
|
|
|
|
|
|
|
|
|
|||
|
Таблица 2 – Распределение элементов выборки по квантам гистограммы |
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
Номер интервала |
1 |
|
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
|
Число элементов, |
|
|
|
|
|
|
|
|
|
|
|
|
попавших в |
4335 |
|
14261 |
32434 |
47909 |
47385 |
30981 |
13356 |
3883 |
756 |
100 |
|
данный интервал |
|
|
|
|
|
|
|
|
|
|
|
|
4. |
Гистограмма сформированной выборки в соответствии с рисунком 3. |
|
Рисунок 2 – График смоделированного закона нормального распределения
5. Графики зависимости оценок математического ожидания и дисперсии от объема выборки в соответствии с рисунком 4. На графиках уровнем отметить теоретические значения этих величин.
Рисунок 3 – Графики зависимости оценок математического ожидания и дисперсии от объема выборки
5
Вывод
В ходе данной лабораторной работы мы познакомились с тем, что такое датчики случайных чисел, и реализовали один из них.
Разработанный нами датчик позволяет преобразовывать равномерное распределение в диапазоне от [0, 1] в нормальное распределение с заданными параметрами.
Чтобы генерировать значения, принадлежащие нормальному распределению нами,
была написана соответствующая функция, которая использует выражения, выведенные методом преобразование Бокса-Мюллера из уравнения нормального распределения.
Подставив в них необходимые значения МО и СКО, мы получаем значения,
принадлежащие нормальному распределению.
Затем, чтобы построить гистограмму была написана вторая функция позволяющая,
итеративно добавляя в выборку значения определить оптимальный размер выборки для построения достаточно точного графика нормального распределения. По полученному в результате набору интервалов и плотностей вероятности построил гистограмму, которая очень близко повторяла линию уравнения нормального распределения.
Во время итеративного подбора оптимального объема выборки мы рассчитывали МО и дисперсию для промежуточных объемов выборки и после завершения работы алгоритма построили графики зависимости оценок математического ожидания и дисперсии от объема выборки. Построенные графики показали, что с увеличением объёма растёт и точность моделирования равномерного распределения.
6
ПРИЛОЖЕНИЕ А. Код программы
from matplotlib import pyplot as plt import numpy as np
def ploting_normal_distribution(mu, sigma, intervals = [], weights = []):
'''Построение графика нормального распрелеоения'''
if len(intervals) != 0 and len(weights) != 0: plt.hist(intervals[:-1], intervals, weights = weights)
f = lambda x : 1 / (sigma * np.sqrt(2*np.pi)) * np.exp(-(x- mu)**2/(2*sigma**2))
x = np.linspace(mu-4*sigma, mu+4*sigma, 100) #Генерируем список из кол. элементов
plt.plot(x, f(x), label='f(x)=1/(sigma*np.sqrt(2*np.pi))*\nnp.exp(-(x- mu)**2/(2*sigma**2)\n mu={} sigma={}'.format(mu, sigma), color='red')
plt.title("График нормального распределения") plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.show()
def ploting_ME_Disp(matexp, mu, disp, sigma, N_array): fig, axis = plt.subplots(1, 2, figsize=(10, 5)) fig.suptitle('Статистика')
#Рисуем график МО
axis[0].plot(N_array, [mu for i in range(0, len(N_array))], color='red', label='Теоретическое значение')
axis[0].plot(N_array, matexp, label='Рассчитанное значение') axis[0].set_title('Мат ожидание') axis[0].set_xlabel('Размер выборки')
axis[0].legend()
# Рисуем график дисперсии sigma **=2
axis[1].plot(N_array, [sigma for i in range(0, len(N_array))], color='red', label='Теоретическое значение')
axis[1].plot(N_array, disp, label='Рассчитанное значение') axis[1].set_title('Дисперсия')
axis[1].set_xlabel('Размер выборки') axis[1].legend()
plt.show()
def norm_random(mu, sigma, N):
'''Функция создающая случайные числа для нормального распределения'''
alpha = [] # Список сгенерированных чисел for i in range(0, N//2+1):
7
R1 |
= np.random.uniform(0,1) |
# |
Случайная |
величина |
R[i] |
R2 |
= np.random.uniform(0,1) |
# |
Случайная |
величина |
R[i+1] |
alpha.append(mu + sigma |
* np.sqrt(-2*np.log(R1)) * |
np.sin(2*np.pi*R2))
alpha.append(mu + sigma * np.sqrt(-2*np.log(R1)) * np.cos(2*np.pi*R2))
return alpha[:N]
def slicearray(array, intervals_cnt):
'''Функция для разбивки списка на интервалы и подсчета кол. попаданий'''
interval=[] #список интервалов entries = [] #список кол. попаданий x_min, x_max = min(array), max(array)
delta = (x_max - x_min) / intervals_cnt
#заполняем список интервалов
for x in range (intervals_cnt+1): interval.append(x_min + delta * x)
for i in range(intervals_cnt):
entries.append(sum(True for x in array if interval[i] < x <= interval[i+1]))
return interval, entries, x_min, x_max, delta
def plotiong_norm_hist(mu, sigma, intervals_cnt = 10, step = 1, minNi=100):
'''Создание набора данных выборки для построения графика'''
A = [] |
# Массив выборки - пустой |
x_max, x_min = 0, 0 |
# Верхняя и нижняя границы |
delta = 0 |
# Длительность интервалов |
N = 0 |
# Кол-во элементов выборки |
intervals = [x_min, x_max] |
# Интервалы |
Ni = [0] |
# Элементов попалов интервал |
matexp, disp = [], [] |
# Список МО и Дисперсии при разных |
N |
|
N_array = [] |
# Список N для которых расчитаны |
МО и Дисперсии |
|
while True: N += step
A_new = norm_random(mu, sigma, step) A.extend(A_new)
for i in range(len(intervals) - 1): # Добавление новых элементов в соответствующии им интервалы
Ni[i] += sum(True for x in A_new if intervals[i] < x <= intervals[i+1])
if (N - sum(Ni)) / N > 0.01: # Проверка процента чисел выходящих за пределы текущих интервалов
intervals, Ni, x_min, x_max, delta = slicearray(A, intervals_cnt)
8
#Считаем МО и Дисперсию matexp.append(np.mean(A)) disp.append(np.var(A)) N_array.append(N)
# print(N, Ni, np.mean(A), np.var(A)) # Тестовый вывод
if min(Ni) >= minNi: break |
# Проверка что все интервалы |
|
содержат минимум |
minNi элементов |
|
print(N, Ni, |
intervals, sep='\n') |
|
Y = [cnt / (N * delta) for cnt in Ni] ploting_normal_distribution(mu, sigma, intervals, Y) return matexp, disp, N_array
def main():
mu, sigma = -1, 5 ploting_normal_distribution(mu, sigma)
matexp, disp, mat = plotiong_norm_hist(mu, sigma, intervals_cnt = 20, step = 100, minNi = 100)
ploting_ME_Disp(matexp, mu, disp, sigma, mat) return 0
if __name__ == "__main__": main()
9