Модель генератора последовательности случайных чисел

Тип работы:
Курсовая
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

Содержание

  • Введение 2
  • 1. Постановка задачи 3
  • 2. Разработка ГСЧ 4
    • 2.1 ГСЧ 1А и ГСЧ1Б 4
    • 2.2 ГСЧ 2А и ГСЧ2Б 6
    • 2.3 Оценка качества ГСЧ 9
  • 3. Разработка имитационной модели объекта 15
    • 3.1 Разработка структурной схемы 15
    • 3.2 Расчет статистических показателей 15
    • 3.3 Разработка алгоритмической модели 16
  • 4. Работа программы 18
  • 5. Анализ результатов моделирования 20
  • Заключение 24
  • Приложение 25

Введение

вычислительное устройство информация мультиплексный

При проектировании вычислительных устройств возникает необходимость в проверке работоспособности, оценке качества, надежности функционирования и определения статистических параметров разрабатываемого устройства. Но поскольку необходимо исследовать вычислительную систему до ее фактического изготовления, то прибегают к построению модели устройства. На этой модели наблюдают за работой проектируемой вычислительной системы и собирают и анализируют ее статистические параметры. Преимущество использования модели для изучения характеристик объекта заключается в возможности проанализировать за короткий промежуток времени большое количество разнообразных ситуаций, возможных в объекте. Использование для этого фактического устройства позволило бы вести сбор статистических параметров только в масштабе реального времени. А при использовании программной модели имеется возможность нахождения статистических параметров практически мгновенно.

В данной работе осуществляется построение программной модели системы обработки информации, содержащей мультиплексный канал и ЭВМ. Для работы с моделью пользователю предоставляется удобный графический интерфейс. Имеется возможность записи событий, происходящих в системе, и вычисления статистических параметров.

Программная модель создавалась с использованием среды программирования C++ Builder.

1. Постановка задачи

Система обработки информации содержит мультиплексный канал и ЭВМ. Сигналы от датчика поступают в канал через интервалы времени, распределённые по равномерному закону в диапазоне от 20 сек. до 40 сек. В канале они буферизуются и предварительно обрабатываются, ёмкость накопителя 10 величин сигналов. Обработка в ЭВМ осуществляется в течение интервала времени, распределенного по равномерному закону, в диапазоне от 15 до 45 сек.

Время безотказной работы и время восстановления ЭВМ распределены по закону Вейбулла-Гнеденко. Среднее значение времени безотказной работы 36 часов, параметр формы распределения = 0,95; среднее времени восстановления 20 мин, значение параметра формы распределения =0,85. Во время отказа ЭВМ обслуживание сигналов датчика прекращается; заявка, обслуживание которой было прервано, возвращается в начало очереди, время обслуживания обнуляется.

Разработать:

1. Модели датчика информационных сигналов и времени обслуживания сигнала датчика в ЭВМ как генераторы последовательности случайных величин, методом обратной функции, с проверкой качества последовательности по гистограмме распределения.

2. Модели генераторов последовательности случайных чисел, имитирующих время безотказной работы и время восстановления ЭВМ, с использованием метода Бусленко, с проверкой качества последовательности по гистограмме распределения.

3. Смоделировать работу системы в течение времени, составляющего 15 дней. Определить вероятностно-статистические характеристики модели.

2. Разработка ГСЧ

Поскольку функционирование данной вычислительной системы подразумевает поступление внешних сигналов от датчиков через случайные моменты времени, и продолжительность обработки данных на ЭВМ тоже не одинакова для всех сообщений, то для имитации этих процессов потребуются генераторы случайных чисел. Для задания времени безотказной работы ЭВМ и времени, требующегося на ее восстановление, также применяются генераторы случайных величин.

