Файл: Построение логической схемы модели.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 10.11.2023

Просмотров: 18

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

ВАРИАНТ 3

Построение логической схемы модели


Логическая схема модели представлена на рисунке 1.

После генерации заявок в источнике И (блок 1) осуществляется распределение потока заданий с вероятностями 40%, 30%, 30% между накопителями Н1 (блок 2), Н2 (блок 3), Н3 (блок 4). В условии задачи емкость накопителя не ограничена, поэтому отказов в системе нет. После ожидания в накопителях Н1, Н2, Н3, задания поступают на обслуживание в каналы К1 (блок 5), К2 (блок 6), К3 (блок 7). Задание, закончившее обработку на первом канале не является решенным, поэтому поступает на ожидание последней обработки в накопители Н2 (блок 3), Н3 (блок 4) с вероятностным распределением 30% и 70% соответственно. Для того чтобы определить загруженность (или простои) каналов К1, К2 и К3, можно проанализировать статистические данные, касающиеся очереди перед соответствующими каналами. После обработки в каналах К2 и К3, задание поступает на удаление (блок 8 и блок 9) и покидает систему.



Рисунок 1- Логическая схема


Получение математических соотношений


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

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


Проверка достоверности модели системы



На данном подэтапе достоверность модели системы проверяется по следующим показателям:

а) возможности решения поставленной задачи:

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

б) точности отражения замысла в логической схеме:

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

в) полноте логической схемы модели:

Проверить наличие всех выше описанных переменных, параметров, зависимостей, последовательности действий;

г) правильности используемых математических соотношений:

Выбор инструментальных средств моделирования


В нашем случае для проведения моделирования системы массового обслуживания с непрерывным временем обработки параметров при наличии случайных факторов необходимо использовать ЭВМ с применением языка имитационного моделирования GPSS, т.к. в настоящее время самым доступным средством моделирования систем является ЭВМ, а применение простого и доступного языка имитационного моделирования GPSS (http://www.gpss.ru) позволяет получить информацию о функции состояний zi(t) системы, анализируя непрерывные процессы функционирования системы только в «особые» дискретные моменты времени при смене состояний системы благодаря моделирующему алгоритму, реализованному по «принципу особых состояний» (принцип z). Кроме того, высокий уровень проблемной ориентации языка GPSS значительно упростит программирование, специально предусмотренные в нем возможности сбора, обработки и вывода результатов моделирования позволят быстро и подробно проанализировать возможные исходы имитационного эксперимента с моделью.

Составление плана выполнения работ по программированию



Выбранный язык имитационного моделирования GPSS имеет три версии: MICRO-GPSS Version 88-01-01, GPSS/PC Version 2, GPSS World Students Version 4.3.5. Micro-GPSS имеет DOS-интерфейс, который чувствителен к стилю написания программы (количеству пробелов между операндами, длине меток и имен и др.), не содержит текстового редактора. GPSS/PC лишен указанных недостатков, однако интерпретатор GPSS World Students имеет ряд преимуществ перед ним, например наличие интерфейса Windows, пошагового отладчика, возможность сбора и сохранения в файлах различной статистической информации, визуальный ввод команд. Поэтому для разработки модели был выбран именно интерпретатор GPSS World Students.



Для моделирования достаточно использовать ЭВМ типа IBM/PC, применение специализированных устройств не требуется. В программное обеспечение ЭВМ, на которой проводится моделирование, должны входить операционная система Windows (версия 9Х и выше) и интерпретатор GPSS. Затраты оперативной и внешней памяти незначительны, и необходимости в их расчете при современном уровне техники нет. Затраты времени на программирование и отладку программы на ЭВМ зависят только от уровня знаний языка и имеющихся навыков, которые были получены мною на лабораторных работах.

Спецификация и построение схемы программы



к программе на языке имитационного моделирования GPSS согласно спецификации программы предъявляются традиционные требования: структурированность, читабельность, корректность, эффективность и работоспособность.

Спецификация постановки задачи данного курсового проекта – определить максимальную длину очередей перед каждой ЭВМ (NО1, NО2, NО3) и коэффициенты загрузки каждой из ЭВМ (ZЭ1, ZЭ2, ZЭ3). В качестве исходных данных задаются интервал времени (интенсивность) поступления заданий в вычислительную систему, состоящую их трех ЭВМ (tпр  tпр), интервал времени обработки заданий на каждой из ЭВМ (tЭ1, tЭ2, tЭ3), а также процент распределения заданий на одну из трех ЭВМ (РЭ1, РЭ2, РЭ3), процент распределения заданий на последний этап обработки на вторую и третью ЭВМ (РР2, РР3).

Спецификация ограничений на параметры исследуемой системы следующая: исходные данные должны быть положительными числами, кроме того, процент распределения заданий на одну из трех ЭВМ (РЭ1, РЭ2, РЭ3) и процент распределения заданий на последний этап обработки на вторую и третью ЭВМ (РР2, РР3), каждый по отдельности в сумме должен составлять 100%.

Схема программы зависит от выбранного языка моделирования.

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


Оценка затрат машинного времени проводится по нескольким критериям эффективности программы: затраты памяти ЭВМ, затраты вычислений (идентичны времени вычислений при последовательной обработке), время вычислений («время ответа»). Форма представления входных и выходных данных определяется интерпретатором языка GPSS и изменить ее по усмотрению пользователя невозможно.



рисунок 2-Схема программы

Проведение программирования модели





Метки

Текст программы

Комментарии




Simulate

Начало программирования




Generate 3,1,,200

Генерация входных заданий




Transfer .400, Met4, Met1

40% заданий направляется на метку 1, а 60% - на метку 4

Met1

Queue EVMQ1

Сбор статистических данных о входе задания в очередь EVMQ1 к прибору EVM1




Seize EVM1

Занятие прибора EVM1




Depart EVMQ1

Сбор статистических данных о выходе задания из очереди EVMQ1 к прибору EVM1




Advance 7,4

Обработка заявки в приборе EVM1




Release EVM1

Освобождение прибора EVM1




Transfer .300, Met3, Met2

30% заданий, обработанных на приборе EVM1 направляется на метку 2, а 70% - на метку 3

Met4

Transfer .500, Met3, Met2

из 60% заданий - 30% заданий направляется на обработку к метке 2 и 30% к метке 3

Met2

Queue EVMQ2

Сбор статистических данных о входе задания в очередь EVMQ2 к прибору EVM2




Seize EVM2

Занятие прибора EVM2




Depart EVMQ2

Сбор статистических данных о выходе задания из очереди EVMQ2 к прибору EVM2




Advance 3,1

Обработка заявки в приборе EVM2




Release EVM2

Освобождение прибора EVM2




Terminate 1

Уничтожение одного задания

Met3

Queue EVMQ3

Сбор статистических данных о входе задания в очередь EVMQ3 к прибору EVM3




Seize EVM3

Занятие прибора EVM3




Depart EVMQ3

Сбор статистических данных о выходе задания из очереди EVMQ2 к прибору EVM3




Advance 5,2

Обработка заявки в приборе EVM3




Release EVM3

Освобождение прибора EVM3




Terminate 1

Уничтожение одного задания




Start 200







End

Конец моделирования



На данном подэтапе последняя проверка машинной реализации модели проводится следующим образом:

а) обратным переводом программы в исходную схему, что в очередной раз подтверждает правильность пути исследования для моделирования;

