КМ МО-317 Шакиров А.Р. ЛР1
.docxУФИМСКИЙ ГОСУДАРСТВЕННЫЙ АВИАЦИОННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
ФАКУЛЬТЕТ ИНФОРМАТИКИ И РОБОТОТЕХНИКИ
КАФЕДРА ВЫЧИСЛИТЕЛЬНОЙ МАТЕМАТИКИ И КИБЕРНЕТИКИ
|
|
|
||
|
УТВЕРЖДАЮ Проректор университета по научной работе ФИО |
|||
|
|
|
||
|
"___" ______________ _______г. |
|||
|
|
|
||
Лабораторная работа № 1
«Генерирование случайных переменных»
|
||||
|
||||
по предмету: КОМПЬЮТЕРНОЕ МОДЕЛИРОВАНИЕ |
||||
Преподаватель |
|
А. Ф. Валеева |
||
|
|
|
||
|
|
|
||
|
|
|
||
Исполнитель |
|
А. Р. Шакиров |
||
|
|
|
||
Уфа - 2021 |
ЗАДАНИЕ
Выбрать для программирования одну непрерывную случайную переменную и одну дискретную. Проверить по критерию согласия принадлежность исследуемой случайной переменной закону распределения.
Ход работы
Реализуем получение равномерной случайной переменной на отрезке [a, b].
Входные данные:
a – минимальное значение (начало отрезка)
b – максимальное значение (конец отрезка)
Выходные данные:
result – значение равномерной случайной переменной на отрезке [a, b]
Алгоритм:
1. u = Uniform [0, 1]
2. result = a + (b - a) * u
Далее реализуем проверку принадлежности равномерной случайной переменной равномерному распределению.
Входные данные:
a – минимальное значение (начало отрезка)
b – максимальное значение (конец отрезка)
N – количество испытаний
Выходные данные:
критерий согласия – значение критерия согласия Пирсона
критерий согласия критический – критическое значение критерия согласия Пирсона при alpha = 0,05.
Алгоритм проверки:
Создаем словарь испытаний, ключами которого являются целые числа от a до b, а значением является частота появления случайной переменной на интервале [ключ, ключ+1].
счетчик испытаний = 0
Пока количество испытаний меньше N:
случайная переменная = равномерная случайная переменная на отрезке [a, b]
ключ = целая часть от значения случайной переменной
Если в словаре испытаний содержится получившийся ключ, то
увеличиваем значение по данному ключу на 1.
иначе
по данному ключу заносим 1.
Увеличиваем счетчик испытаний на 1
сумма = 0
Перебираем ключи словаря испытаний:
частота появления значения в интервале = значение в словаре испытаний по данному ключу
сумма += (ключ + 0,5) * частота появления значения в интервале
выборочное среднее = сумма / N
сумма = 0
Перебираем ключи словаря испытаний
частота появления значения в интервале = значение в словаре испытаний по данному ключу
сумма += (ключ + 0,5) – выборочное среднее)2 * частота появления значения в интервале
дисперсия = сумма / N
среднеквадратичное отклонение = корень квадратный из дисперсии
a* = выборочное среднее – ((корень квадратный от 3) * среднеквадратичное отклонение)
b* = выборочное среднее + ((корень квадратный от 3) * среднеквадратичное отклонение)
теоретическая плотность распределения = 1 / (b* - a*)
число значений = количество ключей в словаре
Создаем словарь теоретических испытаний, ключами которого являются целые числа от a до b, а значением является теоретическая частота появления случайной переменной на интервале [ключ, ключ+1].
Заносим в словарь теоретических испытаний по ключу a значение = N * плотность * (a + 1 - a*).
Если число значений > 2, то
i = a + 1
Пока i < b:
Заносим в словарь теоретических испытаний по ключу i значение = N * теоретическая плотность распределения
Заносим в словарь теоретических испытаний по ключу b значение = N * теоретическая плотность распределения * (b* – (b – 1)).
критерий согласия = 0
Перебираем ключи словаря испытаний
частота появления в интервале = значение в словаре испытаний по данному ключу
теоретическая частота появления в интервале = значение в словаре теоретических испытаний по данному ключу
критерий согласия += (частота появления в интервале - теоретическая частота появления в интервале)2 / теоретическая частота
критерий согласия критический = критическое значение критерия согласия Пирсона (хи квадрат) при alpha = 0,05 и степени свободы = число значений – 3
Если критерий согласия < критерий согласия критический, то
исследуемая случайная переменная принадлежит равномерному закону распределения
иначе
не принадлежит.
Далее реализуем получение Пуассоновской случайной переменной с интенсивностью lambda.
Входные данные:
lambda – среднее количество событий за фиксированный промежуток времени
Промежуточные данные:
p – вероятность того, что X=i
f – вероятность того, что X<=i
Выходные данные:
X – значение Пуассоновской случайной переменной
Алгоритм:
u = Uniform [0, 1]
p = число e в степени минус lambda
f = p
i = 0
Пока не (u < f):
p = lambda * p / (i + 1)
f = f + p
i = i + 1
X = i
Далее реализуем проверку принадлежности Пуассоновской случайной переменной Пуассоновскому распределению.
Входные данные:
lambda – среднее количество событий за фиксированный промежуток времени
N – количество испытаний
Выходные данные:
критерий согласия – значение критерия согласия Пирсона
критерий согласия критический – критическое значение критерия согласия Пирсона при alpha = 0,05
Алгоритм проверки:
Создаем словарь испытаний, ключами которого являются целые числа, а значением является частота появления случайной переменной.
счетчик испытаний = 0
Пока количество испытаний меньше N:
случайная переменная = Пуассоновская случайная переменная при заданном lambda
ключ = случайная переменная
Если в словаре испытаний содержится получившийся ключ, то
увеличиваем значение по данному ключу на 1.
иначе
по данному ключу заносим 1.
Увеличиваем счетчик испытаний на 1
сумма = 0
Перебираем ключи словаря испытаний:
частота появления значения случайной переменной = значение в словаре испытаний по данному ключу
сумма += ключ * частота появления
выборочное среднее = сумма / N
число значений = количество ключей в словаре
ожидаемое среднее = выборочное среднее
Создаем словарь теоретических испытаний, ключами которого являются целые числа, а значением является частота появления случайной переменной.
Перебираем ключи словаря испытаний:
факториал = значение факториала от значения ключа
вероятность = (число е в степени минус ожидаемое среднее) * (ожидаемое среднее в степени значения ключа) / факториал
Заносим в словарь теоретических испытаний по текущему ключу значение = N * вероятность
критерий согласия = 0
Перебираем ключи словаря испытаний
частота появления значения случайной переменной = значение в словаре испытаний по данному ключу
теоретическая частота появления значения случайной переменной = значение в словаре теоретических испытаний по данному ключу
критерий согласия += (частота появления значения случайной переменной - теоретическая частота появления значения случайной переменной)2 / теоретическая частота появления значения случайной переменной
критерий согласия критический = критическое значение критерия согласия Пирсона (хи квадрат) при alpha = 0,05 и степени свободы = число значений – 2
Если критерий согласия < критерий согласия критический, то
исследуемая случайная переменная принадлежит равномерному закону распределения
иначе
не принадлежит.
результат работы программы
Проверка равномерного распределения случайной переменной:
Проверка Пуассоновского распределения случайной переменной:
ЛИСТИНГ ПРОГРАММЫ
// @ts-check
/**
* Критические значения хи квадрат
* при alpha = 0.05
* для числа степеней свободы от 1 до 20
*/
const chi2Criticals = [
3.8,
6,
7.8,
9.5,
11.1,
12.6,
14.1,
15.5,
16.9,
18.3,
19.7,
21,
22.4,
23.7,
25,
26.3,
27.6,
28.9,
30.1,
31.4
]
/**
* Получить значение согласно непрерывному равномерному распределению [min, max]
* @param {number} min
* @param {number} max
*/
function uniform(min, max) {
const u = Math.random()
return min + (max - min) * u
}
/**
* Получить значение согласно дискретному равномерному распределению [min, max]
* @param {number} lambda - параметр интенсивности
*/
function poisson(lambda) {
const u = Math.random()
let p = Math.exp(-lambda)
let f = p
let x = 0
while (!(u < f)) {
p = lambda * p / (x+1)
f += p
x += 1
}
return x
}
/**
* @typedef {Object} IResultItem
* @property {number} count - наблюдаемая частота
* @property {number?} theory - теоретическая частота
*/
/**
* Проверка непрерывного равномерного распределения
* @param {Record<number, IResultItem>} result - Результат выборки сгруппированный в единичные интервалы. 10 => интервал [10, 11)
* @param {number} N - объем выборки
*/
function checkUniform(result, N) {
const intervals = Object.keys(result).map((key) => +key)
const xCenters = intervals.map((begin) => +begin + 0.5) // т.к. интервал [i, i+1], то центр i + 0.5
// Выборочное среднее
const mean = 1 / N * intervals.reduce((acc, xi, index) => {
const ni = result[xi].count
return acc + (xCenters[index] * ni)
}, 0)
// Дисперсия
const variable = 1 / N * intervals.reduce((acc, xi, index) => {
const ni = result[xi].count
return acc + (ni * ((xCenters[index] - mean)**2))
}, 0)
// Среднеквадратичное отклонение
const sd = Math.sqrt(variable)
// оценки параметров a, b равномерного распределения
const a$ = mean - Math.sqrt(3) * sd
const b$ = mean + Math.sqrt(3) * sd
// плотность
const density = 1 / (b$ - a$)
// разбитие, число значений
const s = intervals.length
// теоритические частоты
result[intervals[0]].theory = N * density * (intervals[1] - a$)
if (s > 2) {
for (let i = 1; i < s-1; i++) {
result[intervals[i]].theory = N * density * 1 // 1 взят за ширину
}
}
result[intervals[s-1]].theory = N * density * (b$ - intervals[s-1])
// число степеней свободы k = s - 3
const k = s - 3
// критерий согласия Пирсона (хи квадрат)
const chi2 = intervals.reduce((acc, xi) => {
const ni = result[xi].count
const niTheory = result[xi].theory
return acc + ((ni - niTheory)**2 / niTheory)
}, 0)
const chi2Critical = chi2Criticals[k-1]
const resultTable = {}
Object.keys(result).forEach((key) => {
resultTable[`${key}-${+key+1}`] = result[key]
})
console.table(resultTable)
console.log(`Степень свободы k = ${k}`)
console.log(`Уровень значимости alpha = 0.05`)
console.log(`Хи квадрат наблюдаемое = ${chi2}`)
console.log(`Хи квадрат критическое = ${chi2Critical}`)
console.log(`Хи2 наблюдаемое ${chi2 < chi2Critical ? '<' : '>='} Хи2 критическое => исследуемая случайная переменная ${chi2 < chi2Critical ? '' : 'не '}принадлежит закону распределения`)
}
function factorial(n) {
if (n < 2) {
return 1
}
let result = 1
for (let i = 1; i <= n; i++) {
result *= i
}
return result
}
/**
* Проверка дискретного равномерного распределения
* @param {Record<number, IResultItem>} result - Результат выборки сгруппированный в единичные интервалы. 10 => интервал [10, 11)
* @param {number} N - объем выборки
*/
function checkPoisson(result, N) {
const values = Object.keys(result).map((str) => +str)
// разбитие, число значений
const s = values.length
// выборочное среднее
const mean = 1 / N * values.reduce((acc, xi) => {
const ni = result[xi].count
return acc + (+xi * ni)
}, 0)
const expectedLambda = mean
values.forEach((value) => {
const fact = factorial(value)
const pi = Math.exp(-expectedLambda) * (expectedLambda**value) / fact
result[value].theory = pi * N
})
// критерий согласия Пирсона (хи квадрат)
const chi2 = values.reduce((acc, xi) => {
const ni = result[xi].count
const niTheory = result[xi].theory
return acc + ((ni - niTheory)**2 / niTheory)
}, 0)
// степени свободы
const k = s - 2
// хи квадрат критическое при заданном k
const chi2Critical = chi2Criticals[k-1]
console.table(result)
console.log(`lamda теоретическая = ${expectedLambda}`)
console.log(`Степень свободы k = ${k}`)
console.log(`Уровень значимости alpha = 0.05`)
console.log(`Хи квадрат наблюдаемое = ${chi2}`)
console.log(`Хи квадрат критическое = ${chi2Critical}`)
console.log(`Хи2 наблюдаемое ${chi2 < chi2Critical ? '<' : '>='} Хи2 критическое => исследуемая случайная переменная ${chi2 < chi2Critical ? '' : 'не '}принадлежит закону распределения`)
}
/* Начало */
function main() {
const a = 1
const b = 5
const result1 = {}
for (let i = 0; i < (b-a); i++) {
result1[a+i] = { count: 0 }
}
const N1 = 200
console.log(`Равномерное непрерывное распределение (опытов ${N1}):`)
for (let index = 0; index < N1; index++) {
const x = Math.trunc(uniform(a,b))
result1[x].count += 1
}
// @ts-ignore
checkUniform(result1, N1)
console.log()
const result2 = {}
const N2 = 20000
const lambda = 5
console.log(`Пуассоновское распределение (lambda = ${lambda}, опытов ${N2}):`)
for (let index = 0; index < N2; index++) {
const x = poisson(lambda)
if (result2[x]) {
result2[x].count += 1
} else {
result2[x] = { count: 1 }
}
}
// @ts-ignore
checkPoisson(result2, N2)
}
main()
Вывод
В ходе лабораторной работы были получены навыки генерации случайных переменных. Также были получены навыки проверки по критерию согласия принадлежность исследуемой случайной переменной закону распределения.