Из условия известно, что сигналы от датчиков поступают через интервалы времени, распределенные равномерно в диапазоне от 20 до 40 секунд. Генератор, служащий для имитации работы датчиков, назовем ГСЧ 1А. Обработка в ЭВМ осуществляется в течение интервала времени, распределенного по равномерному закону, в диапазоне от 15 до 45 сек. Генератор, применяемый для нахождения интервала времени, необходимого на обработку сигналов, назовем ГСЧ 1Б. Время безотказной работы ЭВМ, распределенное по закону Вейбулла-Гнеденко с параметром формы распределения в = 0,95 и максимальным значением 36 часов, будет имитировать генератор с названием ГСЧ 2А. Время восстановления ЭВМ, распределенное по этому же закону, но с параметром в = 0,85 и максимальным значением 20 минут, будет определяться генератором ГСЧ 2Б.

2.1 ГСЧ 1А и ГСЧ1Б

Для разработки генератора последовательности случайных чисел, имитирующего сигналы от датчиков, применим метод обратной функции.

В итоге получим:

,

где xi — число из базовой последовательности от 0 до 1, a и b — минимальное и максимальное генерируемые значения соответственно. Подставив заданные значения a = 20, b = 40 получим выражение для ГСЧ 1А:

yi = 20 + 20xi,

а подставив значения a = 15, b = 45 получим выражение для ГСЧ 1Б:

yi = 15 + 30xi.

На основании этих выражений напишем простейшие функции, реализующие работу данных генераторов:

/* Функция генерирует числа от 20 до 40, распределенные по равномерному закону (сигналы от датчиков) */
double GenRand1a()
{
return 20.0 + 20.0 * (static_cast< double>(rand()) / RAND_MAX); 
}
/* Функция генерирует числа от 15 до 45, распределенные по
равномерному закону (обработка в ЭВМ) */
double GenRand1b()
{
return 15.0 + 30.0 * (static_cast< double>(rand()) / RAND_MAX); 
}

2.2 ГСЧ 2А и ГСЧ2Б

Время безотказной работы ЭВМ и время восстановления будут определяться значениями, полученными ГСЧ 2А и ГСЧ 2Б соответственно. Для реализации этих ГСЧ применим метод Бусленко. Суть метода состоит в том, что площадь под кривой закона распределения на заданном участке делится на некоторое число одинаковых по площади прямоугольников. Распределение получается таким, что чем больше вероятность выпадения некоторого значения, тем большее скопление прямоугольников будет в этом месте. Для маловероятных чисел прямоугольников будет мало. Таким образом, если выбор номера прямоугольника осуществляется с равной вероятностью для каждого из прямоугольников, то чаще будем попадать на те прямоугольники, которые соответствуют более часто встречающимся числам для данного закона распределения. Для чисел, чья вероятность выпадения мала, наоборот прямоугольники будут попадаться редко, поскольку их мало (но они более широкие).

После того, как будет выбран номер прямоугольника (интервала) с помощью генератора равномерно распределенных величин, мы получим интервал, на котором лежит генерируемое значение. Для его уточнения прибавим к левой границе этого интервала равномерно распределенное число от 0 до ширины интервала (прямоугольника).

Если обозначить через ai левую границу i-го интервала, то ai+1 будет правой границей этого интервала. Значение из базовой последовательности от 0 до 1 обозначим через ri. Формула для генерации псевдослучайных чисел по методу Бусленко в этом случае будет выглядеть следующим образом:

xi = ai + (ai+1 — ai)ri.

Теперь рассмотрим, как описанный выше механизм работы генератора реализован в программе. Перед применением генератора необходимо произвести его инициализацию, которая как раз и подразумевает процесс разбиения промежутка генерации на равные по площади прямоугольники, этот процесс выполняется в функции Init ().