б) проверкой отдельных частей программы при решении различных тестовых задач;

в) объединением всех частей программы и проверкой ее в целом на контрольном примере моделирования варианта системы.

На этом подэтапе необходимо также проверить затраты машинного времени на моделирование.


#include

#include

#include

#include

#include

using namespace std;

class task {

public:

    int t_prih, // Время прихода задания

        t_obr;  // Время на обработку задания

    task(int x, int y) {

        t_prih = x;

        t_obr = y;

    }

    task() {

        t_prih = 0;

        t_obr = 0;

    }

};

class computer {

public:

    int work;   // Сюда будет записываться количество тактов до выполнения задания

    computer() {

        work = 0;

    }

}; 

#define N int(1000)     // Количество задач

#define iter int(100)   // Количество итераций

 

int t_wait = 0;             // Время ожидания

int t_idle0 = 0;            // Время простоя 1 машины

int t_idle1 = 0;            // Время простоя 2 машины

int tick = 0;               // Такты

int n = 0;                  // Номер текущей задачи

int queue = 0;              // Счетчик очереди

int TotalCompleted = 0;     // Выполненные задания

task tasks[N];              // Создание N заданий

task tempTasks[N];          // Очередь заданий

computer PC[2];             // Класс компьютера 

void setPCFromTask() {      // Задаем машину для выполнения задачи

    if (PC[1].work == 0 && PC[0].work != 0) {       // Если второй свободен И первый занят, то исполняет второй

        PC[1].work = tempTasks[queue].t_obr;        // Передаем время обработки в переменную второй машины

        tempTasks[queue] = task(0, 0);              // Сбрасываем задание из очереди

        queue--;                                    // Уменьшаем счетчик очереди

    }

    if (PC[0].work == 0) {                          // Если 1 машина свободна - назначаем ей задание, дальше аналогично

        PC[0].work = tempTasks[queue].t_obr;

        tempTasks[queue] = task(0, 0);

        queue--;

    }

    queue++;                                        // Увеличиваем очередь, если все машины заняты

}

