КМ МО-317 Ибрагимова К.Б. ЛР1
.docxУФИМСКИЙ ГОСУДАРСТВЕННЫЙ АВИАЦИОННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
ФАКУЛЬТЕТ ИНФОРМАТИКИ И РОБОТОТЕХНИКИ
КАФЕДРА ВЫЧИСЛИТЕЛЬНОЙ МАТЕМАТИКИ И КИБЕРНЕТИКИ
|
|
|
||
|
УТВЕРЖДАЮ Проректор университета по научной работе ФИО |
|||
|
|
|
||
|
"___" ______________ _______г. |
|||
|
|
|
||
Лабораторная работа № 1
«Генерирование случайных переменных»
|
||||
|
||||
по предмету: КОМПЬЮТЕРНОЕ МОДЕЛИРОВАНИЕ |
||||
Преподаватель |
|
А. Ф. Валеева |
||
|
|
|
||
|
|
|
||
|
|
|
||
Исполнитель |
|
К. Б. Ибрагимова |
||
|
|
|
||
Уфа – 2021 |
ЗАДАНИЕ
Выбрать для программирования одну непрерывную случайную переменную и одну дискретную. Проверить по критерию согласия принадлежность исследуемой случайной переменной закону распределения.
Ход работы
Для реализации выбрана показательная и Пуассоновская случайные переменные.
Реализуем получение экспоненциальной случайной переменной на отрезке с заданным параметром lambda.
Входные данные:
lambda – параметр, который можно интерпретировать как среднее число наступлений события в единицу времени
Выходные данные:
result – значение показательной случайной переменной с заданным параметром lambda.
Алгоритм:
1. u = Uniform [0, 1]
2. result = (-1 / lambda) * ln(1 - u)
Далее реализуем проверку принадлежности показательной случайной переменной показательному распределению.
Входные данные:
lambda – параметр показательного распределения
ширина интервала – значение длины наблюдаемого интервала
N – количество испытаний
Выходные данные:
критерий согласия – значение критерия согласия Пирсона
критерий согласия критический – критическое значение критерия согласия Пирсона при alpha = 0,05.
Алгоритм проверки:
Создаем ассоциативный массив испытаний, ключами которого являются значения начал интервалов, а значением является частота появления случайной переменной на интервале [ключ, ключ + ширина интервала].
счетчик испытаний = 0
Пока количество испытаний меньше N:
случайная переменная = показательная случайная переменная с заданным параметром lambda
целое = целая часть от значения случайной переменной
ключ = целое – (целое % ширина интервала)
Если в ассоциативном массиве испытаний содержится получившийся ключ, то
увеличиваем значение по данному ключу на 1.
иначе
по данному ключу заносим 1.
Увеличиваем счетчик испытаний на 1
сумма = 0
Перебираем ключи ассоциативного массива испытаний:
частота появления значения на интервале = значение в ассоциативном массиве испытаний по данному ключу
сумма += (ключ + (ширина интервала / 2)) * частота появления значения на интервале
выборочное среднее = сумма / N
сумма = 0
теоретическая lambda = 1 / выборочное среднее
число значений = количество ключей в ассоциативном массиве
Создаем ассоциативный массив теоретических испытаний, являются значения начал интервалов, а значением является теоретическая частота появления случайной переменной на интервале [ключ, ключ + ширина интервала].
Перебираем ключи ассоциативного массива испытаний:
вероятность = (число е в степени (минус ожидаемое среднее * ключ)) - (число е в степени (минус ожидаемое среднее * (ключ + ширина интервала)))
Заносим в ассоциативный массив теоретических испытаний по текущему ключу значение = вероятность * N
критерий согласия = 0
Перебираем ключи ассоциативного массива испытаний
частота появления на интервале = значение в ассоциативном массиве испытаний по данному ключу
теоретическая частота появления на интервале = значение в ассоциативном массиве теоретических испытаний по данному ключу
критерий согласия += (частота появления на интервале - теоретическая частота появления в интервале) в квадрате / теоретическая частота
критерий согласия критический = критическое значение критерия согласия Пирсона (χ2) при alpha = 0,05 и степени свободы = число значений – 2
Если критерий согласия < критерия согласия критического, то
исследуемая случайная переменная принадлежит показательному закону распределения
иначе
не принадлежит.
Реализуем получение Пуассоновской случайной переменной с параметром 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
Если критерий согласия < критерий согласия критический, то
исследуемая случайная переменная принадлежит Пуассоновскому закону распределения
иначе
не принадлежит.
результат работы программы
Показательное распределение случайной переменной:
Пуассоновское распределение случайной переменной:
ЛИСТИНГ ПРОГРАММЫ
/**
* Критические значения хи квадрат при alpha = 0.05 (от 1 до 20)
*/
const chiSqrCriticals = {
1: 3.8,
2: 6,
3: 7.8,
4: 9.5,
5: 11.1,
6: 12.6,
7: 14.1,
8: 15.5,
9: 16.9,
10: 18.3,
11: 19.7,
12: 21,
13: 22.4,
14: 23.7,
15: 25,
16: 26.3,
17: 27.6,
18: 28.9,
19: 30.1,
20: 31.4
}
/**
* Получить значение согласно экспоненциальному распределению
* @param {number} lambda - параметр
*/
function exponential(lambda) {
const u = Math.random()
const x = (-1 / lambda) * Math.log(1 - u)
return x
}
/**
* Получить значение согласно дискретному Пуассоновскому распределению
* @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 {Map<number, IResultItem>} result - Результат выборки сгруппированный в интервалы. 10 => интервал [10, 10+widthInterval)
* @param {number} N - объем выборки
* @param {number} widthInterval - размер наблюдаемого интервала
*/
function checkExponential(result, N, widthInterval) {
const intervals = Array.from(result.keys()).sort((a,b) => a-b) // начала интервалов шириной widthInterval отсортированные
const xCenters = intervals.map((begin) => begin + widthInterval / 2)
// Выборочное среднее
const mean = 1 / N * intervals.reduce((acc, xi, index) => {
const ni = result.get(xi).count
return acc + (xCenters[index] * ni)
}, 0)
// Оценочная lambda
const theoryLambda = 1 / mean
intervals.forEach((beginInterval) => {
const pi = Math.E**(-theoryLambda * beginInterval) - Math.E**(-theoryLambda * (beginInterval + widthInterval))
result.get(beginInterval).theory = pi * N
})
// разбитие, число значений
const s = intervals.length
// число степеней свободы k = s - 2
const k = s - 2
// критерий согласия Пирсона (хи квадрат)
const chi2 = intervals.reduce((acc, xi) => {
const ni = result.get(xi).count
const niTheory = result.get(xi).theory
return acc + ((ni - niTheory)**2 / niTheory)
}, 0)
const resultTable = {}
intervals.forEach((beginInterval) => {
resultTable[`${beginInterval}-${beginInterval+widthInterval}`] = result.get(beginInterval)
})
console.table(resultTable)
console.log(`lambda теоретическая = ${theoryLambda}`)
console.log(`Степень свободы k = ${k}`)
console.log(`Уровень значимости alpha = 0.05`)
console.log(`Хи квадрат наблюдаемое = ${chi2}`)
console.log(`Хи квадрат критическое = ${chiSqrCriticals[k]}`)
console.log(`Хи2 наблюдаемое ${chi2 < chiSqrCriticals[k] ? '<' : '>='} Хи2 критическое => исследуемая случайная переменная ${chi2 < chiSqrCriticals[k] ? '' : 'не '}принадлежит закону распределения`)
}
function factorial(n) {
if (n < 2) {
return 1
}
let result = 1
for (let i = 1; i <= n; i++) {
result *= i
}
return result
}
/**
* Проверка дискретного равномерного распределения
* @param {Map<number, IResultItem>} result - Результат выборки сгруппированный в единичные интервалы. 10 => интервал [10, 11)
* @param {number} N - объем выборки
*/
function checkPoisson(result, N) {
const values = Array.from(result.keys())
// разбитие, число значений
const s = values.length
// выборочное среднее
const mean = 1 / N * values.reduce((acc, xi) => {
const ni = result.get(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.get(value).theory = pi * N
})
// критерий согласия Пирсона (хи квадрат)
const chi2 = values.reduce((acc, xi) => {
const ni = result.get(xi).count
const niTheory = result.get(xi).theory
return acc + ((ni - niTheory)**2 / niTheory)
}, 0)
// степени свободы
const k = s - 2
console.table(Object.fromEntries([...result]))
console.log(`lambda теоретическая = ${expectedLambda}`)
console.log(`Степень свободы k = ${k}`)
console.log(`Уровень значимости alpha = 0.05`)
console.log(`Хи квадрат наблюдаемое = ${chi2}`)
console.log(`Хи квадрат критическое = ${chiSqrCriticals[k]}`)
console.log(`Хи2 наблюдаемое ${chi2 < chiSqrCriticals[k] ? '<' : '>='} Хи2 критическое => исследуемая случайная переменная ${chi2 < chiSqrCriticals[k] ? '' : 'не '}принадлежит закону распределения`)
}
function begin() {
const result1 = new Map()
const N1 = 200
const lambda1 = 0.1
const widthInterval = 5 // ширина наблюдаемого интервала
console.log(`Экспоненциальное распределение (lambda = ${lambda1}, опытов ${N1}):`)
let x, startInterval
for (let index = 0; index < N1; index++) {
x = exponential(lambda1)
const integralX = Math.trunc(x)
startInterval = integralX - (integralX % widthInterval) // начало интервал 194.7 => 190 при ширине интервала = 5
if (result1.has(startInterval)) {
result1.get(startInterval).count += 1
} else {
result1.set(startInterval, { count: 1 })
}
}
checkExponential(result1, N1, widthInterval)
console.log()
const result2 = new Map()
const N2 = 200
const lambda2 = 5
console.log(`Пуассоновское распределение (lambda = ${lambda2}, опытов ${N2}):`)
for (let index = 0; index < N2; index++) {
x = poisson(lambda2)
if (result2.has(x)) {
result2.get(x).count += 1
} else {
result2.set(x, { count: 1 })
}
}
checkPoisson(result2, N2)
}
begin()
Вывод
В ходе лабораторной работы были получены навыки генерации случайных переменных. Также были получены навыки проверки по критерию согласия принадлежность исследуемой случайной переменной закону распределения.