void GenRand2: :Init()
{
double pos = x1; 
double sq = 0, sq1; 
/* Вычислим площадь под графиком VeibulZakon() */
do
{
sq += VeibulZakon(pos) * step; 
pos += step; 
} while (pos < x2); 
// Найдем единичную площадь, т. е. площадь одного прямоугольника
sq1 = sq / n; 
if (granica != NULL)
{
delete [] granica; 
granica = NULL; 
}
granica = new double[n + 1]; 
granica[0] = x1; 
pos = x1; 
int i; 
/* Найдем границы интервалов, путем разделения всей имеющейся
площади по площадям отдельных прямоугольников */
for (i = 1; i < n; i++)
{
sq = 0; 
do
{
sq += VeibulZakon(pos) * step; 
pos += step; 
} while (sq < sq1); 
granica[i] = pos; 
}
granica[n] = x2; 
IsInit = true; 
}

Непосредственная генерация значений производится функцией Generate (), реализованной следующим образом:

double GenRand2: :Generate()
{
if (!IsInit)
Init(); 
int interval; 
/* Определяем номер требуемого интервала - это
случайное число от 0 до n - 1 */
interval = rand() % n; 
double left_val, right_val; 
/* Найдем правую и левую границы интервалов */
left_val = granica[interval]; 
right_val = granica[interval + 1]; 
// Генерируем число на полученном интервале
double value = (static_cast< double>(rand()) / RAND_MAX) *
(right_val - left_val) + left_val; 
return value; 
}

Следует заметить, что процедура инициализации генератора требует больших затрат машинного времени, но последующая генерация значений осуществляется очень быстро. Разработанный класс применяется как для ГСЧ 2А, так и для ГСЧ 2Б, достаточно объявить соответствующие переменные с разными параметрами:

Generator2a = new GenRand2(0. 95, 36, 36, 42); 
Generator2b = new GenRand2(0. 85, 20, 20, 27); 

2.3 Оценка качества ГСЧ

Проверку качества полученных генераторов будем проводить по гистограмме распределения: построим гистограмму распределения и вычислим площадь отклонений ее значений от идеальной гистограммы распределения для соответствующего закона.

Для этого сгенерируем последовательность псевдослучайных величин определенной длины, например из 3000 значений. Разобьем интервал от минимального до максимального генерируемого значения на некоторое количество интервалов равной ширины, например на 10. Распределим сгенерированные значения по принадлежности к тому интервалу, в котором они лежат. Подсчитаем количество значений, лежащих в каждом интервале, и на основе этих данных построим гистограмму. Ширина столбцов гистограммы будет равна

,

где x1, x2 — соответственно минимальное и максимальное генерируемые значения, а N — количество интервалов разбиения. Высота столбца будет рассчитываться по формуле:

,

где ni — количество значений, лежащих в i-том интервале, n — общее количество сгенерированных значений. Площадь столбца вычисляется по формуле

.

Для идеальной гистограммы распределения равномерного закона высота и площадь столбцов будут одинаковыми и рассчитываются следующим образом:

.

Площадь столбов идеальной гистограммы для закона Вейбулла-Гнеденко будет определяться по формуле:

,

где i — номер интервала, xi и xi + 1 — начало и конец i-го интервала.

Посчитаем по приведенным выше формулам площади столбцов для сгенерированной последовательности и для идеальной последовательности и рассчитаем площадь отклонений:

,

где Sидi — площадь столбца для идеальной последовательности, Si — площадь столбца для проверяемой последовательности. На основании площади отклонений вычислим погрешность распределения по формуле:

,

где Sобщ — суммарная площадь всех столбцов, равная 1.

Описанный алгоритм вычисления погрешности распределения реализован в программе, также имеется возможность построения гистограммы распределения. На рисунке Рисунок 1 показан расчет погрешности распределения для 10 интервалов разбиения и 3000 генерируемых значений для генератора ГСЧ 1А. На рисунке Рисунок 2 показан аналогичный расчет для ГСЧ 1Б. Как видно из этих рисунков, полученные значения погрешности распределения не превышают рекомендуемого значения для равномерного закона распределения, равного 5%. Это позволяет сделать вывод, что последовательности значений, получаемые генераторами ГСЧ 1А и ГСЧ 1Б, являются достаточно качественными. На рисунках Рисунок 3 и Рисунок 4 изображены гистограммы распределения для ГСЧ 1А и ГСЧ 1Б соответственно, построенные по сгенерированным значениям.