void UpdateCounter() {                  // Обработка счетчиков

    if (PC[1].work != 0 && PC[0].work != 0 && queue != 0) t_wait += queue;  // Если обе машины заняты, и очередь не пуста - такт записывается в ожидание

    if (PC[0].work == 0) t_idle0++;     // Если 1 машина не работает - такт записывается в простой первой машины

    if (PC[1].work == 0) t_idle1++;     // Если 2 машина не работает - такт записывается в простой второй машины

    if (PC[0].work != 0) PC[0].work--;  // Если 1 машина работала - вычитаем один такт из времени обработки задания

    if (PC[1].work != 0) PC[1].work--;  // Если 2 машина работала - вычитаем один такт из времени обработки задания

}

int main() {

    setlocale(LC_ALL, "Russian");   // Русский язык в консоли

    float total_P_idle0 = 0;            // Простой первой машины

    float total_P_idle1 = 0;            // Простой второй машины

    float total_av_wait = 0;            // Время среднего ожидания

    for (int i = 0; i < iter; i++) {

        srand(i);   // Генерируем случайное число от итерации

                    //Sleep(1000);

        tasks[0] = task(1 + rand() % 15, 1 + rand() % 19);  // Генерирация первой задачи

        for (int j = 1; j < N; j++) {                       // И остальных задач

            tasks[j] = task(tasks[j - 1].t_prih + (1 + rand() % 15), 1 + rand() % 19);

        }

        t_wait = 0;

        t_idle0 = 0;

        t_idle1 = 0;

        tick = 1;

        n = 0;

        while (1) {

            if (n == N && queue == 0 && PC[0].work == 0 && PC[1].work == 0) {

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

                // очереди нет, и машины не заняты

                // то выходим из цикла

                break;

            }

            UpdateCounter();  //Обновляем счетчики

            if (tick == tasks[n].t_prih) {      // Если нынешний такт равен времени прихода текущей задачи,

                tempTasks[queue] = tasks[n];    // то добавляем ее в очередь,

                n++;                        // увеличиваем номер задачи

                setPCFromTask();            // назначаем машину на обработку

            }

            else {      // В противном случае смотрим, если очередь больше 0

                        // и хотя бы один компьютер свободен, назначаем задание

                if (queue != 0 && (PC[0].work == 0 || PC[1].work == 0)) {

                    queue--;

                    setPCFromTask();

                }

            }

            tick++;     // Прибавляем такт

        }

        float av_wait = ((float)t_wait / N);                    // Среднее время ожидания задания

        float P_idle0 = ((float)t_idle0 / (tick - 1)) * 100;    // Вероятность простоя 1 машины

        float P_idle1 = ((float)t_idle1 / (tick - 1)) * 100;    // Вероятность простоя 2 машины

        total_av_wait += av_wait;                               // Добавляем среднее время ожидания задания за итерацию в общее

        total_P_idle0 += P_idle0;                               // Добавляем среднее время простоя 1 машины за итерацию в общее

        total_P_idle1 += P_idle1;                               // Добавляем среднее время простоя 2 машины за итерацию в общее

        TotalCompleted += N;                                    // Добавляем кол-во выполненных заданий за итерацию в общее

        cout << "Текущий процесс занял " << tick << " квантов работы" << "\n";

        cout << "Выполнилось " << N << " задач" << "\n";

        cout << "Среднее время ожидания задачи = " << av_wait << "\n";

        cout << "Вероятность простоя 1 ПК = " << P_idle0 << "\n";

        cout << "Вероятность простоя 2 ПК = " << P_idle1 << "\n\n";

    }

    total_av_wait /= iter;      // Считаем среднее время ожидания заданий

    total_P_idle0 /= iter;      // Средний простой первой машины

    total_P_idle1 /= iter;      // Средний простой второй машины

    TotalCompleted /= iter;     // Среднее количество выполненных заданий

    cout << "————————————————————————————————————————————————" << "\n\n";

    cout << "В среднем выполнялось " << TotalCompleted << " задач в " << iter << " итерациях" << "\n";

    cout << "Среднее время ожидания задачи = " << total_av_wait << "\n";

    cout << "Вероятность простоя 1 ПК = " << total_P_idle0 << "\n";

    cout << "Вероятность простоя 2 ПК = " << total_P_idle1 << "\n" << endl;

    system("pause");

}