Расчет погрешности распределения для ГСЧ 2А показан на рисунке Рисунок 5, а на рисунке Рисунок 6 приведена гистограмма распределения, построенная на основе сгенерированных значений. Аналогичные сведения для ГСЧ 2Б приведены на рисунках Рисунок 7 и Рисунок 8. Как видно по гистограммам, столбцы, построенные по реально сгенерированным значениям, мало отличаются от идеальных. Это позволяет говорить о высоком качестве спроектированных генераторов.

Рисунок 1

Рисунок 2

Рисунок 3

Рисунок 4

Рисунок 5

Рисунок 6

Рисунок 7

Рисунок 8

3. Разработка имитационной модели объекта

3.1 Разработка структурной схемы

Сообщения от датчиков сигналов поступают в канал, где они буферизируются и предварительно обрабатываются перед обработкой на ЭВМ. Если ЭВМ находится в активном состоянии (не сломана) и не занята обработкой, то она считывает сообщение из мультиплексного канала и приступает к его обработке. Если ЭВМ сломалась, и во время поломки обрабатывала сообщение, то обработка этой заявки прекращается, и она направляется обратно в канал, в начало очереди. В то время, когда ЭВМ находится на восстановлении, обработка сигналов не ведется. После восстановления ЭВМ обработка сигналов возобновляется.

Мультиплексный канал реализован по принципу очереди FIFO: первый зашел, первый вышел. Максимальное количество заявок, хранимое в мультиплексном канале, равно 10. Если канал полностью заполнен и поступают новые заявки, то старые заявки удаляются из конца очереди. Структурная схема модели изображена на рисунке

Рисунок 9

3.2 Расчет статистических показателей

В разрабатываемой программе будет вестись расчет статистических показателей эффективности моделируемой системы. Приведем формулы, применяемые для вычисления этих показателей.

Коэффициент готовности ЭВМ будет определяться как отношение времени нахождения ЭВМ в активном состоянии (когда она не сломана) ко времени работы системы:

.

Коэффициент загрузки ЭВМ найдем как отношение времени обработки сигналов на ЭВМ ко времени нахождения ЭВМ в активном состоянии (когда ЭВМ способна этим заниматься):

.

Показатель эффективности будем рассчитывать путем деления количества обработанных сигналов, на количество сигналов, поступивших от датчика:

.

3.3 Разработка алгоритмической модели

На основании структурной схемы построим алгоритмическую модель вычислительной системы, она показана на рисунке Рисунок 10. Особенностью подхода при проектировании алгоритмической модели является использование объектно-ориентированного программирования, т. е. датчик, мультиплексный канал и ЭВМ представлены в виде объектов, которые взаимодействуют между собой. Это позволяет существенно упростить понимание имитационной модели, поскольку достигается высокий уровень абстрагирования. А все особенности работы скрыты внутри реализации классов. Не погружаясь в техники программирования, можно понять работу этой модели.

Рисунок 10

4. Работа программы

При запуске программы на экране появляется окно, где пользователь может задать необходимые параметры моделирования, запустить выполнение моделирования, или, нажав на кнопку Генераторы, ознакомится с работой ГСЧ.

Рассмотрим имеющиеся настройки. Если необходимо поучить отчет о произошедших в системе событиях, то надо поставить галочку Вести запись событий. У этой опции имеется подопция До 10 000 сек. Поскольку запись всех событий за все время моделирования происходит достаточно долго, то поставив данную галочку, пользователь получит только события, произошедшие с 0 до 10 000 секунду.

Когда будут выбраны необходимые опции, можно запустить процесс моделирования, для этого нужно нажать на кнопку Запуск. После завершения процесса моделирования на экране появится информация о модели и рассчитанные статистические показатели. На рисунке Рисунок 11 показан пример работы программы.

Ознакомление с работой генераторов псевдослучайных величин можно осуществить нажатием кнопки Генераторы, при этом появится окно для подсчета статистических параметров работы генераторов.

Временная диаграмма, построенная по результатам моделирования, изображена на рисунке Рисунок 12. Исходные данные для построения временной диаграммы были получены из программы, запущенной с опцией Вести запись событий:

25: Поступил сигнал от датчика
25: Сигнал добавлен в канал
25: Сигнал прочитан из канала
25: Сигнал запущен на обработку
49: Обработка сигнала завершена
60: Поступил сигнал от датчика
60: Сигнал добавлен в канал
60: Сигнал прочитан из канала
60: Сигнал запущен на обработку
83: Обработка сигнала завершена
85: Поступил сигнал от датчика
85: Сигнал добавлен в канал
85: Сигнал прочитан из канала
85: Сигнал запущен на обработку
114: Поступил сигнал от датчика
114: Сигнал добавлен в канал
124: Обработка сигнала завершена
125: Сигнал прочитан из канала
125: Сигнал запущен на обработку
136: Поступил сигнал от датчика
136: Сигнал добавлен в канал

Рисунок 11

Рисунок 12

5. Анализ результатов моделирования

Запустим программу на моделирование и исследуем выданные результаты. В поле На момент завершения моделирования отображено состояние модели в последнюю секунду имитации. Рассмотрим эти сведения:

Прошло времени: 1 296 000

Количество сигналов, сгенерированных датчиками: 42 473

Количество сигналов, поступивших в канал (от датчиков и от ЭВМ): 42 482

Количество сигналов, удаленных из канала из-за переполнения: 1728

Количество сигналов, поступивших из канала в ЭВМ: 40 750

Количество сигналов, направленных обратно в канал из-за поломки ЭВМ: 9

Количество сигналов, обработанных в ЭВМ: 40 740

Количество сигналов, находящихся в канале: 4

ЭВМ вышла из строя, раз: 9

ЭВМ была восстановлена, раз: 9

Состояние ЭВМ: активна

ЭВМ обрабатывает сигнал: да

Время нахождения ЭВМ в активном состоянии: 1 284 663

Время нахождения ЭВМ в состоянии восстановления: 11 337

Время фактической обработки сигналов на ЭВМ: 1 243 722

Время, когда ЭВМ была в активном состоянии, но не обрабатывала сигналы: 40 941

Видно, что количество сигналов поступивших в канал, больше количества сгенерированных датчиками сигналов. Это свидетельствует о том, что при поломке ЭВМ обрабатываемый сигнал возвращался обратно в канал. Найдем разность между количеством сигналов, поступивших в канал и количеством сигналов сгенерированных датчиками 42 482 — 42 473 = 9. Теперь обратим внимание на строку

Количество сигналов, направленных обратно в канал из-за поломки ЭВМ: 9

Это говорит о том, что подсчет параметров в программе ведется правильно. А то, что количество сигналов, вернувшихся в канал из-за поломки ЭВМ, ничтожно мало по сравнению с общим количеством сгенерированных сигналов означает, что поломки в ЭВМ происходят достаточно редко и даже если не возвращать заявки обратно в канал, а просто удалять, это не приведет к заметному уменьшению показателя эффективности.

Теперь обратим внимание на строку

Количество сигналов, удаленных из канала из-за переполнения: 1728

Это число не так уж и мало, как предыдущее, но все равно не велико относительно общего числа полученных сигналов от датчиков. Попробуем найти причину переполнения канала, для этого прочитаем запись событий:

... 
130848: Поступил сигнал от датчика
130848: Сигнал добавлен в канал
130866: Обработка сигнала завершена
130867: Сигнал прочитан из канала
130867: Сигнал запущен на обработку
130884: Поступил сигнал от датчика
130884: Сигнал добавлен в канал
130901: Поломка ЭВМ
130901: Обрабатываемый сигнал направлен обратно в канал
130901: Сигнал добавлен в канал
130919: Поступил сигнал от датчика
130919: Сигнал добавлен в канал
130919: Удаление сигнала из-за переполнения канала
130948: Поступил сигнал от датчика
130948: Сигнал добавлен в канал
130948: Удаление сигнала из-за переполнения канала
130985: Поступил сигнал от датчика
130985: Сигнал добавлен в канал
130985: Удаление сигнала из-за переполнения канала
131006: Поступил сигнал от датчика
131006: Сигнал добавлен в канал
131006: Удаление сигнала из-за переполнения канала
131027: Поступил сигнал от датчика
131027: Сигнал добавлен в канал
131027: Удаление сигнала из-за переполнения канала
131053: Поступил сигнал от датчика
131053: Сигнал добавлен в канал
131053: Удаление сигнала из-за переполнения канала
131074: Поступил сигнал от датчика
131074: Сигнал добавлен в канал
131074: Удаление сигнала из-за переполнения канала
131097: Поступил сигнал от датчика
131097: Сигнал добавлен в канал
131097: Удаление сигнала из-за переполнения канала
131124: Поступил сигнал от датчика
131124: Сигнал добавлен в канал
131124: Удаление сигнала из-за переполнения канала
131145: Поступил сигнал от датчика
131145: Сигнал добавлен в канал
131145: Удаление сигнала из-за переполнения канала
131183: Поступил сигнал от датчика
131183: Сигнал добавлен в канал
131183: Удаление сигнала из-за переполнения канала
... 

Видно, что большое количество сообщений удаляется после поломки ЭВМ, т. к. она перестает обрабатывать сигналы, а от датчиков они все равно поступают в канал, а его емкость ограничена.

Теперь обратим внимание на статистические параметры модели, отображенные в нижней части окна программы:

Коэффициент готовности ЭВМ: 0,991252
Коэффициент загрузки ЭВМ: 0,968131
Показатель эффективности: 0,959198

Видно, что коэффициент готовности ЭВМ очень высок, это связано с тем, что ЭВМ редко ломается и быстро восстанавливается. За все время моделирования ЭВМ ломалась 9 раз, а время ее бездействия составило 11 337 секунд (это чуть больше трех часов), а общее время моделирования — 15 суток.

Коэффициент загрузки ЭВМ также достаточно высок, это означает, что в данной системе сигналы от датчиков поступают часто и ЭВМ редко простаивает.

Основным параметром, по которому будем судить об эффективности всей системы, является показатель эффективности, равный 0,959 198. Это означает, что 96% заявок обрабатываются, а лишь 4% теряется. Данные характеристики являются неплохими для вычислительной системы, если, конечно, она не задействована в военной области, медицине, авиации, космических полетах и других ответственных сферах.

Заключение

В ходе выполнения данной курсовой работы были разработаны четыре генератора псевдослучайных величин: ГСЧ 1А, ГСЧ 1Б, ГСЧ 2А, ГСЧ 2Б. Проверено качество их работы по гистограмме распределения. Все генераторы показали хорошие результаты. Погрешность распределения для генератора ГСЧ 1А оказалась равной 2,93%, для генератора ГСЧ 1Б — 3,47%, для ГСЧ 2А — 3,15%, для ГСЧ 2Б — 2,40%.

Разработана структурная схема моделируемой системы. После чего с использованием генераторов была построена алгоритмическая модель системы. На основе алгоритмической модели разработана программа, позволяющая имитировать работу системы. С помощью данной программы были получены статистические параметры работы модели. Показатель эффективности работы системы равен 96%, что является очень хорошим результатом. Коэффициент загрузки ЭВМ составил 97%, что означает практически полное использование ресурсов ЭВМ. Коэффициент готовности ЭВМ оказался равным 99%, это может говорить о том, что поломки ЭВМ не приводят к длительному простою.

Оценивая, в общем, состояние системы, можно сказать, что ее применение в неопасных областях оправдано и достаточно эффективно.

Приложение

Исходный код программы.

//---------------------------------------------------------------------------

#include < vcl. h>

#include < stdlib. h>

#include < math. h>

#pragma hdrstop

#include «GenUnit. h»

#include «GistUnit. h»

#include «Gist2Unit. h»

//---------------------------------------------------------------------------

#pragma package (smart_init)

#pragma resource «*. dfm»

TGenForm *GenForm;

// Массив, содержащий сгенерированные значения случайных чисел

double *MyNums;

/* Массив, хранящий количество чисел, попавших в данный интервал.

Пример: N чисел попадает в интервал с индексом i:

Interval[i] = N */

int *Interval;

// Идеальная высота столбцов диаграммы

double *Ideal;

/* Количество интервалов, количество генерируемых чисел */

int Intervals, Kolvo;

// Ширина интервала

double Delta;

GenRand2 *Generator2a;

GenRand2 *Generator2b;

//---------------------------------------------------------------------------

__fastcall TGenForm: :TGenForm (TComponent* Owner)

: TForm (Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TGenForm: :FormCreate (TObject *Sender)

{

randomize ();

IntervalInfoGrid-> Cells[0][0] = «Интервал»;

IntervalInfoGrid-> ColWidths[0] = 90;

IntervalInfoGrid-> Cells[1][0] = «Количество»;

IntervalInfoGrid-> Cells[2][0] = «Высота»;

IntervalInfoGrid-> Cells[3][0] = «Площадь»;

StatistGrid-> Cells[0][0] = «Интервал»;

StatistGrid-> ColWidths[0] = 90;

StatistGrid-> Cells[1][0] = «Кол-во»;

StatistGrid-> ColWidths[1] = 35;

StatistGrid-> Cells[2][0] = «Высота»;

StatistGrid-> ColWidths[2] = 43;

StatistGrid-> Cells[3][0] = «Площадь»;

StatistGrid-> ColWidths[3] = 50;

StatistGrid-> Cells[4][0] = «Ид. площадь»;

MyNums = NULL;

Interval = NULL;

Generator2a = new GenRand2(0. 95, 36, 36, 42);

Generator2b = new GenRand2(0. 85, 20, 20, 27);

/*Generator2a-> Init ();

Generator2b-> Init ();*/

}

//---------------------------------------------------------------------------

/* Функция генерирует числа от 20 до 40, распределенные по

равномерному закону (сигналы от датчиков) */

double GenRand1a ()

{

return 20.0 + 20.0 * (static_cast< double>(rand ()) / RAND_MAX);

}

/* Функция генерирует числа от 15 до 45, распределенные по

равномерному закону (обработка в ЭВМ) */

double GenRand1b ()

{

return 15.0 + 30.0 * (static_cast< double>(rand ()) / RAND_MAX);

}

double GenRand2: :VeibulZakon (double x)

{

if (x > c)

return beta * pow (x — c, beta — 1) * exp (-pow (x — c, beta));

else

return 0;

}

GenRand2: :GenRand2()

{

granica = NULL;

n = 500;

step = 0. 1;

c = 0;

beta = 0. 95;

x1 = 36;

x2 = 46;

IsInit = false;

}

GenRand2: :GenRand2(double my_beta, double my_c,

double my_x1, double my_x2)

{

granica = NULL;

n = 500;

step = 0. 1;

beta = my_beta;

c = my_c;

x1 = my_x1;

x2 = my_x2;

IsInit = false;

}

void GenRand2: :Init ()

{

double pos = x1;

double sq = 0, sq1;

/* Вычислим площадь под графиком VeibulZakon () */

do

{

sq += VeibulZakon (pos) * step;

pos += step;

} while (pos < x2);

// Найдем единичную площадь, т. е. площадь одного прямоугольника

sq1 = sq / n;

if (granica ≠ NULL)

{

delete [] granica;

granica = NULL;

}

granica = new double[n + 1];

granica[0] = x1;

pos = x1;

int i;

/* Найдем границы интервалов, путем разделения всей имеющейся

площади по площадям отдельных прямоугольников */

for (i = 1; i < n; i++)

{

sq = 0;

do

{

sq += VeibulZakon (pos) * step;

pos += step;

} while (sq < sq1);

granica[i] = pos;

}

granica[n] = x2;

IsInit = true;

}

GenRand2: :~GenRand2()

{

if (granica ≠ NULL)

{

delete [] granica;

granica = NULL;

}

}

double GenRand2: :Generate ()

{

if (!IsInit)

Init ();

int interval;

/* Определяем номер требуемого интервала — это

случайное число от 0 до n — 1 */

interval = rand () % n;

double left_val, right_val;

/* Найдем правую и левую границы интервалов */

left_val = granica[interval];

right_val = granica[interval + 1];

// Генерируем число на полученном интервале

double value = (static_cast< double>(rand ()) / RAND_MAX) *

(right_val — left_val) + left_val;

return value;

}

double GenRand2: :Integral (double x1, double x2)

{

const double step = 0. 001;

double x, S;

S = 0;

for (x = x1; x < x2; x = x + step)

{

S += VeibulZakon (x) * step;

}

return S;

}

void __fastcall TGenForm: :btGenVal1Click (TObject *Sender)

{

// Число интервалов разбиения

Intervals = StrToIntDef (txtIntervals-> Text, -1);

// Количество генерируемых значений

Kolvo = StrToIntDef (txtKolvo-> Text, -1);

if (Intervals == -1 || Kolvo == -1)

{

MessageDlg («Введено неверное значение», mtError,

TMsgDlgButtons () < < mbOK, 0);

return;

}

if ((MyNums ≠ NULL) || (Interval ≠ NULL))

{

delete [] MyNums;

delete [] Interval;

MyNums = NULL;

Interval = NULL;

}

MyNums = new double[Kolvo];

int i;

// Очистим список значений

ListVal-> Clear ();

/* Сгенерируем нужное количество случайных значений и

заполним ими список */

for (i = 0; i < Kolvo; i++)

{

// Если выставлена радиокнопка rb2040 то используем генератор

// GenRand1a, иначе GenRand1b

MyNums[i] = (rb2040-> Checked)? GenRand1a (): GenRand1b ();

ListVal-> AddItem (FloatToStrF (MyNums[i], ffFixed, 7, 4), NULL);

}

Interval = new int[Intervals];

// Инициализируем кол-во значений попавших в каждый интервал нулем

for (i = 0; i < Intervals; i++)

{

Interval[i] = 0;

}

// Ширина интервала

Delta = ((rb2040-> Checked)? 20. 0: 30. 0) / Intervals;

// Выведем на форму

txtDelta-> Text = FloatToStrF (Delta, ffFixed, 7, 5);

int j;

// Минимальное генерируемое значение, левая граница

double Lev = (rb2040-> Checked)? 20. 0: 15. 0;

// Для всех сгенерированных чисел

for (i = 0; i < Kolvo; i++)

{

/* Левая граница — исключительный случай — обработаем отдельно,

т. к. ((больше) & & (меньше или равно)) крайняя левая граница

не прорабатывается в написанном ниже цикле */

if (MyNums[i] == Lev)

Interval[0]++;

// Проверяем число на принадлежность интервалам

for (j = 0; j < Intervals; j++)

{

// Если число попало в текущий интервал

if ((MyNums[i] > Delta * j + Lev) & &

(MyNums[i] <= Delta * (j + 1) + Lev))

{

// Увеличим счетчик

Interval[j]++;

}

}

}

ПоказатьСвернуть
Заполнить форму текущей работой