При имитационном моделировании с использованием специальных инструментальных средств, например, GPSS World, в общем случае решаются две задачи. Назовем их прямой и обратной.
Прямая задача заключается в нахождении оценки математического ожидания какого-либо показателя моделируемой системы при заданном времени ее функционирования.
Обратная задача состоит в определении оценки математического ожидания времени функционирования системы, за которое какой-либо её показатель достигает заданного значения.
Решение этих задач, особенно обратной задачи, имеет свои особенности. Рассмотрим эти особенности далее на примерах. Начнём построение GPSS-моделей с прямой задачи.
Сервер обрабатывает запросы, поступающие с автоматизированных рабочих мест (АРМ) с интервалами, распределенными по показательному закону со средним значением T1 = 2 мин. Сервер имеет входной буфер ёмкостью 5 запросов.
Вычислительная сложность запросов подчинена нормальному закону с математическим ожиданием $$S1=6\cdot 10^7$$ оп и среднеквадратическим отклонением $$S2=2\cdot 10^5$$ оп. Производительность сервера $$Q=6\cdot 10^5$$ оп/с. В случае полной занятости входного буфера поступающий запрос теряется.
Построить имитационную модель обработки запросов сервером для определения оценки математического ожидания количества запросов (дальше - количества запросов), обработанных сервером за время функционирования T = 1 час, и оценки математического ожидания вероятности обработки запросов (дальше - вероятности обработки запросов).
Сервер представляет собой однофазную систему массового обслуживания разомкнутого типа с ожиданием и с отказами.
В модели для имитации источника запросов следует использовать блок GENERATE, для имитации сервера как одноканального устройства - блоки SEIZE и RELEASE, для имитации буфера - QUEUE и DEPART, обработки запросов - ADVANCE.
В модели должны быть следующие элементы:
Серверу дадим имя Server. Для вывода из модели транзактов, имитирующих обработанные и потерянные запросы, используем блоки TERMINATE с метками ObrZap и PotZap соответственно. Для счета количества всех запросов используем метку KolZap.
Выберем масштаб: 1 единице масштабного времени соответствует 1 с. Так как среднее значение интервалов поступления запросов ,$$T1=2$$ мин. то теперь это будет 120 ед. мод. времени.
Рассчитаем количество прогонов, которые нужно выполнить в каждом наблюдении, т. е. проведем так называемое тактическое планирование эксперимента. Пусть результаты моделирования (вероятность обработки запросов) нужно получить с доверительной вероятностью $$\alpha =0,95$$ и точностью $$\varepsilon =0,01$$ Расчет проведем для худшего случая, т. е. при вероятности $$p =0,5$$, так как до эксперимента $$p$$ неизвестно:
$$N=t^2_\alpha \cdot \frac{p\cdot (1-p)}{\varepsilon ^2}=1,96^2\cdot \frac{0,5\cdot (1-0,5)}{0,01^2}=3,8416\cdot \frac{0,25}{0,0001}=9604$$Построим блок-диаграмму модели для решения прямой задачи, т. е. сегмент имитации поступления и обработки запросов и сегмент задания времени моделирования и расчета результатов моделирования (Рис. 1.1).
Блок-диаграмма представляет собой набор стандартных блоков. Она строится так. Из множества блоков выбирают нужные, и далее выстраивают их в диаграмму для того, чтобы в процессе функционирования модели они как бы взаимодействовали друг с другом. Диаграмма сопровождается необходимыми комментариями. Использование блоков при построении моделей зависит от логических схем работы реальных систем, моделируемых на ЭВМ.
Теперь приступим к написанию программы модели.
(рис 1.1) Блок-диаграмма модели
Для задания исходных данных используем переменные пользователя. Они задаются с помощью команды EQU. Переменным пользователя даны такие же имена, как и в постановке задачи, но добавлен знак подчеркивания. Например, T1_, S1_ и т. д. Время моделирования зададим переменной пользователя VrMod.
Арифметическая переменная для расчета времени обработки VrObr запроса на сервере:
VrObr VARIABLE (Normal(2,(S1_#Koef),(S2_#Koef))))/Q_
Переменная пользователя Koef введена для удобства изменения (пропорционального изменения) характеристик нормального закона распределения, которому подчиняется вычислительная сложность запросов. Особенно целесообразно использование этой переменной при проведении экспериментов.
Вероятность обработки VerObr запросов на сервере будем определять как отношение количества обработанных N$ObrZap запросов к количеству всего поступивших N$KolZap запросов:
VerObr VARIABLE N$ObrZap/N$KolZap
В арифметическом выражении VerObr, например, N$ObrZap - системный числовой атрибут - количество транзактов, вошедших в блок с меткой ObrZap, а N$KolZap - количество транзактов, вошедших в блок с меткой KolZap.
Количество обработанных запросов определяется арифметическим выражением:
Res VARIABLE INT(N$ObrZap/X$Prog)
Все необходимое для написания программы модели имеется. Напишем программу модели для решения прямой задачи.
; Обработка запросов сервером. Прямая задача ; Задание исходных данных T1_ EQU 120 ; Средний интервал поступления запросов, с S1_ EQU 60000000 ; Среднее значение вычислительной сложности запросов, оп S2_ EQU 200000 ; Стандартное отклонение вычислительной сложности запросов, оп Q_ EQU 600000 ; Средняя производительность сервера, оп/с Emk EQU 5 ; Ёмкость входного буфера Koef EQU 1 ; Коэффициент изменения характеристик нормального распределения VrObr VARIABLE (Normal(9,(S1_#Koef),(S2_#Koef)))/Q_ VerObr VARIABLE N$ObrZap/N$KolZap Res VARIABLE INT(N$ObrZap/X$Prog) VrMod EQU 3600 ; Время моделирования, 1 ед. мод. времени = 1 с. ; Сегмент имитации обработки запросов GENERATE (Exponential(2,0,T1_)) ; Источник запросов KolZap TEST L Q$Server,Emk,PotZap ; Занят ли буфер? QUEUE Server ; Встать в очередь к серверу SEIZE Server ; Занять сервер DEPART Server ; Покинуть очередь к серверу ADVANCE V$VrObr ; Имитация обработки запроса SAVEVALUE SumTime+,M1; Время обработки всех запросов RELEASE Server ; Освободить сервер ObrZap TERMINATE ; Обработанные запросы PotZap TERMINATE ; Потерянные запросы ; Сегмент задания времени моделирования и расчета результатов GENERATE VrMod TEST L X$Prog,TG1,Met1 ; Если X$Prog < TG1, SAVEVALUE Prog,TG1 ; то X$Prog = TG1 Met1 TEST E TG1,1,Met2 ; Если TG1 = 1, то SAVEVALUE VerObr,V$VerObr ; расчет и сохранение в ячейке VerObr вероятности обработки запросов SAVEVALUE Res,V$Res ; числа обработанных запросов SAVEVALUE TimeMean,(X$SumTime/N$ObrZap) Met2 TERMINATE 1 START 9604 ; Количество прогонов модели
При расчете количества обработанных запросов Res в арифметическом выражении N$ObrZap/X$Prog используется число прогонов. В арифметическом выражении указано не явное число прогонов, а в виде содержимого ячейки X$Prog. Число прогонов заносится предварительно в эту ячейку по завершении первого прогона модели, но до того момента, когда из счетчика завершений TG1 будет вычтена первая единица. В этом случае арифметическое выражение не зависит от числа прогонов, которое может меняться на различных этапах создания и эксплуатации модели, в том числе и в зависимости от исходных данных, а также от точности и достоверности результатов моделирования. Поскольку количество обработанных запросов не может быть дробным числом, то для получения целого числа, записываемого в ячейку Res, используется процедура INT из встроенной библиотеки.
Среднее время X$TimeMean обработки одного запроса определяется как отношение суммарного времени X$SumTime к количеству обработанных запросов N$ObrZap. В данной модели можно определять X$TimeMean как сумму средних времен обработки одного транзакта на сервере и среднего времени задержки в очереди.
Для уменьшения машинного времени расчет искомых показателей производится не после каждого прогона, а после завершения последнего прогона, т. е. когда содержимое счетчика завершений будет равно единице (TG1 = 1).
File / New и в появившемся меню выберите Model. Нажмите Ok.
[Tab]. Например, после набора Т1_ нужно нажать клавишу [Tab]. Интервалы табуляции установлены по умолчанию.
Command / Create Simulation. По этой команде транслятор GPSS проверяет программу модели на наличие синтаксических ошибок.
JOURNAL выдаст список сообщений об ошибках трансляции. Перейдите к п. 7. При отсутствии ошибок в окне JOURNAL появится сообщение Model Translation Begun. Ready. Перейдите к п. 9.
Search / Next Error, предварительно перейдя из окна JOURNAL в текст программы модели. При первом выполнении этой команды курсор мыши помещается в строке текста модели с ошибкой. После исправления первой ошибки вновь используйте команду Search / Next Error и т.д. столько раз, сколько ошибок в тексте программы.
File / Save As. Дайте модели имя Модель процессов изготовления изделий и нажмите Ok.
Command / Start и в диалоговом окне вместо 1 наберите 9604. Нажмите Ok.
Search / Goto Line столько раз, сколько ошибок указано в окне JOURNAL. Там же (в окне JOURNAL) указаны номера строк с ошибками.
Report. В окне будут содержаться следующие данные:В результате решения прямой задачи получим, что за один час сервером будет обработано N=29 запросов, а вероятность обработки составит VerObr=0,97. Если не использовать процедуру INT - выделения целого числа с отбрасыванием дробной части, будет обработано 29,161 запроса. Среднее время обработки одного запроса составит TimeMean=255,262
Сущность этого эксперимента состоит в проведении многофакторного дисперсионного анализа с целью выявления степени влияния различных факторов и их комбинаций (взаимодействий) на значение целевой функции (функции отклика, представленной в виде уравнения регрессии).
Для каждого фактора необходимо выбрать два уровня - нижний и верхний. Рекомендуется выбирать уровни, значительно отстоящие друг от друга. Это необходимо для получения также значительно отличающихся откликов.
В условиях прямой задачи требуется исследовать зависимость вероятности обработки запросов от трех факторов, например, при следующих их минимальных и максимальных значениях (Табл. 1.1):
| Уровни факторов | Факторы | ||
|---|---|---|---|
| T1_, с | Koef | Q_, оп/c | |
| Нижний | 60 | 0,5 | 300000 |
| Верхний | 180 | 1,5 | 700000 |
Для проведения дисперсионного анализа нужно воспользоваться созданным в п. 1.1.1.4 объектом "Модель". В программе модели удалите последнюю строку.
Откройте модель Прямая задача. Выберите Edit / Insert Experiment / Screening … (Правка / Вставить эксперимент / Отсеивающий …).
Откроется диалоговое окно Screening Experiment Generator (Генератор отсеивающего эксперимента) (Рис. 1.2).
Приступите к заполнению полей диалогового окна.
В поля Experiment Name (Имя эксперимента) и Run Procedure Name (Имя процедуры запуска) введите, например, Dis_Server и Dis_Server_Run соответственно (Рис. 1.3).
Имена эксперименту и процедуре запуска эксперимента даёт пользователь.
Дальше расположена группа полей Factors (Факторы). В рассматриваемом примере определяется вероятность обработки запросов, поступающих на сервер. Факторы, влияние которых необходимо исследовать, были определены нами ранее (см. Табл. 1.1).
(рис 1.2) Диалоговое окно (незаполненное) Screening Experiment Generator (Генератор отсеивающего эксперимента)
(рис 1.3) Диалоговое окно (заполненное) Screening Experiment Generator (Генератор отсеивающего эксперимента)
В GPSS World максимальное количество факторов, влияние которых на функцию отклика можно исследовать посредством дисперсионного анализа, равно шести.
Введите ранее выбранные факторы, начиная с фактора А. В поле Name (User Variable) (Имя (Переменная пользователя)) введите имя фактора, в поля Value1 и Value2 - его нижний и верхний уровни соответственно. После ввода всех факторов для дальнейшей работы будем иметь факторы А, В и С.
Ниже идет группа Fraction (Часть полного эксперимента). Эксперимент, проводимый в GPSS World, может быть полным факторным экспериментом (ПФЭ) или дробным факторным экспериментом (ДФЭ). Группа Fraction (Часть дробного эксперимента) позволяет это задавать, т. е. позволяет провести стратегическое планирование эксперимента, цель которого, как вам известно, является определение количества наблюдений и сочетаний уровней факторов в них для получения наиболее полной и достоверной информации о поведении системы.
Установке ПФЭ соответствует кнопка Full, для ДФЭ в 1/2 от ПФЭ - Half, в 1/4 - Quarter, в 1/8 - Eight, в 1/16 - Sixteen.
Установите пока Half (1/2). Справа под Run Count появится число 4, так как $$2^2=4$$. Это количество наблюдений, которое необходимо сделать. Количество прогонов в каждом наблюдении будет указано позже.
В поле Expression (Выражение) группы Result (Результат) введите выражение, по которому вычисляется вероятность обработки запросов: N$ObrZap/N$KolZap.
После группы Result (Результат) расположены два флажка, позволяющие выбирать опции.
При выборе опции Generate Run Procedure вместе с экспериментом создается стандартная процедура запуска, которую пользователь может корректировать согласно своим требованиям.
Выбор второй опции Load F11 with CONDUCT Command закрепляет команду CONDUCT за функциональной клавишей F11. Тогда после создания объекта "Процесс моделирования" для запуска эксперимента нужно только нажать функциональную клавишу F11. Выберите обе опции.
Перед созданием эксперимента необходимо изучить группы смешивания с целью осуществления стратегического планирования эксперимента. Для этого нужно нажать кнопку Alias Groups (Группы смешивания). Появится диалоговое окно Alias Groups (Группы смешивания) (Рис. 1.4).
При изучении групп смешивания необходимо вначале найти отсутствующие факторы, а затем факторы, которые неразличимы, так как находятся в одной группе смешивания. Например, взаимодействие факторов А и В - АВ.
(рис 1.4) Диалоговое окно Alias Groups (Группы смешивания)
Из Рис. 1.4 видно, что отсутствующих факторов нет. Факторы А, В и С находятся в различных группах смешивания по два фактора в каждом. Невозможно будет судить об эффектах, т. е. о влиянии на отклик взаимодействий двух факторов. В некоторых случаях этого будет достаточно.
Нажмите кнопку Cancel (Отмена).
В диалоговом окне Screening Experiment Generator (Генератор отсеивающего эксперимента) в группе Fraction (Часть дробного эксперимента) установите Full (ПФЭ). Под Run Count появится число 8.
Обратите внимание, что кнопка Alias Groups (Группы смешивания) при установке полного факторного эксперимента Full (ПФЭ) не будет активной.
Теперь необходимо создать Plus - операторы и вставить их в нижнюю часть модели Прямая задача. Для этого нажмите кнопку Insert Experiment (Вставить эксперимент), расположенную в левой нижней части диалогового окна Screening Experiment Generator (Генератор отсеивающего эксперимента).
Так как была выбрана опция Generate Run Procedure, то создана стандартная процедура запуска с именем Dis_Server_Run. Появится ее диалоговое окно, дающее возможность пользователю изменить процедуру запуска согласно своим требованиям (Рис. 1.5).
(рис 1.5) Диалоговое окно стандартной процедуры запуска
(рис 1.6) Условия стандартной процедуры запуска по умолчанию
Перейдите, пользуясь клавишами вверх-вниз, в конец процедуры запуска. Там в разделе Set up your own run conditions (Задайте свои условия наблюдения) имеются две команды START, между которыми находится команда RESET (Рис. 1.6).
Поясним назначение этих команд.
Первой командой START
DoCommand("START 100,NP"); /*Get past the Startup Period. */
определяется количество прогонов в неустоявшемся режиме.
Подразумевается, что если моделирование выполняется долго, то система приходит в стационарное состояние. Сколько времени следует вести моделирование, чтобы достичь стационарного состояния? Часто ответ на этот вопрос можно получить из опыта экспериментирования с моделью. Команда RESET служит для этого. Она сбрасывает в ноль накопленную на неустоявшемся режиме статистику без удаления транзактов из процесса моделирования.
Второй командой START
DoCommand("START 1000,NP"); /*Run the Simulation. */
определяется количество прогонов в наблюдении, т. е. количество прогонов, которое было определено ранее при тактическом планировании эксперимента: N = 9604. Измените 1000 на 9604 (Рис. 1.7).
Корректировка процедуры запуска возможна до и после того, как она будет добавлена к объекту "Модель".
(рис 1.7) Условия стандартной процедуры запуска после корректировки
После корректировки нажмите Ok.
Сгенерированный Plus - эксперимент представлен ниже. Изучите его. Это необходимо для создания собственных экспериментов, отличающихся от стандартных экспериментов GPSS World.
В начале автоматически сгенерированного эксперимента определяется и инициализируется в неопределенное состояние (UNSPECIFIED) матрица результатов. Далее имеются Plus - операторы, которые для каждого из наблюдений определяют сочетания уровней факторов. В рассматриваемом примере таких сочетаний восемь.
Plus - эксперимент содержит также вызов Plus - процедуры запуска. Процедура запуска осуществляет связь между генерируемым экспериментом и процессом моделирования. Она вызывается столько раз, сколько требуется сделать наблюдений. Так как процедура запуска вызывается Plus - экспериментом, ей разрешается вызывать библиотечную процедуру DoCommand и, следовательно, выполнять RMULT, CLEAR, RESET и многие другие команды GPSS. Поэтому все команды, необходимые для определения условий наблюдения, например, обнуление сохраняемых ячеек, следует помещать в процедуру запуска.
Для сохранения матрицы результатов при обнулении переменных перед очередным наблюдением используется команда CLEAR OFF. Для изменения начального числа генератора случайных чисел в каждом наблюдении процедуре передается номер запуска.
****************************************************
* Dis_Server *
* Факторный отсеивающий эксперимент *
****************************************************
Dis_Server_Results MATRIX ,2,2,2
INITIAL Dis_Server_Results,UNSPECIFIED
Dis_Server_NextRunNumber EQU 0
EXPERIMENT Dis_Server() BEGIN
/* Наблюдение 1 */
T1_ = 60;
Koef = 0.5;
Q_ = 300000;
IF (StringCompare(DataType(Dis_Server_Results[1,1,1]),
"UNSPECIFIED")'E'0)
THEN BEGIN
/* Установить начальное значение переменной количества наблюдений */
Dis_Server_NextRunNumber = 1;
/* Записать данные наблюдения и запустить процесс моделирования*/
Dis_Server_GetResult();
Dis_Server_Results[1,1,1] = N$ObrZap/N$KolZap;
END;
/* Наблюдение 2 */
T1_ = 60;
Koef = 0.5;
Q_ = 700000;
IF (StringCompare(DataType(Dis_Server_Results[1,1,2]),
"UNSPECIFIED")'E'0)
THEN BEGIN
/* Записать данные наблюдения и запустить процесс моделирования */
Dis_Server_GetResult();
Dis_Server_Results[1,1,2] = N$ObrZap/N$KolZap;
END;
/* Наблюдения 3 - 7 для краткости пропущены */
/* Наблюдение 8 */
T1_ = 180;
Koef = 1.5;
Q_ = 700000;
IF (StringCompare(DataType(Dis_Server_Results[2,2,2]),
"UNSPECIFIED")'E'0)
THEN BEGIN
/* Записать данные наблюдения и запустить процесс моделирования */
Dis_Server_GetResult();
Dis_Server_Results[2,2,2] = N$ObrZap/N$KolZap;
END;
/* Эффекты смешивания в дробном факторном эксперименте */
SE_Effects(Dis_Server_Results,"I");
END;
*******************************************************
* Процедура запуска наблюдения *
*******************************************************
PROCEDURE Dis_Server_GetResult() BEGIN
/* Выполнить указанное число прогонов и записать результаты. */
/* Факторы для этого наблюдения уже были определены. */
TEMPORARY CurrentYield,ShowString,CommandString;
/* Вызов процедуры запуска */
Dis_Server_Run(Dis_Server_NextRunNumber);
CurrentYield = N$ObrZap/N$KolZap;
ShowString = PolyCatenate("Run ",String(Dis_Server_NextRunNumber),". ", "" );
ShowString = PolyCatenate(ShowString," Yield=",String(CurrentYield),". ");
ShowString = PolyCatenate(ShowString," T1_=",String(T1_), ";" );
ShowString = PolyCatenate(ShowString," Koef=",String(Koef), ";" );
ShowString = PolyCatenate(ShowString," Q_=",String(Q_), ";" );
CommandString = PolyCatenate("SHOW """,ShowString,"""", "" );
DoCommand(CommandString);
Dis_Server_NextRunNumber = Dis_Server_NextRunNumber + 1;
RETURN CurrentYield;
END;
*******************************************************
* Процедура запуска *
*******************************************************
PROCEDURE Dis_Server_Run(Run_Number) BEGIN
DoCommand("CLEAR OFF"); /* Использовать OFF для сохранения результата. */
/* Увеличьте число команд RMULT, если у вас большее число ГСЧ. */
/* Задать новые случайные числа всем потокам случайных чисел. */
TEMPORARY CommandString;
/* Вычислить, прежде чем перейти к DoCommand. */
CommandString = Catenate("RMULT ",Run_Number#111);
/* DoCommand контролирует строку в глобальном контексте. */
DoCommand(CommandString);
/* Установить собственные условия наблюдения. */
DoCommand("START 100,NP"); /* Пройти неустоявшийся режим. */
DoCommand("RESET"); /* Начать период измерений. */
DoCommand("START 9604,NP"); /* Провести моделирование. */
END;
Проведем эксперимент. Для вызова эксперимента предназначена команда CONDUCT. Однако за функциональной клавишей [F11] была закреплена соответствующая команда CONDUCT (Edit / Settings / Function Keys (Правка / Настройки / Функциональные клавиши)).
Проведите трансляцию, т. е. создайте объект "Процесс моделирования", для чего нажмите [Ctrl]+[Alt]+[S] или выполните команду Command / Create Simulation (Команда / Создать процесс моделирования).
При отсутствии ошибок в сгенерированном эксперименте в окне Journal (Журнал) появится сообщение (Рис. 1.8), свидетельствующее об отсутствии ошибок. Нажмите функциональную клавишу [F11]. Эксперимент начинает работать.
HALT. Остальные команды неактивны, т. е. процесс моделирования можно только остановить и потом продолжить, но просмотреть его с использованием меню, вызываемого командой WINDOW / SIMULATION WINDOW и другими командами, нельзя.В ходе выполнения сгенерированного эксперимента автоматически создается отчет, который по готовности записывается в окно Journal (Журнал) объекта "Процесс моделирования". Фрагмент отчета для четырех наблюдений (Run1 … Run4) показан на Рис. 1.9. В отчете содержатся Yield - целевая функция и значения факторов, при которых получение значение целевой функции.
(рис 1.8) Окно Journal (Журнал) с сообщением об успешном создании объекта "Процесс моделирования"
(рис 1.9) Окно Journal (Журнал) с отчетами по каждому наблюдению
Так как эксперимент включает 8 наблюдений по 9604 прогонов в каждом из них, то будет выдано 8 отчетов (на Рис. 1.9 в целях сокращения показаны только первые четыре отчета). Окончательные результаты моделирования после статистической обработки будут выведены в виде таблицы Anova (Рис. 1.10).
В таблице каждый фактор и взаимодействие факторов представлены отдельной строкой. В каждой строке для всех эффектов указаны коэффициенты, с которыми они входят в целевую функцию (столбец Effect), а для главных эффектов (А, В, С) - суммы квадратов отклонений - столбец Sum of Squares.
В столбце Degrees of Freedom приведены степени свободы соответствующих измерений.
В столбце F-for Only Main Effects - вычисленные значения F-статистик для главных эффектов, а в столбце Critical Value of F (p=0,5) - соответствующие критические значения F - распределения для уровня значимости 50%.
В строке Error показаны остаточная составляющая дисперсии и соответствующая степень свободы.
В строке Total - общая сумма квадратов ошибок по всему эксперименту.
В строке Greand - среднее значение результата исследования (в примере - вероятности) по данным всего эксперимента.
(рис 1.10) Результаты дисперсионного анализа
Чем больше значение F-статистики (F-for Only Main Effects), тем сильнее эффект. Эффект, а, следовательно, и фактор, считается значимым, если превышает критическое значение (Critical Value of F(p=.05)).
В данном примере факторы А и В являются значимыми, так как их F-статистики больше критического значения, равного 7.71. Обратите внимание, что эффекты факторов А и В противоположны.
Таким образом, по результатам моделирования можно сделать вывод, что при данном потоке и характеристиках сервера вероятность обработки запросов в среднем составляет 0,731, т. е. вероятность потерь запросов составляет 0,269. Для уменьшения потерь запросов нужно продолжить исследование каждого значимого фактора А и В.
Для того чтобы определить среднее количество запросов, которые будут обработаны при таких же значениях факторов, проведите ёще один дисперсионный анализ.
Для этого удалите сгенерированный эксперимент из программы модели. Затем выберите Edit / Insert Experiment / Screening … (Правка / Вставить эксперимент / Отсеивающий …). Всё, что вы ранее вводили (см. Рис. 1.3), останется неизменным. Вам нужно будет только заменить в поле Expression (Выражение) группы Result (Результат) выражение, по которому вычисляется вероятность обработки запросов, выражением для расчёта количества обработанных запросов: N$ObrZap/X$Prog.
После замены вставьте эксперимент и выполните его. Вы получите, что среднее количество обработанных запросов составит 25,889, а все факторы будут несущественными.
Для решения обратной задачи возьмем количество запросов, ожидаемое время обработки которых нужно определить, N=29 - результат решения прямой задачи.
Программа модели приведена ниже.
; Обработка запросов сервером. Обратная задача ; Задание исходных данных T1_ EQU 120 ; Средний интервал поступления запросов, с S1_ EQU 60000000 ; Среднее значение вычислительной сложности запросов, оп S2_ EQU 200000 ; Стандартное отклонение вычислительной сложности запросов, оп Q_ EQU 600000 ; Средняя производительность сервера, оп/c Emk EQU 5 ; Ёмкость входного буфера Koef EQU 1 ; Коэффициент изменения характеристик нормального распределения Koef1 EQU 1 ; Коэффициент учета дробной части N_ EQU 29 ; Количество запросов ; Сегмент имитации обработки запросов GENERATE (Exponential(1,0,T1_)) ; Источник запросов KolZap TEST L Q$Server,Emk,PotZap ; Занят ли буфер? QUEUE Server ; Встать в очередь к серверу SEIZE Server ; Занять сервер DEPART Server ; Покинуть очередь к серверу ADVANCE ((Normal(2,(S1_#Koef),(S2_#Koef)))/Q_) ; Имитация обработки запроса RELEASE Server ; Освободить сервер TRANSFER ,ObrZap ; Запрос отправляется в сегмент завершения моделирования PotZap TERMINATE ; Потерянные запросы ; Сегмент организации завершения моделирования и расчета результатов ObrZap TEST L X$Prog,TG1,Met1 ; Если X$Prog < TG1, SAVEVALUE Prog,TG1 ; то X$Prog = TG1 SAVEVALUE NZap,0 ; Обнуление счетчика обработанных запросов Met1 SAVEVALUE NZap+,1 ; Счет количества обработанных запросов TEST E X$NZap,N_,Ter1 ; Если X$NZap = N_, то TEST E TG1,1,Met2 ; если TG1 = 1, то SAVEVALUE VerObr,(N$ObrZap/N$KolZap) ; расчет и сохранение в ячейке VerObr вероятности обработки запросов SAVEVALUE TimeNZap,((AC1-X$AC2)/(X$Prog#Koef1)) ;расчет и сохранение в ячейке TimeNZap времени обработки запросов SAVEVALUE AC2,AC1 ; Запомнить абсолютное модельное время в ячейке АС2 Met2 SAVEVALUE NZap,0 ; Обнуление счетчика обработанных запросов TERMINATE 1 Ter1 TERMINATE START 1000,NP ; Прогоны до установившегося режима RESET ; Сброс накопленной статистики START 9604 ; Количество прогонов модели
При решении обратной задачи один прогон определяется заданным количеством запросов N_, которые нужно обработать сервером, а не временем моделирования. Для этого организован счетчик обработанных запросов в виде сохраняемой ячейки X$NZap. Как только содержимое X$NZap = N_, из счетчика завершений вычитается единица. Таким образом, фиксируется один прогон модели. После этого ячейка X$NZap обнуляется и начинается очередной прогон.
Для расчета времени обработки заданного количества запросов используется арифметическое выражение (AC1-X$AC2)/X$Prog. В состав этого выражения входят абсолютное модельное время АС1 и опять количество прогонов. Запоминается количество прогонов также как и при решении прямой задачи.
Кроме этого, в арифметическом выражении есть сохраняемая ячейка X$AC2. Дело в том, что команда RESET не влияет на абсолютное модельное время АС1. Время же выполнения 1000 прогонов до установившегося режима не должно участвовать в расчёте. Поэтому оно запоминается, а затем вычитается из абсолютного модельного времени выполнения 1000 + 9604 = 10604 прогонов. Число прогонов до установившегося режима может быть и другим.
В результате моделирования получим среднее время обработки 29 запросов 3579,401 с.
Фрагмент из отчета моделирования приведен ниже:
SAVEVALUE RETRY VALUE PROG 0 9604.000 NZAP 0 0 VEROBR 0 0.971 TIMENZAP 0 3579.401
А почему не 3600 сек? Ведь это же время моделирования было задано при решении прямой задачи? Потому что мы отбросили дробную часть, т. е. взяли 29, а не 29,161. Как же поступить, чтобы учесть и отброшенную дробную часть? Ведь в счётчике фиксируются обработанные запросы только целыми числами, а не дробными?
Для учёта десятых долей дробной части зададим N_ = 291, т. е. увеличим в 10 раз. Это нужно учесть и в арифметическом выражении: ((AC1-X$AC2)/(X$Prog#Koef1)). Переменной пользователя Koef1 задается значение 10. По завершении моделирования получим 3594,826 с. Этот результат уже ближе к 3600.
Для учёта сотых долей дробной части установим N_ = 2916, а Koef1 = 100. Получим 3602,099.
Вероятность обработки запросов в обоих случаях практически одна и та же, т. е. 0,971. Однако время моделирования существенно возрастает: 2 с, 21 с и 3 мин 34 c соответственно, т. е. более чем в 10 и 100 раз.
В примере обратной задачи также показано, что арифметические выражения можно не описывать отдельно до блоковой части программы вместе с заданием исходных данных (как в программе модели прямой задачи), а сразу записывать в соответствующих блоках, заключив в скобки (скобки можно и не ставить, но лучше это делать).
Например (см. сегмент организации завершения моделирования и расчета результатов):
ADVANCE ((Normal(2,(S1_#Koef),(S2_#Koef)))/Q_) ; Розыгрыш времени обработки запроса SAVEVALUE VerObr,(N$ObrZap/N$KolZap)) ; Расчет вероятности обработки запросов SAVEVALUE TimeNZap,((AC1-X$AC2)/(X$Prog#Koef1)) ; Расчет среднего времени обработки запросов
Сервер обрабатывает запросы, поступающие с автоматизированных рабочих мест с интервалами, распределенными по показательному закону со средним значением 2 мин. Время обработки сервером одного запроса распределено по экспоненциальному закону со средним значением 3 мин. Сервер имеет входной буфер ёмкостью 5 запросов.
Построить имитационную модель для определения математического ожидания времени и вероятности обработки запросов.
Сервер представляет собой однофазную систему массового обслуживания разомкнутого типа с ограниченной входной емкостью, то есть с отказами, и абсолютной надёжностью (Рис. 1.11).
На Рис. 1.11 приведены также объекты AnyLogic, которые будут использованы для создания диаграммы процесса. На них мы остановимся позже. Приступим к созданию диаграммы процесса.
(рис 1.11) Сервер как система массового обслуживания
Имя модели введите Server.
Местоположение или выбрать этот каталог с помощью диалога навигации по файловой системе, открывающегося нажатием кнопки Выбрать.
(рис 1.12) Диалоговое окно Новая модель
Готово. Откроется пользовательский интерфейс (Рис. 1.13). Остановимся на нём.
Проекты и панель Палитра. Панель Проект обеспечивает навигацию по элементам моделей, открытых в текущий момент времени. Модель организована иерархически. Она отображается в виде дерева. Сама модель образует верхний уровень дерева. Эксперименты, классы активных объектов и Java классы образуют следующий уровень. Элементы, входящие в состав активных объектов, вложены в соответствующую подветвь дерева класса активного объекта и т. д.
Палитра (левый вертикальный столбец) содержит разделённые по категориям элементы, которые могут быть добавлены на графическую диаграмму типа агентов или эксперимента. На Рис. 1.13 раскрыта палитра Презентация. Для того чтобы открыть нужную палитру, следует подвести курсор к иконке и щелкнуть мышью. Иконка становится светлой.
Свойства. Панель Свойства используется для просмотра и изменения свойств выбранного в данный момент элемента (или элементов) модели.
AnyLogic размещён графический редактор диаграммы агента Main.
(рис 1.13) Пользовательский интерфейс
.
Библиотеку моделирования процессов (Рис. 1.14). Из неё перетащите объекты на диаграмму и соедините, как показано на Рис. 1.15. Для добавления объекта на диаграмму, надо щёлкнуть его мыщью и, не отпуская её, перетащить в графический редактор.
(рис 1.14) Библиотека моделирования процессов
(рис 1.15) Диаграмма системы массового обслуживания
Дадим краткую характеристику объектов диаграммы.
Объект Source генерирует заявки определенного типа. Обычно он используется в качестве начальной точки диаграммы процесса, формализующей поток заявок. В нашем примере заявками будут запросы на обработку сервером, а объект Source будет моделировать их поступление.
Объект Queue моделирует очередь заявок, ожидающих приема объектами, следующими за данным в диаграмме процесса. В нашем случае он будет моделировать очередь запросов, ожидающих освобождения сервера.
Объект Delay задерживает заявки на заданный период времени. Он представляет в нашей модели сервер, обрабатывающий запросы.
Объект Sink уничтожает поступившие заявки. Обычно он используется в качестве конечной точки потока заявок (и диаграммы процесса соответственно).Помним, что мы хотим сначала создать простейшую модель, в которой будем рассматривать только обработку запросов сервером.
В основе каждой дискретно-событийной модели лежит диаграмма процесса - последовательность соединенных между собой объектов (Библиотеки моделирование процессов), задающих последовательность операций, которые будут производиться над проходящими по диаграмме процесса заявками.
Как вы уже знаете диаграмма процесса в AnyLogic создаётся путем добавления объектов библиотеки из палитры на диаграмму класса активного объекта, соединения их портов и изменения значений свойств блоков в соответствии с требованиями модели.
Всё, что нам нужно, чтобы сделать созданную диаграмму модели (см. Рис. 1.15) адекватной постановке задачи - это изменить некоторые свойства объектов.
Свойства объекта (как и любого другого элемента AnyLogic) можно изменить в панели Свойства.
Обратите внимание, что панель Свойства является контекстно-зависимой. Она отображает свойства выделенного в текущий момент элемента. Поэтому для изменения свойств элемента нужно будет предварительно щелчком мыши выделить его в графическом редакторе или в панели Проекты.
Чтобы всегда была уверенность в том, что в текущий момент в рабочем пространстве выбран именно нужный элемент, и именно его свойства вы редактируете в панели Свойства, обращайте внимание на первую строку, показываемую в панели Свойства - в ней отображается имя выбранного в текущий момент времени элемента и его тип.
Согласно принятым стандартам, объекты в диаграмме процесса обычно располагаются цепочкой слева направо, представляя собой последовательную очередность операций, которые будут производиться над заявкой.
Первым объектом в диаграмме процесса является объект класса Source. Объект source генерирует заявки определенного типа. Заявки представляют собой объекты, которые производятся, обрабатываются, обслуживаются, или еще каким-нибудь образом подвергаются действию моделируемого процесса: это могут быть клиенты в системе обслуживания, детали в модели производства, транспортные средства в модели перевозок, документы в модели документооборота, сообщения в моделях систем связи и т.д. В нашем примере заявками будут запросы на обработку данных, а объект source будет моделировать поступление запросов на сервер.
(рис 1.16) Свойства объекта source
В нашем случае объект создает заявки через временной интервал, распределенный по показательному (экспоненциальному) закону со средним значением 2 мин.
Установим среднее время поступления запросов и среднее время их обработки в секундах. Однако имеется воз-можность установить время в минутах, часах, днях, в чем вы убедитесь несколько позднее, когда будете устанавливать мо-дельное время.
Прибывают согласно: укажите, что запросы поступают согласно Времени между прибытиями: (Рис. 1.16).
Время между прибытиями появится запись exponential(1). Установите согласно постановке задачи среднее значение интервалов времени поступления запросов на сервер, изменив свойства объекта source. Для этого вместо характеристики распределения 1 введите 1/120.0.В языке программирования Java символ / означает целочисленное деление, т.е. если оба числа целые, то и результат будет целым. В нашем случае отношение 1/120 было бы равно нулю. Для получения вещественного результата, необходимо, чтобы хотя бы одно из чисел было вещественным (double). Поэтому в качестве характеристики экспоненциального распределения (интенсивности поступления запросов) необходимо указать 1/120.0 или 1.0/120.
Следующий объект - queue. Выделите его. Он моделирует очередь заявок, ожидающих приема объектами, следующими за данным объектом в диаграмме процесса. В нашем случае он будет, как уже отмечалось, моделировать очередь запросов, ждущих освобождения сервера.
Измените свойства объекта queue (Рис. 1.17).
Вместимость: 5. В очереди будут находиться не более 5 запросов.
Включить сбор статистики, чтобы включить сбор статистики для этого объекта. В этом случае по ходу моделирования будет собираться статистика по количеству запросов в очереди. Если же вы не установите этот флажок, то данная функциональность будет недоступна, поскольку по умолчанию она отключена для повышения скорости выполнения модели. Для вывода, например, средней длины очереди, нужно в модели предусмотреть Java код.
(рис 1.17) Свойства объекта queue
Следующим в нашей диаграмме процесса расположен объект delay. Он задерживает заявки на заданный период времени, представляя в нашей модели непосредственно сервер, на котором обрабатываются запросы.
Измените свойства объекта delay (Рис. 1.18).
Время задержки: exponential(1/180.0). Функция exponential() является стандартной функцией генератора случайных чисел AnyLogic. AnyLogic предос-тавляет функции и других случайных распределений, таких как нормальное, треугольное, и т. д.
(рис 1.18) Свойства объекта delay
Для вывода коэффициента использования объекта delay в модели также следует предусмотреть соответствующий Java код.
Последним в диаграмме нашей дискретно-событийной модели находится объект sink. Этот объект уничтожает поступившие заявки. Обычно он используется в качестве конечной точки потока заявок (и диаграммы процесса соответственно). В нашем случае он выводит из модели обработанные сервером запросы.
Вы можете сконфигурировать выполнение модели в соответствии с вашими требованиями. Модель выполняется в соответствии с набором установок, задаваемым специальным элементом модели - экспериментом. Вы можете создать несколько экспериментов с различными установками и, изменять конфигурацию модели, просто запуская тот или иной эксперимент модели.
В панели Проект эксперименты отображаются в нижней части дерева модели. Один эксперимент, названный Simulation, создается по умолчанию (см. справа). Это простой эксперимент, позволяющий запускать модель с заданными значениями параметров, поддерживающий режимы виртуального и реального времени, анимацию и отладку модели.
Если вы хотите наблюдать поведение модели в течение длительного периода (до того момента, пока вы сами не остановите выполнение модели), то по умолчанию времени остановки нет. Обработку запросов сервером мы планируем исследовать в течение одного часа, т.е. 3600 с.
Проект выделите эксперимент Simulation:Main.
Модельное время.
Виртуальное время (максимальная скорость) (Рис. 1.19).
Остановить: выберите из списка В заданное время.
Конечное время: установите 3600.
Случайность.
Фиксированное начальное число (воспроизводимые прогоны).
Начальное число: установите 9.
Проект, выделите Server (Рис. 1.20).
Единицы модельного времени: выберите секунды.Постройте вашу модель с помощью кнопки панели инструментов
(F7) Построить модель (при этом в рабочей области AnyLogic должен быть выбран какой-то элемент именно этой модели). Если в модели есть какие-нибудь ошибки, то построение не будет завершено, и в панель Ошибки будет выведена информация об ошибках, обнаруженных в модели. Двойным щелчком мыши по ошибке в этом списке вы можете перейти к предполагаемому месту ошибки, чтобы исправить её. При этом откроется соответствующее место ошибки.
(рис 1.19) Установка свойств эксперимента
(рис 1.20) Установка модельного времени
После исправления ошибок и построения модели, запустите её:
Запустить (или нажмите F5) и выберите из открывшегося списка эксперимент, который вы хотите запустить. Эксперимент этой модели будет называться Server/Simulation.
Запустить (или кнопки F5) будет запускаться тот эксперимент, который запускался вами в последний раз. Чтобы выбрать другой эксперимент, вам будет нужно щелкнуть мышью по стрелке, находящейся в правой части кнопки Запустить, и выбрать нужный вам эксперимент из открывшегося списка (или щелкнуть правой кнопкой мыши по этому эксперименту в панели Проект и выбрать Запустить из контекстного меню).
Main).
Библиотеке моделирования процессов, автоматически создается блок-схема с наглядной визуализацией процесса, с помощью которой вы можете изучать текущее состояние модели, например, длину очереди, количество обработанных запросов и так далее (Рис. 1.22).
(рис 1.21) Окно презентации модели
(рис 1.22) Модель остановилась с ошибкой
(рис 1.23) Сообщение о логической ошибке в модели
OK. Далее измените свойства объекта queue, т. е. увеличьте длину очереди (см. Рис. 1.17). Для этого введите в поле Вместимость 15. Можете убедиться, что при увеличении ёмкости в пределах 6 … 14 модель по-прежнему останавливается с этой же ошибкой. Момент появления ошибки зависит от длительности времени моделирования.
(рис 1.24) Окно инспекта
Можно было наблюдать, анализировать и интерпретировать работу запущенной модели с помощью визуализированной диаграммы процесса (см. Рис. 1.22, 1.24).
Однако удобнее в ряде случаев иметь более наглядную визуализацию с помощью анимации. В этой задаче мы хотим создать визуализированный процесс поступления запросов на сервер и обработки запросов сервером.
Так как в данном случае нас не интересует конкретное расположение объектов в пространстве, то мы можем просто добавить схематическую анимацию интересующих нас объектов - сервер и очередь запросов к нему.
Анимация модели рисуется в той же диаграмме (в графическом редакторе), в которой задается и диаграмма моделируемого процесса.
Нарисуйте прямоугольный узел, который будет обозначать на анимации сервер.
Разметка пространства (Рис. 1.25). Чтобы открыть какую-либо палитру, нужно щелкнуть по иконке этой палитры.
Разметка пространства (Рис. 1.25) содержит в качестве элементов различные примитивные фигуры, используемые для рисования презентаций моделей. Это путь, прямоугольный узел, многоугольный узел, точечный узел, аттрактор, стеллаж, масштаб.
(рис 1.25) Палитра Разметка пространства
Прямоугольный узел и перетащите его на диаграмму класса активного объекта. Поместите элемент Прямоугольный узел так, как показано на Рис. 1.26.
(рис 1.26) Элемент Прямоугольный узел на диаграмме
Внешний вид панели свойств (Рис. 1.27).
Если нужно, чтобы по ходу моделирования то или иное свойство фигуры меняло своё значение в зависимости от каких-то условий, то можете ввести в поле соответствующего динамического свойства выражение, которое будет постоянно вычисляться заново при выполнении модели.
Возвращаемый результат вычисления будет присваиваться текущему значению этого свойства. Мы хотим, чтобы во время моделирования менялся цвет нашей фигуры, поэтому щёлкните в поле Цвет заливки: по стрелке, выберите Динамическое значение и введите там следующую строку:
delay.size()>0?red:green
(рис 1.27) Установлено динамическое значение цвета заливки
Здесь delay - это имя нашего объекта delay. Функция size() возвращает число запросов, обслуживаемых в данный момент времени. Если сервер занят, то цвет кружка будет красным, в противном случае - зелёным.
Разметка пространства, чтобы перейти в режим рисования. Теперь вы можете рисовать путь точка за точкой, последовательно щелкая мышью в тех точках диаграммы, куда вы хотите поместить вершины пути. Чтобы завершить рисование, добавьте последнюю точку пути двойным щелчком мыши.
Очень важно, какую точку пути вы создаете первой. Заявки будут располагаться вдоль нарисованного вами пути в направлении от конечной точки к начальной точке. Поэтому обязательно начните рисование пути слева и поместите рядом с сервером конечную точку пути, которая будет соответствовать в этом случае началу очереди.
(рис 1.28) Путь на диаграмме процесса
Место заявок: выберите из выпадающего списка path (Рис. 1.29).
Место заявок: из выпадающего списка имя нашего прямоугольного узла: node (Рис. 1.30).
(рис 1.29) Задание пути в качестве фигуры анимации очереди
(рис 1.30) Задание прямоугольного узла в качестве фигуры анимации сервера
(рис 1.31) Анимация модели
AnyLogic предоставляет пользователю удобные средства для сбора статистики по работе блоков диаграммы процесса. Объекты Enterprise Library самостоятельно производят сбор основной статистики. Все, что вам нужно сделать - это включить сбор статистики для объекта.
Поскольку мы уже сделали это для объектов delay и queue, то теперь мы можем, например, просмотреть интересующую нас статистику (скажем, статистику занятости сервера и длины очереди) с помощью диаграмм.
Добавьте диаграмму для отображения среднего коэффициента использования сервера:
Статистика. Эта палитра содержит элементы сбора данных и статистики, а также диаграммы для визуализации данных и результатов моделирования.
Столбиковая диаграмма из палитры Статистика на диаграмму класса и измените ее размер, как показано на Рис. 1.32.
(рис 1.32) Элемент Столбиковая диаграмма на диаграмме класса
Свойства. Щёлкните кнопку Добавить элемент данных. После щелчка появится секция свойств того элемента данных (chart - Столбиковая диаграмма), который будет отображаться на этой диаграмме (Рис. 1.33).
(рис 1.33) Страница Свойства
Заголовок на SERVER utilization.
delay.statsUtilization.mean() в поле Значение. Здесь delay - это имя нашего объекта delay. У каждого объекта delay есть встроенный набор данных statsUtilization, занимающийся сбором статистики использования этого объекта. Функция mean() возвращает среднее из всех измеренных этим набором данных значений. Вы можете использовать и другие методы сбора статистики, такие, как min() или max(). Полный список методов можно найти на странице документации этого класса набора данных: StatisticsContinuous (на английском языке).
Внешний вид (Рис. 1.34). Установите свойства: направление столбцов, цвета фона, границ, меток, сетки, положение подписей у столбцов.
(рис 1.34) Вкладка Внешний вид
Местоположение и размер, Легенда, Область диаграммы (Рис. 1.35). Установите свойства, чтобы изменить расположение легенды относительно диаграммы (мы хотим, чтобы она отображалась внизу), размер диаграммы, высоту, ширину, координаты размещения на диаграмме, цвета текста, границы.
(рис 1.35) Вкладки Местоположение и размер, Легенда, Область диаграммы
Свойства щёлкните Добавить элемент данных. После щелчка появится страница Данные свойств элемента данных (chart1 - Столбиковая диаграмма), который также будет отображаться на этой диаграмме (Рис. 1.36).
Заголовок: и Значение: измените так, как показано на Рис. 1.36. В поле Заголовок: введите Queue lenqth, а в поле Значение: введите queue.statsSize.mean().
Внешний вид, Местоположение и размер, Легенда, Область диаграммы установите свойства самостоятельно. Столбцы диаграммы должны размещаться горизонтально.
(рис 1.36) Страницы Данные, Внешний вид панели Свойства
Значение: queue - это имя нашего объекта queue. У каждого объекта queue, как и объекта delay, также есть встроенный набор данных statsSize, занимающийся сбором статистики использования этого объекта. Функция mean() также возвращает среднее из всех измеренных этим набором данных значений.
(рис 1.37) Добавлены две столбиковые диаграммы
Внешний вид панели Свойства выберите в секции свойств Направление столбцов вторую опцию (Рис. 1.36), чтобы столбцы во второй столбиковой диаграмме, расположенной горизонтально, росли вправо (Рис. 1.37).
На Рис. 1.38 (снимок сделан по окончании времени моделирования) видно, что длина очереди равна 14 запросам при установленной максимальной длине 15. Но ведь в постановке задачи ёмкость буфера была определена в 5 запросов. Нам не удалось до этого построить модель с такой ёмкостью из-за ошибки (см. Рис. 1.32) - невозможности очередного запроса покинуть блок source, так как длина очереди уже была равна 5 запросам. Нам пришлось во избежание этой ошибки увеличить ёмкость буфера до 15 запросов.
А возможно ли выполнить данное условие постановки задачи средствами AnyLogic? Оказывается, что можно. Причем, различными способами. Уточним модель согласно постановке задачи одним из этих способов.
(рис 1.38) Наблюдение за моделью с двумя столбиковыми диаграммами
Объект queue моделирует очередь заявок, ожидающих приёма объектами, следующими за ним в потоковой диаграмме, или же моделирует хранилище заявок общего назначения. При необходимости вы можете задать максимальное время ожидания заявки в очереди. Вы также можете с помощью написанной вами программы извлекать заявки из любых позиций в очереди.
Заявка может покинуть объект queue различными способами:
out, когда объект, следующий в блок-схеме за этим объектом, готов принять заявку;
outTimeout, если заявка проведет в очереди заданное количество времени (если включен режим таймаута);
outPreempted, будучи вытесненной другой поступившей заявкой при заполненной очереди (если включен режим вытеснения);
remove() или removeFirst().В первом случае объект queue покидает заявка, находящаяся в самом начале очереди (в нулевой позиции). Если заявка направлена в порт outTimeout или outPreempted, то она должна покинуть объект мгновенно. Если включена опция вытеснения, то объект queue всегда готов принять новую заявку, в противном случае при заполненной очереди заявка принята не будет.
Поступающие заявки помещаются в очередь в определенном порядке: либо согласно правилу FIFO (в порядке поступления в очередь), либо согласно приоритетам заявок. Приоритет может быть либо явно храниться в заявке, либо вычисляться согласно свойствам заявки и каким-то внешним условиям. Очередь с приоритетами всегда примет новую входящую заявку, вычислит её приоритет, и поместит в очередь в позицию, соответствующую её приоритету. Если очередь будет заполнена, то приход новой заявки вынудит последнюю хранящуюся в очереди заявку покинуть объект через порт outPreempted. Но если приоритет новой заявки не будет превышать приоритет последней заявки, то тогда вместо неё будет вытеснена именно эта новая заявка.
Для выполнения условия постановки задачи воспользуемся последним способом вытеснения. Все запросы, вырабатываемые объектом source, имеют один и тот же приоритет. Поэтому при полном заполнении накопителя (5 запросов) теряться будет последний запрос. Уточните модель.
Свойства измените Вместимость с 15 на 5 запросов.
Разрешить вытеснение.
Палитре Библиотеку моделирования процессов и перетащите блок sink на диаграмму (Рис. 1.39). При перетаскивании объект пытается автоматически соединиться с входами имеющимися на диаграмме объектами. Но это может вас не устраивать.
outPreempted объекта queue с входным портом InPort блока sink1. Чтобы соединить порты, сделайте двойной щелчок мышью по одному порту, например, outPreempted, затем последовательно Щёлкните в тех местах диаграммы, где вы хотите поместить точки изгиба соединителя.
(рис 1.39) Уточненная модель
Однако согласно постановке задачи требуется определить математическое ожидание времени обработки одного запроса и математическое ожидание вероятности обработки запросов.
Entity (заявка) являются базовым классом для всех заявок, которые создаются и работают с ресурсами в процессе, описанном вами с помощью диаграммы из объектов Библиотеки моделирования процессов. Entity по существу является обычным Java классом с теми функциональными возможностями, которые необходимы и достаточны для обработки и отображения анимации заявки объектами Библиотеки моделирования процессов. Эти функциональные возможности можно расширить добавлением дополнительных полей и методов и работой с ними из объектов диаграммы, описывающей моделируемый процесс.
Согласно постановке задачи нужно определять математическое ожидание времени и вероятности обработки запросов сервером.
(рис 1.40) Работа модели согласно ёмкости входного буфера
Математическое ожидание или среднее время обработки одного запроса определяется как отношение суммарного времени обработки n запросов к их количеству, т. е. к n. Для определения суммарного времени нужно знать время обработки i-го запроса. Для этого введем дополнительные поля:
time_vxod - время входа запроса в буфер сервера,
time_vixod - время выхода запроса с сервера (входа в блок sink).Тогда
time_obrabotki=time_vixod-time_vxod
Вероятность обработки запросов сервером определяется как отношение количества обработанных запросов к количеству всех поступивших запросов. Значит, нужно вести счет запросов на выходе источника запросов и на выходе с сервера (входе в блок sink). Для этого также введем дополнительные поля:
col_vxod - количество поступивших всего запросов,
col_vixod - количество обработанных сервером запросов.Тогда
ver_obrabotki=col_vixod/col_vxod
Для включения в запросы дополнительных полей необходимо создать нестандартный тип заявки. Это возможно двумя способами. Создадим первым способом тип заявок Inquiry.
Проект щёлкните правой кнопкой мыши элемент модели верхнего уровня дерева и выберите из контекстного меню Создать/Java класс.
Новый Java класс (Рис. 1.41). В поле Имя: введите имя нового класса Inquiry.
Базовый класс: выберите из выпадающего списка Entity в качестве базового класса. Щёлкните кнопку Далее.
(рис 1.41) Диалоговое окно создания нового Java класса
Мастера создания Java класса. (Рис. 1.42).
(рис 1.42) Вторая страница Мастера создания Новый Java класс
time_vxod типа double, time_vixod типа double, col_vxod типа int, col_vixod типа int. Типы полей выбираются из выпадающего списка. Начальные значения всех параметров, поскольку не указаны, по умолчанию будут установлены равными нулю.
Создать конструктор и Создать метод toString (). Тогда у класса будут созданы сразу два конструктора: один, по умолчанию, без параметров, и второй, с параметрами, инициализирующими поля класса. Эти конструкторы используются объектами, создающими новые заявки, такие, как Source.
Готово. Вы увидите редактор кода, в котором будет показан автоматически созданный код вашего Java класса (Рис. 1.43). Закройте редактор, щелкнув крестик в закладке рядом с его названием.
Проект только что созданный Java класс и в контекстном меню выберите Преобразовать Java класс в тип агента.
Inquiry (см. Рис. 1.48).
(рис 1.43) Окно редактора кода созданного нестандартного класса
Создайте тип заявок Inquiry.
Библиотека моделирования процесов.
Тип заявки в графический редактор. Появится тип заявки Entity (Рис. 1.44).
Создание агента. Шаг 1. Анимация агента (Рис. 1.45).
В поле Имя нового агента: введите Inquiry.
Выберите анимацию агента: установите 2D и выберите из выпадающего списка, например, Сообщение.
Щёлкните Далее.
Создание агента. Шаг 2. Параметры агента (Рис. 1.46).
<добавить…>. В поле Параметр: введите time_vxod (Рис. 1.47).
Тип: выберите double.
<добавить…>. В поле Параметр: введите time_vixod.
Тип: выберите double.
<добавить…>. В поле Параметр: введите col_vxod.
Тип: оставьте int.
(рис 1.44) Появился тип заявки Entity
(рис 1.45) Диалоговое окно Создание агента. Шаг 1. Анимация агента
<добавить…>. В поле Параметр: введите col_vixod.
Тип: оставьте int.
(рис 1.46) Диалоговое окно Создание агента. Шаг 2. Параметры агента
(рис 1.47) Диалоговое окно Создание агента. Шаг 2. Параметры агента с установленными параметрами нестандартного типа заявок Inquiry
Значение по умолчанию мы не устанавливали никаких значений, то всем параметрам будет установлен 0.
(рис 1.48) Окно с параметрами нестандартного типа заявки Inquiry
Готово. Вы увидите окно, в котором будут показаны автоматически созданные параметры нестандартного типа заявок Inquiry (Рис. 1.48). Закройте оно, щелкнув крестик в закладке рядом с его названием.Для сбора статистических данных о времени обработки запросов сервером необходимо добавить элемент статистики. Этот элемент будет запоминать значения времен для каждого запроса. На основе этого он предоставит пользователю стандартную статистическую информацию (среднее, минимальное, максимальное из измеренных значений, среднеквадратичное отклонение и т.д.).
Данные гистограммы с палитры Статистика на диаграмму активного класса.
Имя: на time_obrabotki;
Кол-во интервалов: равным 50;
Нач. размер интервала: 0.01.
(рис 1.49) Элемент сбора статистики о времени обработки запросов
Добавьте еще элемент сбора статистики для определения вероятности обработки запросов.
Данные гистограммы с палитры Статистика на диаграмму активного класса.
Имя: на ver_obrabotki;
Кол-во интервалов: равным 50;
Нач. размер интервала: 0.01.Диаграмма после добавления элементов сбора статистики представлена на Рис. 1.51.
(рис 1.50) Элемент сбора статистики о вероятности обработки запросов
Чтобы создавать заявки нестандартного типа, как в нашем случае Inquiry, вам нужно поместить вызов конструктора этого типа в поле Новая заявка объекта source. Но, несмотря на то, что заявки в потоке теперь и будут типа Inquiry, остальные объекты диаграммы будут продолжать их считать заявками типа Entity.
Поэтому они не позволят явно обращаться к дополнительным полям класса Inquiry. Чтобы разрешить доступ к полям вашего нестандартного типа заявки в коде динамических параметров объектов потоковой диаграммы, вам нужно указать имя нестандартного типа заявки в качестве Типа заявки этого объекта. В нашей потоковой диаграмме с учётом блока source всего пять объектов.
(рис 1.51) Диаграмма после добавления элементов сбора статистики
(рис 1.52) Объект source с изменёнными свойствами
Измените их свойства.
source (Рис. 1.52):Тип заявки:. Это позволит напрямую обращаться к полям типа заявки Inquiry в коде динамических параметров этого объекта;
Inquiry() в поле Новая заявка:. Теперь этот объект будет создавать заявки нашего типа Inquiry;
entity.time_vxod=time(); в поле Действия При выходе:. Код будет сохранять время создания заявки-запроса в параметре time_vxod нашего типа заявки Inquiry.Функция time() возвращает текущее значение модельного времени.
queue:Inquiry в поле Тип заявки:.delay:Inquiry в поле Тип заявки:.sink1:Inquiry в поле Тип заявки:.sink:Inquiry в поле Тип заявки:;
Действие при входе следующие коды:
time_obrabotki.add(time()-entity.time_vxod);
Этот код добавляет время обработки одного запроса в объект сбора данных гистограммы time_obrabotki. Данное время определяется как разность между текущим модельным временем time() и временем входа запроса в модель. add - встроенная функция добавления элемента в массив.
entity.col_vixod=sink.count(); entity.col_vxod=source.count();
Эти коды заносят количество запросов, вошедших в блок sink и вышедших из блока source соответственно. count() - встроенная функция этих блоков, возвращает количество вошедших в блок sink и количество вышедших из блока source заявок.
ver_obrabotki.add(entity.col_vixod/entity.col_vxod);
Этот код добавляет относительную долю обработанных запросов в объект сбора данных гистограммы ver_obrabotki при поступлении каждого обработанного запроса в блок sink. На основе множества таких относительных долей определяется математическое ожидание вероятности обработки запросов сервером.
(рис 1.53) Второе сообщение об ошибке
Продолжить. Появится второе сообщение (Рис. 1.53).
(рис 1.54) Информация об ошибке в панели Консоль
Консоль Main.java.399 (Рис. 1.54). Появится код с выделенными ошибками.Мы установили тип int для col_vxod и col_vixod (см. Рис. 1.42). Изменим этот тип на double.
Обратите внимание, что вам не пришлось использовать поле time_vixod, так как вместо него была использована функция time(), возвращающая, как вам уже известно, текущее значение модельного времени.
Удалите поле time_vixod.
Проект дважды Щёлкните кнопку Inquiry. Откроется окно Inquiry (см. Рис. 1.48).
time_vixod, выделив его и нажав Delete.
col_vxod. Из выпадающего списка Тип: вместо int выберите double (Рис. 1.55).
col_vixod. Из выпадающего списка Тип: вместо int выберите double.
(рис 1.55) Окно после удаления поля time_vixod
Основная элемент Параметр. Дайте ему любое имя и установите Тип: из выпадающего списка. В дальнейшем это поле нестандартного типа заявки вы можете использовать в кодах модели.Итак, все условия постановки задачи выполнены. Чтобы наблюдать за работой модели, установите, что время остановки модели не задано. Запустите модель. (Рис. 1.56).
(рис 1.56) Фрагмент работы модели
Активный объект может иметь параметры. Параметры обычно используются для задания статических характеристик объекта. Но значения параметров при необходимости можно изменять во время работы модели. Для этого нужно написать код обработчика события, то есть действий, которые должны выполняться при изменении значения параметра.
Создайте параметр time_mean объекта delay.
Палитре выделите Основная.
Параметр на диаграмму класса Main и разместите ниже объекта delay, чтобы было видно, к какому объекту относится параметр.
Свойства (Рис. 1.57).
Имя введите имя параметра time_mean (среднее время). По этому имени параметр будет доступен из кода.
double.
(рис 1.57) Окно установки свойств элемента Параметр
Значение по умолчанию установите 180. Если значение не задано явно, по правилам Java оно будет равно нулю.
delay.
Свойства в поле Время задержки вместо выражения exponential(1/180.0) введите выражение exponential(1/time_mean).Пусть вы хотите изменять среднее время обработки запросов time_mean в ходе моделирования. Используйте для этого элемент управления - бегунок.
Элементы управления и перетащите элемент Бегунок из палитры на диаграмму класса Main (Рис. 1.58).
time_mean, чтобы было понятно, что с помощью этого бегунка будет меняться среднее время обработки запросов объектом delay.
Минимальное значение:, а 300 - в поле Максимальное значение: (Рис. 1.59).
Связать с: и в активизированное поле введите time_mean.Пусть теперь вы хотите также изменять ёмкость буфера в ходе моделирования. Используйте для этого также бегунок.
Элементы управления и перетащите элемент Бегунок из палитры на диаграмму класса Main (Рис. 1.59).
(рис 1.58) Установка элемента управления Бегунок
(рис 1.59) Окно установки свойств элемента управления Бегунок
Максимальное значение.
Связать с: и в активизированное поле введите queue.capacity.
Приостановить приостановить работу модели, изменить значения параметров, а затем продолжить моделирование (Рис. 1.60).
Main.Мы научились добавлять элементы Параметр и Бегунок. Но согласитесь, что какие параметры модели нужно будет менять, и в каких интервалах, заранее определить затруднительно. Также при использовании элемента Бегунок существуют трудности точного установления значения характеристики, так как невозможно предусмотреть нужный масштаб или цену деления Бегунка.
(рис 1.60) Фрагмент работы модели с добавленным элементом Параметр и элементами управления
Существует и другой способ изменения свойств объектов во время выполнения модели: нужно щёлкнуть по элементу, войти в режим редактирования и ввести новое значение в одной из закладок всплывающего окна инспекта. Поэтому заранее не нужно продумывать, значения каких параметров планируется изменять, и не добавлять специальные элементы управления (например, бегунки).
Изменение значения в окне инспекта поддерживается для следующих элементов: простая переменная; параметр; накопитель.
И для следующих типов: численные; логический (boolean); текстовый (String).
Бегунок для Параметра time_mean.
Параметра time_mean.
Параметр вы увидите введённое вами значение 240.0.
(рис 1.61) Ввод нового значения параметра в окно инспекта
Теперь добавим на диаграмму нашего потока гистограмму, которая будет отображать собранную временную статистику.
Гистограмма из палитры Статистика в то место графического редактора, куда хотите ее поместить.
Данные имя соответствующего элемента: time_obrabotki (Рис. 1.62). Установите Отображать среднее.
Заголовок: введите Histogram Time obrabotki.Добавим на диаграмму нашего потока гистограмму, которая будет отображать собранную вероятностную статистику.
Гистограмма из палитры Статистика.
Добавить данные и введите в поле Данные имя элемента: ver_obrabotki. Установите Отображать среднее.
Заголовок: введите Histogram Ver obrabotki.
time_mean=180, хотя ранее мы изменили его значение на 240.
(рис 1.62) Окно установки свойств элемента Гистограмма
(рис 1.63) Фрагмент работы модели с элементом управления и гистограммами
Построенная модель соответствует постановке задачи (п. 1.2.1). В ней, с целью упрощения процесса построения первой модели, время обработки запросов сервером было принято распределённым по показательному (экспоненциальному) закону со средним значением T2 = 3 мин.
Однако в модели время обработки поступающих запросов зависит от производительности сервера $$Q=6\cdot 10^5$$ оп/с и вычислительной сложности запросов, распределенной по нормальному закону с математическим ожиданием $$S1=6\cdot 10^7$$ оп и среднеквадратическим отклонением $$S2=2\cdot 10^5$$ оп.
Кроме того, в модели определяется среднее количество запросов, обработанных за время моделирования 3600 с.
Внесите в модель изменения для аналогичного расчёта времени обработки запросов.
Параметр с именем time_mean элемент Бегунок для элемента queue.
Основная перетащите три элемента Параметр на диаграмму класса Main (Рис. 1.64).
Имя каждого из элементов введите S1_, S2_ и Q_ соответственно. Выберите Тип double.
Значение по умолчанию каждого из элементов введите 60000000,200000 и 600000 соответственно.
Переменная.
Имя укажите KolZap.
delay.
Время задержки вместо exponential(1/time_mean) введите:(normal(S2_,S1_))/Q_
sink. В поле Действие при входе к имеющемуся там коду добавьте код:
KolZap=sink.in.count()/9604.0;
Для получения результатов моделирования с доверительной вероятностью $$\alpha =0,95$$ и точностью $$\varepsilon =0,01$$ нужно выполнить 9604 прогонов модели:
$$N=t^2_\alpha \cdot \frac{p\cdot (1-p)}{\varepsilon ^2}=1,96^2\cdot \frac{0,5^2}{0,01^2}\approx 9604$$где $$t_\alpha = 1,96$$ - табулированный аргумент функции Лапласа, p - ожидаемая вероятность исхода события, в данном случае вероятность обаботки запросов сервером.
Расчёт проведен для так называемого "худшего" случая, то есть в предположении, что ожидаемая вероятность обработки запросов p = 0,5.
Увеличим время моделирования в AnyLogic-модели в 9604 раз. А так как статистические данные о количестве обработанных запросов собираются за всё время моделирования, увеличенное в 9604 раз, то для получения среднего значения это количество нужно разделить на 9604, что и предусмотрено в коде.
(рис 1.64) Элементы AnyLogic-модели, соответствующие постановке
Проект выделите Simulation. На странице Модельное время в поле Установить выберите В заданное время.
Конечное время установите 34574400.
Результаты моделирования приведены на Рис. 1.65.
(рис 1.65) Результаты моделирования обработки запросов сервером
Для проведения исследований на модели сделайте ещё несколько дополнений и изменений. Можно было бы обойтись и без них, но они улучшат эксплуатацию модели.
Основная перетащите три элемента Параметр на диаграмму агента Main. Разместите их выше параметров S1_, S2_, Q_. Можно перетащить один параметр, скопировать его и вставить остальные два. Если установить свойства первого элемента Параметр, то они будут и в скопированных элементах. Не будем их устанавливать. Установим после копирования и вставки.
Параметр. В поле Имя: первого параметра введите timeMean - среднее время поступления запросов для обработки на сервере. Оставьте тип double.
Значение по умолчанию введите 120.
source. В поле Время между прибытиями вместо 120.0 введите timeMean. Теперь вам при изменении среднего времени поступления запросов не придётся искать нужный код в свойствах объекта модели.
Параметр. В поле Имя: введите kolProg - количество прогонов модели. Как и в предыдущем случае, при корректировке числа прогонов код в свойствах искать будет не нужно. Оставьте тип double.
Значение по умолчанию введите 9604.
sink.
Действие при входе в имеющемся там коде замените последнюю строку следующей:
KolZap=round(sink.in.count()/kolProg);
На Рис. 1.10. количество обработанных запросов KolZap сервером выдаётся с дробной частью. Теперь, вследствие применения процедуры round, количество запросов будет целым.
Как уже отмечалось, при изменении количества прогонов модели не надо будет искать код для требуемой корректировки. Однако всё-таки потребуется изменить модельное время. Например, если нужно выполнять с моделью 1000 прогонов, то модельное время следует установить равным 3600*1000=3600000.
Параметр. В поле Имя: введите emkBuf - ёмкость в сообщениях входного буфера сервера. Установите тип int.
Значение по умолчанию введите 5.
queue. В поле Вместимость введите emkBuf.
Проведём несколько экспериментов. Будем изменять среднее время поступления запросов timeMean в предположении, что с течением времени количество источников запросов будет расти, то есть timeMean будет уменьшаться. В сторону увеличения будем изменять ёмкость входного буфера emkBuf и производительность Q_ сервера.
(рис 1.66) Результаты моделирования при условиях постановки задачи
Результаты экспериментов приведены в Табл. 1.2.
Из экспериментов 1 и 2 следует, что при увеличении ёмкости входного буфера в два раза вероятность обработки запросов увеличивается незначительно на 0,025, то есть количество обработанных запросов практически одно и тоже. Среднее время обработки одного запроса возрастает в 1,27 раза вследствие увеличения длины очереди в 1,48 раза.
Увеличение интенсивности поступления запросов в три раза при увеличении ёмкости входного буфера в два раза (эксперименты 3 и 4) также не даёт существенного увеличения количества обработанных запросов: 36 вместо 30.
| Показатели | GPSS World | AnyLogic6 | AnyLogic7 |
|---|---|---|---|
| 1) timeMean = 120, emkBuf = 5 | |||
| Количество обработанных запросов | 29 | 29 | 29 |
| Вероятность обработки запросов | 0,97 | 0,971 | 0,97 |
| Среднее время обработки одного запроса | 255,262 | 254,942 | 255,727 |
| Средняя длина очереди запросов к серверу | 1,258 | 1,254 | 1,261 |
| Коэффициент использования сервера | 0,81 | 0,81 | 0,81 |
| 2) timeMean = 120, emkBuf = 10 | |||
| Количество обработанных запросов | 29 | 30 | 30 |
| Вероятность обработки запросов | 0,995 | 0,995 | 0,995 |
| Среднее время обработки одного запроса | 328,328 | 321,54 | 325,017 |
| Средняя длина очереди запросов к серверу | 1,902 | 1,841 | 1,87 |
| Коэффициент использования сервера | 0,833 | 0,831 | 0,831 |
| 3) timeMean = 40, emkBuf = 5 | |||
| Количество обработанных запросов | 36 | 36 | 36 |
| Вероятность обработки запросов | 0,4 | 0,399 | 0,4 |
| Среднее время обработки одного запроса | 1055,335 | 1055,108 | 554,983 |
| Средняя длина очереди запросов к серверу | 4,554 | 4,552 | 4,55 |
| Коэффициент использования сервера | 1 | 1 | 1 |
| 4) timeMean = 40, emkBuf = 10 | |||
| Количество обработанных запросов | 36 | 36 | 36 |
| Вероятность обработки запросов | 0,399 | 0,399 | 0,4 |
| Среднее время обработки одного запроса | 591,86 | 591,304 | 1054,907 |
| Средняя длина очереди запросов к серверу | 9,554 | 9,551 | 9,549 |
| Коэффициент использования сервера | 1 | 1 | 1 |
| 5) timeMean = 40, emkBuf = 10, Q_ = 1000000 | |||
| Количество обработанных запросов | 59 | 60 | 60 |
| Вероятность обработки запросов | 0,666 | 0,665 | 0,667 |
| Среднее время обработки одного запроса | 591,86 | 591,304 | 591,129 |
| Средняя длина очереди запросов к серверу | 8,855 | 8,852 | |
| Коэффициент использования сервера | 1 | 1 | 1 |
| 6) timeMean = 40, emkBuf = 15, Q_ = 2000000 | |||
| Количество обработанных запросов | 90 | 90 | 90 |
| Вероятность обработки запросов | 1 | 1 | 1 |
| Среднее время обработки одного запроса | 74,859 | 75,049 | 75,096 |
| Средняя длина очереди запросов к серверу | 8,864 | 1,096 | 1,128 |
| Коэффициент использования сервера | 0,751 | 0,75 | 0,751 |
При этом уменьшается вероятность обработки запросов в 2,5 раза, а время обработки одного запроса возрастает в 3,25 раза. Возросла и средняя длина очереди запросов к серверу
Коэффициент использования сервера равен 1. Из этого следует, что добиться увеличения вероятности и количества обработанных запросов можно только увеличением производительности сервера.
В экспериментах 5 и 6 увеличена производительность сервера до 1000000 и 2000000 оп/c соответственно.
По сравнению с экспериментом 1 количество обработанных запросов в эксперименте 5 увеличилось в 2 раза, а в эксперименте 6 - в 3 раза (вероятность обработки запросов равна 1). Среднее время обработки одного запроса всё равно примерно в 2 раза больше в эксперименте 5, а в эксперименте 6 - в 3,4 раза меньше. Можно полагать, что такая разница в среднем времени обработки одного запроса вызвана тем, что в эксперименте 5 средняя длина очереди запросов к серверу 8,852, а в эксперименте 6 - 1,128, то есть в 7,85 раза меньше.
Коэффициент использования сервера в эксперименте 6 равен 0,751. Из этого следует, что дальнейщее увеличение производительности сервера приведёт к уменьшению длины очереди и среднего времени обработки одного запроса.
Машинное время выполнения модели в AnyLogic примерно 70…90 с.
При имитационном моделировании с использованием специальных инструментальных средств, например, GPSS World, в общем случае решаются две задачи. Назовем их прямой и обратной.
Прямая задача заключается в нахождении оценки математического ожидания какого-либо показателя моделируемой системы при заданном времени ее функционирования.
Обратная задача состоит в определении оценки математического ожидания времени функционирования системы, за которое какой-либо её показатель достигает заданного значения.
Решение этих задач, особенно обратной задачи, имеет свои особенности. Рассмотрим эти особенности далее на примерах. Начнём построение GPSS-моделей с прямой задачи.
Сервер обрабатывает запросы, поступающие с автоматизированных рабочих мест (АРМ) с интервалами, распределенными по показательному закону со средним значением T1 = 2 мин. Сервер имеет входной буфер ёмкостью 5 запросов.
Вычислительная сложность запросов подчинена нормальному закону с математическим ожиданием $$S1=6\cdot 10^7$$ оп и среднеквадратическим отклонением $$S2=2\cdot 10^5$$ оп. Производительность сервера $$Q=6\cdot 10^5$$ оп/с. В случае полной занятости входного буфера поступающий запрос теряется.
Построить имитационную модель обработки запросов сервером для определения оценки математического ожидания количества запросов (дальше - количества запросов), обработанных сервером за время функционирования T = 1 час, и оценки математического ожидания вероятности обработки запросов (дальше - вероятности обработки запросов).
Сервер представляет собой однофазную систему массового обслуживания разомкнутого типа с ожиданием и с отказами.
В модели для имитации источника запросов следует использовать блок GENERATE, для имитации сервера как одноканального устройства - блоки SEIZE и RELEASE, для имитации буфера - QUEUE и DEPART, обработки запросов - ADVANCE.
В модели должны быть следующие элементы:
Серверу дадим имя Server. Для вывода из модели транзактов, имитирующих обработанные и потерянные запросы, используем блоки TERMINATE с метками ObrZap и PotZap соответственно. Для счета количества всех запросов используем метку KolZap.
Выберем масштаб: 1 единице масштабного времени соответствует 1 с. Так как среднее значение интервалов поступления запросов ,$$T1=2$$ мин. то теперь это будет 120 ед. мод. времени.
Рассчитаем количество прогонов, которые нужно выполнить в каждом наблюдении, т. е. проведем так называемое тактическое планирование эксперимента. Пусть результаты моделирования (вероятность обработки запросов) нужно получить с доверительной вероятностью $$\alpha =0,95$$ и точностью $$\varepsilon =0,01$$ Расчет проведем для худшего случая, т. е. при вероятности $$p =0,5$$, так как до эксперимента $$p$$ неизвестно:
$$N=t^2_\alpha \cdot \frac{p\cdot (1-p)}{\varepsilon ^2}=1,96^2\cdot \frac{0,5\cdot (1-0,5)}{0,01^2}=3,8416\cdot \frac{0,25}{0,0001}=9604$$Построим блок-диаграмму модели для решения прямой задачи, т. е. сегмент имитации поступления и обработки запросов и сегмент задания времени моделирования и расчета результатов моделирования (Рис. 1.1).
Блок-диаграмма представляет собой набор стандартных блоков. Она строится так. Из множества блоков выбирают нужные, и далее выстраивают их в диаграмму для того, чтобы в процессе функционирования модели они как бы взаимодействовали друг с другом. Диаграмма сопровождается необходимыми комментариями. Использование блоков при построении моделей зависит от логических схем работы реальных систем, моделируемых на ЭВМ.
Теперь приступим к написанию программы модели.
(рис 1.1) Блок-диаграмма модели
Для задания исходных данных используем переменные пользователя. Они задаются с помощью команды EQU. Переменным пользователя даны такие же имена, как и в постановке задачи, но добавлен знак подчеркивания. Например, T1_, S1_ и т. д. Время моделирования зададим переменной пользователя VrMod.
Арифметическая переменная для расчета времени обработки VrObr запроса на сервере:
VrObr VARIABLE (Normal(2,(S1_#Koef),(S2_#Koef))))/Q_
Переменная пользователя Koef введена для удобства изменения (пропорционального изменения) характеристик нормального закона распределения, которому подчиняется вычислительная сложность запросов. Особенно целесообразно использование этой переменной при проведении экспериментов.
Вероятность обработки VerObr запросов на сервере будем определять как отношение количества обработанных N$ObrZap запросов к количеству всего поступивших N$KolZap запросов:
VerObr VARIABLE N$ObrZap/N$KolZap
В арифметическом выражении VerObr, например, N$ObrZap - системный числовой атрибут - количество транзактов, вошедших в блок с меткой ObrZap, а N$KolZap - количество транзактов, вошедших в блок с меткой KolZap.
Количество обработанных запросов определяется арифметическим выражением:
Res VARIABLE INT(N$ObrZap/X$Prog)
Все необходимое для написания программы модели имеется. Напишем программу модели для решения прямой задачи.
; Обработка запросов сервером. Прямая задача ; Задание исходных данных T1_ EQU 120 ; Средний интервал поступления запросов, с S1_ EQU 60000000 ; Среднее значение вычислительной сложности запросов, оп S2_ EQU 200000 ; Стандартное отклонение вычислительной сложности запросов, оп Q_ EQU 600000 ; Средняя производительность сервера, оп/с Emk EQU 5 ; Ёмкость входного буфера Koef EQU 1 ; Коэффициент изменения характеристик нормального распределения VrObr VARIABLE (Normal(9,(S1_#Koef),(S2_#Koef)))/Q_ VerObr VARIABLE N$ObrZap/N$KolZap Res VARIABLE INT(N$ObrZap/X$Prog) VrMod EQU 3600 ; Время моделирования, 1 ед. мод. времени = 1 с. ; Сегмент имитации обработки запросов GENERATE (Exponential(2,0,T1_)) ; Источник запросов KolZap TEST L Q$Server,Emk,PotZap ; Занят ли буфер? QUEUE Server ; Встать в очередь к серверу SEIZE Server ; Занять сервер DEPART Server ; Покинуть очередь к серверу ADVANCE V$VrObr ; Имитация обработки запроса SAVEVALUE SumTime+,M1; Время обработки всех запросов RELEASE Server ; Освободить сервер ObrZap TERMINATE ; Обработанные запросы PotZap TERMINATE ; Потерянные запросы ; Сегмент задания времени моделирования и расчета результатов GENERATE VrMod TEST L X$Prog,TG1,Met1 ; Если X$Prog < TG1, SAVEVALUE Prog,TG1 ; то X$Prog = TG1 Met1 TEST E TG1,1,Met2 ; Если TG1 = 1, то SAVEVALUE VerObr,V$VerObr ; расчет и сохранение в ячейке VerObr вероятности обработки запросов SAVEVALUE Res,V$Res ; числа обработанных запросов SAVEVALUE TimeMean,(X$SumTime/N$ObrZap) Met2 TERMINATE 1 START 9604 ; Количество прогонов модели
При расчете количества обработанных запросов Res в арифметическом выражении N$ObrZap/X$Prog используется число прогонов. В арифметическом выражении указано не явное число прогонов, а в виде содержимого ячейки X$Prog. Число прогонов заносится предварительно в эту ячейку по завершении первого прогона модели, но до того момента, когда из счетчика завершений TG1 будет вычтена первая единица. В этом случае арифметическое выражение не зависит от числа прогонов, которое может меняться на различных этапах создания и эксплуатации модели, в том числе и в зависимости от исходных данных, а также от точности и достоверности результатов моделирования. Поскольку количество обработанных запросов не может быть дробным числом, то для получения целого числа, записываемого в ячейку Res, используется процедура INT из встроенной библиотеки.
Среднее время X$TimeMean обработки одного запроса определяется как отношение суммарного времени X$SumTime к количеству обработанных запросов N$ObrZap. В данной модели можно определять X$TimeMean как сумму средних времен обработки одного транзакта на сервере и среднего времени задержки в очереди.
Для уменьшения машинного времени расчет искомых показателей производится не после каждого прогона, а после завершения последнего прогона, т. е. когда содержимое счетчика завершений будет равно единице (TG1 = 1).
File / New и в появившемся меню выберите Model. Нажмите Ok.
[Tab]. Например, после набора Т1_ нужно нажать клавишу [Tab]. Интервалы табуляции установлены по умолчанию.
Command / Create Simulation. По этой команде транслятор GPSS проверяет программу модели на наличие синтаксических ошибок.
JOURNAL выдаст список сообщений об ошибках трансляции. Перейдите к п. 7. При отсутствии ошибок в окне JOURNAL появится сообщение Model Translation Begun. Ready. Перейдите к п. 9.
Search / Next Error, предварительно перейдя из окна JOURNAL в текст программы модели. При первом выполнении этой команды курсор мыши помещается в строке текста модели с ошибкой. После исправления первой ошибки вновь используйте команду Search / Next Error и т.д. столько раз, сколько ошибок в тексте программы.
File / Save As. Дайте модели имя Модель процессов изготовления изделий и нажмите Ok.
Command / Start и в диалоговом окне вместо 1 наберите 9604. Нажмите Ok.
Search / Goto Line столько раз, сколько ошибок указано в окне JOURNAL. Там же (в окне JOURNAL) указаны номера строк с ошибками.
Report. В окне будут содержаться следующие данные:В результате решения прямой задачи получим, что за один час сервером будет обработано N=29 запросов, а вероятность обработки составит VerObr=0,97. Если не использовать процедуру INT - выделения целого числа с отбрасыванием дробной части, будет обработано 29,161 запроса. Среднее время обработки одного запроса составит TimeMean=255,262
Сущность этого эксперимента состоит в проведении многофакторного дисперсионного анализа с целью выявления степени влияния различных факторов и их комбинаций (взаимодействий) на значение целевой функции (функции отклика, представленной в виде уравнения регрессии).
Для каждого фактора необходимо выбрать два уровня - нижний и верхний. Рекомендуется выбирать уровни, значительно отстоящие друг от друга. Это необходимо для получения также значительно отличающихся откликов.
В условиях прямой задачи требуется исследовать зависимость вероятности обработки запросов от трех факторов, например, при следующих их минимальных и максимальных значениях (Табл. 1.1):
| Уровни факторов | Факторы | ||
|---|---|---|---|
| T1_, с | Koef | Q_, оп/c | |
| Нижний | 60 | 0,5 | 300000 |
| Верхний | 180 | 1,5 | 700000 |
Для проведения дисперсионного анализа нужно воспользоваться созданным в п. 1.1.1.4 объектом "Модель". В программе модели удалите последнюю строку.
Откройте модель Прямая задача. Выберите Edit / Insert Experiment / Screening … (Правка / Вставить эксперимент / Отсеивающий …).
Откроется диалоговое окно Screening Experiment Generator (Генератор отсеивающего эксперимента) (Рис. 1.2).
Приступите к заполнению полей диалогового окна.
В поля Experiment Name (Имя эксперимента) и Run Procedure Name (Имя процедуры запуска) введите, например, Dis_Server и Dis_Server_Run соответственно (Рис. 1.3).
Имена эксперименту и процедуре запуска эксперимента даёт пользователь.
Дальше расположена группа полей Factors (Факторы). В рассматриваемом примере определяется вероятность обработки запросов, поступающих на сервер. Факторы, влияние которых необходимо исследовать, были определены нами ранее (см. Табл. 1.1).
(рис 1.2) Диалоговое окно (незаполненное) Screening Experiment Generator (Генератор отсеивающего эксперимента)
(рис 1.3) Диалоговое окно (заполненное) Screening Experiment Generator (Генератор отсеивающего эксперимента)
В GPSS World максимальное количество факторов, влияние которых на функцию отклика можно исследовать посредством дисперсионного анализа, равно шести.
Введите ранее выбранные факторы, начиная с фактора А. В поле Name (User Variable) (Имя (Переменная пользователя)) введите имя фактора, в поля Value1 и Value2 - его нижний и верхний уровни соответственно. После ввода всех факторов для дальнейшей работы будем иметь факторы А, В и С.
Ниже идет группа Fraction (Часть полного эксперимента). Эксперимент, проводимый в GPSS World, может быть полным факторным экспериментом (ПФЭ) или дробным факторным экспериментом (ДФЭ). Группа Fraction (Часть дробного эксперимента) позволяет это задавать, т. е. позволяет провести стратегическое планирование эксперимента, цель которого, как вам известно, является определение количества наблюдений и сочетаний уровней факторов в них для получения наиболее полной и достоверной информации о поведении системы.
Установке ПФЭ соответствует кнопка Full, для ДФЭ в 1/2 от ПФЭ - Half, в 1/4 - Quarter, в 1/8 - Eight, в 1/16 - Sixteen.
Установите пока Half (1/2). Справа под Run Count появится число 4, так как $$2^2=4$$. Это количество наблюдений, которое необходимо сделать. Количество прогонов в каждом наблюдении будет указано позже.
В поле Expression (Выражение) группы Result (Результат) введите выражение, по которому вычисляется вероятность обработки запросов: N$ObrZap/N$KolZap.
После группы Result (Результат) расположены два флажка, позволяющие выбирать опции.
При выборе опции Generate Run Procedure вместе с экспериментом создается стандартная процедура запуска, которую пользователь может корректировать согласно своим требованиям.
Выбор второй опции Load F11 with CONDUCT Command закрепляет команду CONDUCT за функциональной клавишей F11. Тогда после создания объекта "Процесс моделирования" для запуска эксперимента нужно только нажать функциональную клавишу F11. Выберите обе опции.
Перед созданием эксперимента необходимо изучить группы смешивания с целью осуществления стратегического планирования эксперимента. Для этого нужно нажать кнопку Alias Groups (Группы смешивания). Появится диалоговое окно Alias Groups (Группы смешивания) (Рис. 1.4).
При изучении групп смешивания необходимо вначале найти отсутствующие факторы, а затем факторы, которые неразличимы, так как находятся в одной группе смешивания. Например, взаимодействие факторов А и В - АВ.
(рис 1.4) Диалоговое окно Alias Groups (Группы смешивания)
Из Рис. 1.4 видно, что отсутствующих факторов нет. Факторы А, В и С находятся в различных группах смешивания по два фактора в каждом. Невозможно будет судить об эффектах, т. е. о влиянии на отклик взаимодействий двух факторов. В некоторых случаях этого будет достаточно.
Нажмите кнопку Cancel (Отмена).
В диалоговом окне Screening Experiment Generator (Генератор отсеивающего эксперимента) в группе Fraction (Часть дробного эксперимента) установите Full (ПФЭ). Под Run Count появится число 8.
Обратите внимание, что кнопка Alias Groups (Группы смешивания) при установке полного факторного эксперимента Full (ПФЭ) не будет активной.
Теперь необходимо создать Plus - операторы и вставить их в нижнюю часть модели Прямая задача. Для этого нажмите кнопку Insert Experiment (Вставить эксперимент), расположенную в левой нижней части диалогового окна Screening Experiment Generator (Генератор отсеивающего эксперимента).
Так как была выбрана опция Generate Run Procedure, то создана стандартная процедура запуска с именем Dis_Server_Run. Появится ее диалоговое окно, дающее возможность пользователю изменить процедуру запуска согласно своим требованиям (Рис. 1.5).
(рис 1.5) Диалоговое окно стандартной процедуры запуска
(рис 1.6) Условия стандартной процедуры запуска по умолчанию
Перейдите, пользуясь клавишами вверх-вниз, в конец процедуры запуска. Там в разделе Set up your own run conditions (Задайте свои условия наблюдения) имеются две команды START, между которыми находится команда RESET (Рис. 1.6).
Поясним назначение этих команд.
Первой командой START
DoCommand("START 100,NP"); /*Get past the Startup Period. */
определяется количество прогонов в неустоявшемся режиме.
Подразумевается, что если моделирование выполняется долго, то система приходит в стационарное состояние. Сколько времени следует вести моделирование, чтобы достичь стационарного состояния? Часто ответ на этот вопрос можно получить из опыта экспериментирования с моделью. Команда RESET служит для этого. Она сбрасывает в ноль накопленную на неустоявшемся режиме статистику без удаления транзактов из процесса моделирования.
Второй командой START
DoCommand("START 1000,NP"); /*Run the Simulation. */
определяется количество прогонов в наблюдении, т. е. количество прогонов, которое было определено ранее при тактическом планировании эксперимента: N = 9604. Измените 1000 на 9604 (Рис. 1.7).
Корректировка процедуры запуска возможна до и после того, как она будет добавлена к объекту "Модель".
(рис 1.7) Условия стандартной процедуры запуска после корректировки
После корректировки нажмите Ok.
Сгенерированный Plus - эксперимент представлен ниже. Изучите его. Это необходимо для создания собственных экспериментов, отличающихся от стандартных экспериментов GPSS World.
В начале автоматически сгенерированного эксперимента определяется и инициализируется в неопределенное состояние (UNSPECIFIED) матрица результатов. Далее имеются Plus - операторы, которые для каждого из наблюдений определяют сочетания уровней факторов. В рассматриваемом примере таких сочетаний восемь.
Plus - эксперимент содержит также вызов Plus - процедуры запуска. Процедура запуска осуществляет связь между генерируемым экспериментом и процессом моделирования. Она вызывается столько раз, сколько требуется сделать наблюдений. Так как процедура запуска вызывается Plus - экспериментом, ей разрешается вызывать библиотечную процедуру DoCommand и, следовательно, выполнять RMULT, CLEAR, RESET и многие другие команды GPSS. Поэтому все команды, необходимые для определения условий наблюдения, например, обнуление сохраняемых ячеек, следует помещать в процедуру запуска.
Для сохранения матрицы результатов при обнулении переменных перед очередным наблюдением используется команда CLEAR OFF. Для изменения начального числа генератора случайных чисел в каждом наблюдении процедуре передается номер запуска.
****************************************************
* Dis_Server *
* Факторный отсеивающий эксперимент *
****************************************************
Dis_Server_Results MATRIX ,2,2,2
INITIAL Dis_Server_Results,UNSPECIFIED
Dis_Server_NextRunNumber EQU 0
EXPERIMENT Dis_Server() BEGIN
/* Наблюдение 1 */
T1_ = 60;
Koef = 0.5;
Q_ = 300000;
IF (StringCompare(DataType(Dis_Server_Results[1,1,1]),
"UNSPECIFIED")'E'0)
THEN BEGIN
/* Установить начальное значение переменной количества наблюдений */
Dis_Server_NextRunNumber = 1;
/* Записать данные наблюдения и запустить процесс моделирования*/
Dis_Server_GetResult();
Dis_Server_Results[1,1,1] = N$ObrZap/N$KolZap;
END;
/* Наблюдение 2 */
T1_ = 60;
Koef = 0.5;
Q_ = 700000;
IF (StringCompare(DataType(Dis_Server_Results[1,1,2]),
"UNSPECIFIED")'E'0)
THEN BEGIN
/* Записать данные наблюдения и запустить процесс моделирования */
Dis_Server_GetResult();
Dis_Server_Results[1,1,2] = N$ObrZap/N$KolZap;
END;
/* Наблюдения 3 - 7 для краткости пропущены */
/* Наблюдение 8 */
T1_ = 180;
Koef = 1.5;
Q_ = 700000;
IF (StringCompare(DataType(Dis_Server_Results[2,2,2]),
"UNSPECIFIED")'E'0)
THEN BEGIN
/* Записать данные наблюдения и запустить процесс моделирования */
Dis_Server_GetResult();
Dis_Server_Results[2,2,2] = N$ObrZap/N$KolZap;
END;
/* Эффекты смешивания в дробном факторном эксперименте */
SE_Effects(Dis_Server_Results,"I");
END;
*******************************************************
* Процедура запуска наблюдения *
*******************************************************
PROCEDURE Dis_Server_GetResult() BEGIN
/* Выполнить указанное число прогонов и записать результаты. */
/* Факторы для этого наблюдения уже были определены. */
TEMPORARY CurrentYield,ShowString,CommandString;
/* Вызов процедуры запуска */
Dis_Server_Run(Dis_Server_NextRunNumber);
CurrentYield = N$ObrZap/N$KolZap;
ShowString = PolyCatenate("Run ",String(Dis_Server_NextRunNumber),". ", "" );
ShowString = PolyCatenate(ShowString," Yield=",String(CurrentYield),". ");
ShowString = PolyCatenate(ShowString," T1_=",String(T1_), ";" );
ShowString = PolyCatenate(ShowString," Koef=",String(Koef), ";" );
ShowString = PolyCatenate(ShowString," Q_=",String(Q_), ";" );
CommandString = PolyCatenate("SHOW """,ShowString,"""", "" );
DoCommand(CommandString);
Dis_Server_NextRunNumber = Dis_Server_NextRunNumber + 1;
RETURN CurrentYield;
END;
*******************************************************
* Процедура запуска *
*******************************************************
PROCEDURE Dis_Server_Run(Run_Number) BEGIN
DoCommand("CLEAR OFF"); /* Использовать OFF для сохранения результата. */
/* Увеличьте число команд RMULT, если у вас большее число ГСЧ. */
/* Задать новые случайные числа всем потокам случайных чисел. */
TEMPORARY CommandString;
/* Вычислить, прежде чем перейти к DoCommand. */
CommandString = Catenate("RMULT ",Run_Number#111);
/* DoCommand контролирует строку в глобальном контексте. */
DoCommand(CommandString);
/* Установить собственные условия наблюдения. */
DoCommand("START 100,NP"); /* Пройти неустоявшийся режим. */
DoCommand("RESET"); /* Начать период измерений. */
DoCommand("START 9604,NP"); /* Провести моделирование. */
END;
Проведем эксперимент. Для вызова эксперимента предназначена команда CONDUCT. Однако за функциональной клавишей [F11] была закреплена соответствующая команда CONDUCT (Edit / Settings / Function Keys (Правка / Настройки / Функциональные клавиши)).
Проведите трансляцию, т. е. создайте объект "Процесс моделирования", для чего нажмите [Ctrl]+[Alt]+[S] или выполните команду Command / Create Simulation (Команда / Создать процесс моделирования).
При отсутствии ошибок в сгенерированном эксперименте в окне Journal (Журнал) появится сообщение (Рис. 1.8), свидетельствующее об отсутствии ошибок. Нажмите функциональную клавишу [F11]. Эксперимент начинает работать.
HALT. Остальные команды неактивны, т. е. процесс моделирования можно только остановить и потом продолжить, но просмотреть его с использованием меню, вызываемого командой WINDOW / SIMULATION WINDOW и другими командами, нельзя.В ходе выполнения сгенерированного эксперимента автоматически создается отчет, который по готовности записывается в окно Journal (Журнал) объекта "Процесс моделирования". Фрагмент отчета для четырех наблюдений (Run1 … Run4) показан на Рис. 1.9. В отчете содержатся Yield - целевая функция и значения факторов, при которых получение значение целевой функции.
(рис 1.8) Окно Journal (Журнал) с сообщением об успешном создании объекта "Процесс моделирования"
(рис 1.9) Окно Journal (Журнал) с отчетами по каждому наблюдению
Так как эксперимент включает 8 наблюдений по 9604 прогонов в каждом из них, то будет выдано 8 отчетов (на Рис. 1.9 в целях сокращения показаны только первые четыре отчета). Окончательные результаты моделирования после статистической обработки будут выведены в виде таблицы Anova (Рис. 1.10).
В таблице каждый фактор и взаимодействие факторов представлены отдельной строкой. В каждой строке для всех эффектов указаны коэффициенты, с которыми они входят в целевую функцию (столбец Effect), а для главных эффектов (А, В, С) - суммы квадратов отклонений - столбец Sum of Squares.
В столбце Degrees of Freedom приведены степени свободы соответствующих измерений.
В столбце F-for Only Main Effects - вычисленные значения F-статистик для главных эффектов, а в столбце Critical Value of F (p=0,5) - соответствующие критические значения F - распределения для уровня значимости 50%.
В строке Error показаны остаточная составляющая дисперсии и соответствующая степень свободы.
В строке Total - общая сумма квадратов ошибок по всему эксперименту.
В строке Greand - среднее значение результата исследования (в примере - вероятности) по данным всего эксперимента.
(рис 1.10) Результаты дисперсионного анализа
Чем больше значение F-статистики (F-for Only Main Effects), тем сильнее эффект. Эффект, а, следовательно, и фактор, считается значимым, если превышает критическое значение (Critical Value of F(p=.05)).
В данном примере факторы А и В являются значимыми, так как их F-статистики больше критического значения, равного 7.71. Обратите внимание, что эффекты факторов А и В противоположны.
Таким образом, по результатам моделирования можно сделать вывод, что при данном потоке и характеристиках сервера вероятность обработки запросов в среднем составляет 0,731, т. е. вероятность потерь запросов составляет 0,269. Для уменьшения потерь запросов нужно продолжить исследование каждого значимого фактора А и В.
Для того чтобы определить среднее количество запросов, которые будут обработаны при таких же значениях факторов, проведите ёще один дисперсионный анализ.
Для этого удалите сгенерированный эксперимент из программы модели. Затем выберите Edit / Insert Experiment / Screening … (Правка / Вставить эксперимент / Отсеивающий …). Всё, что вы ранее вводили (см. Рис. 1.3), останется неизменным. Вам нужно будет только заменить в поле Expression (Выражение) группы Result (Результат) выражение, по которому вычисляется вероятность обработки запросов, выражением для расчёта количества обработанных запросов: N$ObrZap/X$Prog.
После замены вставьте эксперимент и выполните его. Вы получите, что среднее количество обработанных запросов составит 25,889, а все факторы будут несущественными.
Для решения обратной задачи возьмем количество запросов, ожидаемое время обработки которых нужно определить, N=29 - результат решения прямой задачи.
Программа модели приведена ниже.
; Обработка запросов сервером. Обратная задача ; Задание исходных данных T1_ EQU 120 ; Средний интервал поступления запросов, с S1_ EQU 60000000 ; Среднее значение вычислительной сложности запросов, оп S2_ EQU 200000 ; Стандартное отклонение вычислительной сложности запросов, оп Q_ EQU 600000 ; Средняя производительность сервера, оп/c Emk EQU 5 ; Ёмкость входного буфера Koef EQU 1 ; Коэффициент изменения характеристик нормального распределения Koef1 EQU 1 ; Коэффициент учета дробной части N_ EQU 29 ; Количество запросов ; Сегмент имитации обработки запросов GENERATE (Exponential(1,0,T1_)) ; Источник запросов KolZap TEST L Q$Server,Emk,PotZap ; Занят ли буфер? QUEUE Server ; Встать в очередь к серверу SEIZE Server ; Занять сервер DEPART Server ; Покинуть очередь к серверу ADVANCE ((Normal(2,(S1_#Koef),(S2_#Koef)))/Q_) ; Имитация обработки запроса RELEASE Server ; Освободить сервер TRANSFER ,ObrZap ; Запрос отправляется в сегмент завершения моделирования PotZap TERMINATE ; Потерянные запросы ; Сегмент организации завершения моделирования и расчета результатов ObrZap TEST L X$Prog,TG1,Met1 ; Если X$Prog < TG1, SAVEVALUE Prog,TG1 ; то X$Prog = TG1 SAVEVALUE NZap,0 ; Обнуление счетчика обработанных запросов Met1 SAVEVALUE NZap+,1 ; Счет количества обработанных запросов TEST E X$NZap,N_,Ter1 ; Если X$NZap = N_, то TEST E TG1,1,Met2 ; если TG1 = 1, то SAVEVALUE VerObr,(N$ObrZap/N$KolZap) ; расчет и сохранение в ячейке VerObr вероятности обработки запросов SAVEVALUE TimeNZap,((AC1-X$AC2)/(X$Prog#Koef1)) ;расчет и сохранение в ячейке TimeNZap времени обработки запросов SAVEVALUE AC2,AC1 ; Запомнить абсолютное модельное время в ячейке АС2 Met2 SAVEVALUE NZap,0 ; Обнуление счетчика обработанных запросов TERMINATE 1 Ter1 TERMINATE START 1000,NP ; Прогоны до установившегося режима RESET ; Сброс накопленной статистики START 9604 ; Количество прогонов модели
При решении обратной задачи один прогон определяется заданным количеством запросов N_, которые нужно обработать сервером, а не временем моделирования. Для этого организован счетчик обработанных запросов в виде сохраняемой ячейки X$NZap. Как только содержимое X$NZap = N_, из счетчика завершений вычитается единица. Таким образом, фиксируется один прогон модели. После этого ячейка X$NZap обнуляется и начинается очередной прогон.
Для расчета времени обработки заданного количества запросов используется арифметическое выражение (AC1-X$AC2)/X$Prog. В состав этого выражения входят абсолютное модельное время АС1 и опять количество прогонов. Запоминается количество прогонов также как и при решении прямой задачи.
Кроме этого, в арифметическом выражении есть сохраняемая ячейка X$AC2. Дело в том, что команда RESET не влияет на абсолютное модельное время АС1. Время же выполнения 1000 прогонов до установившегося режима не должно участвовать в расчёте. Поэтому оно запоминается, а затем вычитается из абсолютного модельного времени выполнения 1000 + 9604 = 10604 прогонов. Число прогонов до установившегося режима может быть и другим.
В результате моделирования получим среднее время обработки 29 запросов 3579,401 с.
Фрагмент из отчета моделирования приведен ниже:
SAVEVALUE RETRY VALUE PROG 0 9604.000 NZAP 0 0 VEROBR 0 0.971 TIMENZAP 0 3579.401
А почему не 3600 сек? Ведь это же время моделирования было задано при решении прямой задачи? Потому что мы отбросили дробную часть, т. е. взяли 29, а не 29,161. Как же поступить, чтобы учесть и отброшенную дробную часть? Ведь в счётчике фиксируются обработанные запросы только целыми числами, а не дробными?
Для учёта десятых долей дробной части зададим N_ = 291, т. е. увеличим в 10 раз. Это нужно учесть и в арифметическом выражении: ((AC1-X$AC2)/(X$Prog#Koef1)). Переменной пользователя Koef1 задается значение 10. По завершении моделирования получим 3594,826 с. Этот результат уже ближе к 3600.
Для учёта сотых долей дробной части установим N_ = 2916, а Koef1 = 100. Получим 3602,099.
Вероятность обработки запросов в обоих случаях практически одна и та же, т. е. 0,971. Однако время моделирования существенно возрастает: 2 с, 21 с и 3 мин 34 c соответственно, т. е. более чем в 10 и 100 раз.
В примере обратной задачи также показано, что арифметические выражения можно не описывать отдельно до блоковой части программы вместе с заданием исходных данных (как в программе модели прямой задачи), а сразу записывать в соответствующих блоках, заключив в скобки (скобки можно и не ставить, но лучше это делать).
Например (см. сегмент организации завершения моделирования и расчета результатов):
ADVANCE ((Normal(2,(S1_#Koef),(S2_#Koef)))/Q_) ; Розыгрыш времени обработки запроса SAVEVALUE VerObr,(N$ObrZap/N$KolZap)) ; Расчет вероятности обработки запросов SAVEVALUE TimeNZap,((AC1-X$AC2)/(X$Prog#Koef1)) ; Расчет среднего времени обработки запросов
Сервер обрабатывает запросы, поступающие с автоматизированных рабочих мест с интервалами, распределенными по показательному закону со средним значением 2 мин. Время обработки сервером одного запроса распределено по экспоненциальному закону со средним значением 3 мин. Сервер имеет входной буфер ёмкостью 5 запросов.
Построить имитационную модель для определения математического ожидания времени и вероятности обработки запросов.
Сервер представляет собой однофазную систему массового обслуживания разомкнутого типа с ограниченной входной емкостью, то есть с отказами, и абсолютной надёжностью (Рис. 1.11).
На Рис. 1.11 приведены также объекты AnyLogic, которые будут использованы для создания диаграммы процесса. На них мы остановимся позже. Приступим к созданию диаграммы процесса.
(рис 1.11) Сервер как система массового обслуживания
Имя модели введите Server.
Местоположение или выбрать этот каталог с помощью диалога навигации по файловой системе, открывающегося нажатием кнопки Выбрать.
(рис 1.12) Диалоговое окно Новая модель
Готово. Откроется пользовательский интерфейс (Рис. 1.13). Остановимся на нём.
Проекты и панель Палитра. Панель Проект обеспечивает навигацию по элементам моделей, открытых в текущий момент времени. Модель организована иерархически. Она отображается в виде дерева. Сама модель образует верхний уровень дерева. Эксперименты, классы активных объектов и Java классы образуют следующий уровень. Элементы, входящие в состав активных объектов, вложены в соответствующую подветвь дерева класса активного объекта и т. д.
Палитра (левый вертикальный столбец) содержит разделённые по категориям элементы, которые могут быть добавлены на графическую диаграмму типа агентов или эксперимента. На Рис. 1.13 раскрыта палитра Презентация. Для того чтобы открыть нужную палитру, следует подвести курсор к иконке и щелкнуть мышью. Иконка становится светлой.
Свойства. Панель Свойства используется для просмотра и изменения свойств выбранного в данный момент элемента (или элементов) модели.
AnyLogic размещён графический редактор диаграммы агента Main.
(рис 1.13) Пользовательский интерфейс
.
Библиотеку моделирования процессов (Рис. 1.14). Из неё перетащите объекты на диаграмму и соедините, как показано на Рис. 1.15. Для добавления объекта на диаграмму, надо щёлкнуть его мыщью и, не отпуская её, перетащить в графический редактор.
(рис 1.14) Библиотека моделирования процессов
(рис 1.15) Диаграмма системы массового обслуживания
Дадим краткую характеристику объектов диаграммы.
Объект Source генерирует заявки определенного типа. Обычно он используется в качестве начальной точки диаграммы процесса, формализующей поток заявок. В нашем примере заявками будут запросы на обработку сервером, а объект Source будет моделировать их поступление.
Объект Queue моделирует очередь заявок, ожидающих приема объектами, следующими за данным в диаграмме процесса. В нашем случае он будет моделировать очередь запросов, ожидающих освобождения сервера.
Объект Delay задерживает заявки на заданный период времени. Он представляет в нашей модели сервер, обрабатывающий запросы.
Объект Sink уничтожает поступившие заявки. Обычно он используется в качестве конечной точки потока заявок (и диаграммы процесса соответственно).Помним, что мы хотим сначала создать простейшую модель, в которой будем рассматривать только обработку запросов сервером.
В основе каждой дискретно-событийной модели лежит диаграмма процесса - последовательность соединенных между собой объектов (Библиотеки моделирование процессов), задающих последовательность операций, которые будут производиться над проходящими по диаграмме процесса заявками.
Как вы уже знаете диаграмма процесса в AnyLogic создаётся путем добавления объектов библиотеки из палитры на диаграмму класса активного объекта, соединения их портов и изменения значений свойств блоков в соответствии с требованиями модели.
Всё, что нам нужно, чтобы сделать созданную диаграмму модели (см. Рис. 1.15) адекватной постановке задачи - это изменить некоторые свойства объектов.
Свойства объекта (как и любого другого элемента AnyLogic) можно изменить в панели Свойства.
Обратите внимание, что панель Свойства является контекстно-зависимой. Она отображает свойства выделенного в текущий момент элемента. Поэтому для изменения свойств элемента нужно будет предварительно щелчком мыши выделить его в графическом редакторе или в панели Проекты.
Чтобы всегда была уверенность в том, что в текущий момент в рабочем пространстве выбран именно нужный элемент, и именно его свойства вы редактируете в панели Свойства, обращайте внимание на первую строку, показываемую в панели Свойства - в ней отображается имя выбранного в текущий момент времени элемента и его тип.
Согласно принятым стандартам, объекты в диаграмме процесса обычно располагаются цепочкой слева направо, представляя собой последовательную очередность операций, которые будут производиться над заявкой.
Первым объектом в диаграмме процесса является объект класса Source. Объект source генерирует заявки определенного типа. Заявки представляют собой объекты, которые производятся, обрабатываются, обслуживаются, или еще каким-нибудь образом подвергаются действию моделируемого процесса: это могут быть клиенты в системе обслуживания, детали в модели производства, транспортные средства в модели перевозок, документы в модели документооборота, сообщения в моделях систем связи и т.д. В нашем примере заявками будут запросы на обработку данных, а объект source будет моделировать поступление запросов на сервер.
(рис 1.16) Свойства объекта source
В нашем случае объект создает заявки через временной интервал, распределенный по показательному (экспоненциальному) закону со средним значением 2 мин.
Установим среднее время поступления запросов и среднее время их обработки в секундах. Однако имеется воз-можность установить время в минутах, часах, днях, в чем вы убедитесь несколько позднее, когда будете устанавливать мо-дельное время.
Прибывают согласно: укажите, что запросы поступают согласно Времени между прибытиями: (Рис. 1.16).
Время между прибытиями появится запись exponential(1). Установите согласно постановке задачи среднее значение интервалов времени поступления запросов на сервер, изменив свойства объекта source. Для этого вместо характеристики распределения 1 введите 1/120.0.В языке программирования Java символ / означает целочисленное деление, т.е. если оба числа целые, то и результат будет целым. В нашем случае отношение 1/120 было бы равно нулю. Для получения вещественного результата, необходимо, чтобы хотя бы одно из чисел было вещественным (double). Поэтому в качестве характеристики экспоненциального распределения (интенсивности поступления запросов) необходимо указать 1/120.0 или 1.0/120.
Следующий объект - queue. Выделите его. Он моделирует очередь заявок, ожидающих приема объектами, следующими за данным объектом в диаграмме процесса. В нашем случае он будет, как уже отмечалось, моделировать очередь запросов, ждущих освобождения сервера.
Измените свойства объекта queue (Рис. 1.17).
Вместимость: 5. В очереди будут находиться не более 5 запросов.
Включить сбор статистики, чтобы включить сбор статистики для этого объекта. В этом случае по ходу моделирования будет собираться статистика по количеству запросов в очереди. Если же вы не установите этот флажок, то данная функциональность будет недоступна, поскольку по умолчанию она отключена для повышения скорости выполнения модели. Для вывода, например, средней длины очереди, нужно в модели предусмотреть Java код.
(рис 1.17) Свойства объекта queue
Следующим в нашей диаграмме процесса расположен объект delay. Он задерживает заявки на заданный период времени, представляя в нашей модели непосредственно сервер, на котором обрабатываются запросы.
Измените свойства объекта delay (Рис. 1.18).
Время задержки: exponential(1/180.0). Функция exponential() является стандартной функцией генератора случайных чисел AnyLogic. AnyLogic предос-тавляет функции и других случайных распределений, таких как нормальное, треугольное, и т. д.
(рис 1.18) Свойства объекта delay
Для вывода коэффициента использования объекта delay в модели также следует предусмотреть соответствующий Java код.
Последним в диаграмме нашей дискретно-событийной модели находится объект sink. Этот объект уничтожает поступившие заявки. Обычно он используется в качестве конечной точки потока заявок (и диаграммы процесса соответственно). В нашем случае он выводит из модели обработанные сервером запросы.
Вы можете сконфигурировать выполнение модели в соответствии с вашими требованиями. Модель выполняется в соответствии с набором установок, задаваемым специальным элементом модели - экспериментом. Вы можете создать несколько экспериментов с различными установками и, изменять конфигурацию модели, просто запуская тот или иной эксперимент модели.
В панели Проект эксперименты отображаются в нижней части дерева модели. Один эксперимент, названный Simulation, создается по умолчанию (см. справа). Это простой эксперимент, позволяющий запускать модель с заданными значениями параметров, поддерживающий режимы виртуального и реального времени, анимацию и отладку модели.
Если вы хотите наблюдать поведение модели в течение длительного периода (до того момента, пока вы сами не остановите выполнение модели), то по умолчанию времени остановки нет. Обработку запросов сервером мы планируем исследовать в течение одного часа, т.е. 3600 с.
Проект выделите эксперимент Simulation:Main.
Модельное время.
Виртуальное время (максимальная скорость) (Рис. 1.19).
Остановить: выберите из списка В заданное время.
Конечное время: установите 3600.
Случайность.
Фиксированное начальное число (воспроизводимые прогоны).
Начальное число: установите 9.
Проект, выделите Server (Рис. 1.20).
Единицы модельного времени: выберите секунды.Постройте вашу модель с помощью кнопки панели инструментов
(F7) Построить модель (при этом в рабочей области AnyLogic должен быть выбран какой-то элемент именно этой модели). Если в модели есть какие-нибудь ошибки, то построение не будет завершено, и в панель Ошибки будет выведена информация об ошибках, обнаруженных в модели. Двойным щелчком мыши по ошибке в этом списке вы можете перейти к предполагаемому месту ошибки, чтобы исправить её. При этом откроется соответствующее место ошибки.
(рис 1.19) Установка свойств эксперимента
(рис 1.20) Установка модельного времени
После исправления ошибок и построения модели, запустите её:
Запустить (или нажмите F5) и выберите из открывшегося списка эксперимент, который вы хотите запустить. Эксперимент этой модели будет называться Server/Simulation.
Запустить (или кнопки F5) будет запускаться тот эксперимент, который запускался вами в последний раз. Чтобы выбрать другой эксперимент, вам будет нужно щелкнуть мышью по стрелке, находящейся в правой части кнопки Запустить, и выбрать нужный вам эксперимент из открывшегося списка (или щелкнуть правой кнопкой мыши по этому эксперименту в панели Проект и выбрать Запустить из контекстного меню).
Main).
Библиотеке моделирования процессов, автоматически создается блок-схема с наглядной визуализацией процесса, с помощью которой вы можете изучать текущее состояние модели, например, длину очереди, количество обработанных запросов и так далее (Рис. 1.22).
(рис 1.21) Окно презентации модели
(рис 1.22) Модель остановилась с ошибкой
(рис 1.23) Сообщение о логической ошибке в модели
OK. Далее измените свойства объекта queue, т. е. увеличьте длину очереди (см. Рис. 1.17). Для этого введите в поле Вместимость 15. Можете убедиться, что при увеличении ёмкости в пределах 6 … 14 модель по-прежнему останавливается с этой же ошибкой. Момент появления ошибки зависит от длительности времени моделирования.
(рис 1.24) Окно инспекта
Можно было наблюдать, анализировать и интерпретировать работу запущенной модели с помощью визуализированной диаграммы процесса (см. Рис. 1.22, 1.24).
Однако удобнее в ряде случаев иметь более наглядную визуализацию с помощью анимации. В этой задаче мы хотим создать визуализированный процесс поступления запросов на сервер и обработки запросов сервером.
Так как в данном случае нас не интересует конкретное расположение объектов в пространстве, то мы можем просто добавить схематическую анимацию интересующих нас объектов - сервер и очередь запросов к нему.
Анимация модели рисуется в той же диаграмме (в графическом редакторе), в которой задается и диаграмма моделируемого процесса.
Нарисуйте прямоугольный узел, который будет обозначать на анимации сервер.
Разметка пространства (Рис. 1.25). Чтобы открыть какую-либо палитру, нужно щелкнуть по иконке этой палитры.
Разметка пространства (Рис. 1.25) содержит в качестве элементов различные примитивные фигуры, используемые для рисования презентаций моделей. Это путь, прямоугольный узел, многоугольный узел, точечный узел, аттрактор, стеллаж, масштаб.
(рис 1.25) Палитра Разметка пространства
Прямоугольный узел и перетащите его на диаграмму класса активного объекта. Поместите элемент Прямоугольный узел так, как показано на Рис. 1.26.
(рис 1.26) Элемент Прямоугольный узел на диаграмме
Внешний вид панели свойств (Рис. 1.27).
Если нужно, чтобы по ходу моделирования то или иное свойство фигуры меняло своё значение в зависимости от каких-то условий, то можете ввести в поле соответствующего динамического свойства выражение, которое будет постоянно вычисляться заново при выполнении модели.
Возвращаемый результат вычисления будет присваиваться текущему значению этого свойства. Мы хотим, чтобы во время моделирования менялся цвет нашей фигуры, поэтому щёлкните в поле Цвет заливки: по стрелке, выберите Динамическое значение и введите там следующую строку:
delay.size()>0?red:green
(рис 1.27) Установлено динамическое значение цвета заливки
Здесь delay - это имя нашего объекта delay. Функция size() возвращает число запросов, обслуживаемых в данный момент времени. Если сервер занят, то цвет кружка будет красным, в противном случае - зелёным.
Разметка пространства, чтобы перейти в режим рисования. Теперь вы можете рисовать путь точка за точкой, последовательно щелкая мышью в тех точках диаграммы, куда вы хотите поместить вершины пути. Чтобы завершить рисование, добавьте последнюю точку пути двойным щелчком мыши.
Очень важно, какую точку пути вы создаете первой. Заявки будут располагаться вдоль нарисованного вами пути в направлении от конечной точки к начальной точке. Поэтому обязательно начните рисование пути слева и поместите рядом с сервером конечную точку пути, которая будет соответствовать в этом случае началу очереди.
(рис 1.28) Путь на диаграмме процесса
Место заявок: выберите из выпадающего списка path (Рис. 1.29).
Место заявок: из выпадающего списка имя нашего прямоугольного узла: node (Рис. 1.30).
(рис 1.29) Задание пути в качестве фигуры анимации очереди
(рис 1.30) Задание прямоугольного узла в качестве фигуры анимации сервера
(рис 1.31) Анимация модели
AnyLogic предоставляет пользователю удобные средства для сбора статистики по работе блоков диаграммы процесса. Объекты Enterprise Library самостоятельно производят сбор основной статистики. Все, что вам нужно сделать - это включить сбор статистики для объекта.
Поскольку мы уже сделали это для объектов delay и queue, то теперь мы можем, например, просмотреть интересующую нас статистику (скажем, статистику занятости сервера и длины очереди) с помощью диаграмм.
Добавьте диаграмму для отображения среднего коэффициента использования сервера:
Статистика. Эта палитра содержит элементы сбора данных и статистики, а также диаграммы для визуализации данных и результатов моделирования.
Столбиковая диаграмма из палитры Статистика на диаграмму класса и измените ее размер, как показано на Рис. 1.32.
(рис 1.32) Элемент Столбиковая диаграмма на диаграмме класса
Свойства. Щёлкните кнопку Добавить элемент данных. После щелчка появится секция свойств того элемента данных (chart - Столбиковая диаграмма), который будет отображаться на этой диаграмме (Рис. 1.33).
(рис 1.33) Страница Свойства
Заголовок на SERVER utilization.
delay.statsUtilization.mean() в поле Значение. Здесь delay - это имя нашего объекта delay. У каждого объекта delay есть встроенный набор данных statsUtilization, занимающийся сбором статистики использования этого объекта. Функция mean() возвращает среднее из всех измеренных этим набором данных значений. Вы можете использовать и другие методы сбора статистики, такие, как min() или max(). Полный список методов можно найти на странице документации этого класса набора данных: StatisticsContinuous (на английском языке).
Внешний вид (Рис. 1.34). Установите свойства: направление столбцов, цвета фона, границ, меток, сетки, положение подписей у столбцов.
(рис 1.34) Вкладка Внешний вид
Местоположение и размер, Легенда, Область диаграммы (Рис. 1.35). Установите свойства, чтобы изменить расположение легенды относительно диаграммы (мы хотим, чтобы она отображалась внизу), размер диаграммы, высоту, ширину, координаты размещения на диаграмме, цвета текста, границы.
(рис 1.35) Вкладки Местоположение и размер, Легенда, Область диаграммы
Свойства щёлкните Добавить элемент данных. После щелчка появится страница Данные свойств элемента данных (chart1 - Столбиковая диаграмма), который также будет отображаться на этой диаграмме (Рис. 1.36).
Заголовок: и Значение: измените так, как показано на Рис. 1.36. В поле Заголовок: введите Queue lenqth, а в поле Значение: введите queue.statsSize.mean().
Внешний вид, Местоположение и размер, Легенда, Область диаграммы установите свойства самостоятельно. Столбцы диаграммы должны размещаться горизонтально.
(рис 1.36) Страницы Данные, Внешний вид панели Свойства
Значение: queue - это имя нашего объекта queue. У каждого объекта queue, как и объекта delay, также есть встроенный набор данных statsSize, занимающийся сбором статистики использования этого объекта. Функция mean() также возвращает среднее из всех измеренных этим набором данных значений.
(рис 1.37) Добавлены две столбиковые диаграммы
Внешний вид панели Свойства выберите в секции свойств Направление столбцов вторую опцию (Рис. 1.36), чтобы столбцы во второй столбиковой диаграмме, расположенной горизонтально, росли вправо (Рис. 1.37).
На Рис. 1.38 (снимок сделан по окончании времени моделирования) видно, что длина очереди равна 14 запросам при установленной максимальной длине 15. Но ведь в постановке задачи ёмкость буфера была определена в 5 запросов. Нам не удалось до этого построить модель с такой ёмкостью из-за ошибки (см. Рис. 1.32) - невозможности очередного запроса покинуть блок source, так как длина очереди уже была равна 5 запросам. Нам пришлось во избежание этой ошибки увеличить ёмкость буфера до 15 запросов.
А возможно ли выполнить данное условие постановки задачи средствами AnyLogic? Оказывается, что можно. Причем, различными способами. Уточним модель согласно постановке задачи одним из этих способов.
(рис 1.38) Наблюдение за моделью с двумя столбиковыми диаграммами
Объект queue моделирует очередь заявок, ожидающих приёма объектами, следующими за ним в потоковой диаграмме, или же моделирует хранилище заявок общего назначения. При необходимости вы можете задать максимальное время ожидания заявки в очереди. Вы также можете с помощью написанной вами программы извлекать заявки из любых позиций в очереди.
Заявка может покинуть объект queue различными способами:
out, когда объект, следующий в блок-схеме за этим объектом, готов принять заявку;
outTimeout, если заявка проведет в очереди заданное количество времени (если включен режим таймаута);
outPreempted, будучи вытесненной другой поступившей заявкой при заполненной очереди (если включен режим вытеснения);
remove() или removeFirst().В первом случае объект queue покидает заявка, находящаяся в самом начале очереди (в нулевой позиции). Если заявка направлена в порт outTimeout или outPreempted, то она должна покинуть объект мгновенно. Если включена опция вытеснения, то объект queue всегда готов принять новую заявку, в противном случае при заполненной очереди заявка принята не будет.
Поступающие заявки помещаются в очередь в определенном порядке: либо согласно правилу FIFO (в порядке поступления в очередь), либо согласно приоритетам заявок. Приоритет может быть либо явно храниться в заявке, либо вычисляться согласно свойствам заявки и каким-то внешним условиям. Очередь с приоритетами всегда примет новую входящую заявку, вычислит её приоритет, и поместит в очередь в позицию, соответствующую её приоритету. Если очередь будет заполнена, то приход новой заявки вынудит последнюю хранящуюся в очереди заявку покинуть объект через порт outPreempted. Но если приоритет новой заявки не будет превышать приоритет последней заявки, то тогда вместо неё будет вытеснена именно эта новая заявка.
Для выполнения условия постановки задачи воспользуемся последним способом вытеснения. Все запросы, вырабатываемые объектом source, имеют один и тот же приоритет. Поэтому при полном заполнении накопителя (5 запросов) теряться будет последний запрос. Уточните модель.
Свойства измените Вместимость с 15 на 5 запросов.
Разрешить вытеснение.
Палитре Библиотеку моделирования процессов и перетащите блок sink на диаграмму (Рис. 1.39). При перетаскивании объект пытается автоматически соединиться с входами имеющимися на диаграмме объектами. Но это может вас не устраивать.
outPreempted объекта queue с входным портом InPort блока sink1. Чтобы соединить порты, сделайте двойной щелчок мышью по одному порту, например, outPreempted, затем последовательно Щёлкните в тех местах диаграммы, где вы хотите поместить точки изгиба соединителя.
(рис 1.39) Уточненная модель
Однако согласно постановке задачи требуется определить математическое ожидание времени обработки одного запроса и математическое ожидание вероятности обработки запросов.
Entity (заявка) являются базовым классом для всех заявок, которые создаются и работают с ресурсами в процессе, описанном вами с помощью диаграммы из объектов Библиотеки моделирования процессов. Entity по существу является обычным Java классом с теми функциональными возможностями, которые необходимы и достаточны для обработки и отображения анимации заявки объектами Библиотеки моделирования процессов. Эти функциональные возможности можно расширить добавлением дополнительных полей и методов и работой с ними из объектов диаграммы, описывающей моделируемый процесс.
Согласно постановке задачи нужно определять математическое ожидание времени и вероятности обработки запросов сервером.
(рис 1.40) Работа модели согласно ёмкости входного буфера
Математическое ожидание или среднее время обработки одного запроса определяется как отношение суммарного времени обработки n запросов к их количеству, т. е. к n. Для определения суммарного времени нужно знать время обработки i-го запроса. Для этого введем дополнительные поля:
time_vxod - время входа запроса в буфер сервера,
time_vixod - время выхода запроса с сервера (входа в блок sink).Тогда
time_obrabotki=time_vixod-time_vxod
Вероятность обработки запросов сервером определяется как отношение количества обработанных запросов к количеству всех поступивших запросов. Значит, нужно вести счет запросов на выходе источника запросов и на выходе с сервера (входе в блок sink). Для этого также введем дополнительные поля:
col_vxod - количество поступивших всего запросов,
col_vixod - количество обработанных сервером запросов.Тогда
ver_obrabotki=col_vixod/col_vxod
Для включения в запросы дополнительных полей необходимо создать нестандартный тип заявки. Это возможно двумя способами. Создадим первым способом тип заявок Inquiry.
Проект щёлкните правой кнопкой мыши элемент модели верхнего уровня дерева и выберите из контекстного меню Создать/Java класс.
Новый Java класс (Рис. 1.41). В поле Имя: введите имя нового класса Inquiry.
Базовый класс: выберите из выпадающего списка Entity в качестве базового класса. Щёлкните кнопку Далее.
(рис 1.41) Диалоговое окно создания нового Java класса
Мастера создания Java класса. (Рис. 1.42).
(рис 1.42) Вторая страница Мастера создания Новый Java класс
time_vxod типа double, time_vixod типа double, col_vxod типа int, col_vixod типа int. Типы полей выбираются из выпадающего списка. Начальные значения всех параметров, поскольку не указаны, по умолчанию будут установлены равными нулю.
Создать конструктор и Создать метод toString (). Тогда у класса будут созданы сразу два конструктора: один, по умолчанию, без параметров, и второй, с параметрами, инициализирующими поля класса. Эти конструкторы используются объектами, создающими новые заявки, такие, как Source.
Готово. Вы увидите редактор кода, в котором будет показан автоматически созданный код вашего Java класса (Рис. 1.43). Закройте редактор, щелкнув крестик в закладке рядом с его названием.
Проект только что созданный Java класс и в контекстном меню выберите Преобразовать Java класс в тип агента.
Inquiry (см. Рис. 1.48).
(рис 1.43) Окно редактора кода созданного нестандартного класса
Создайте тип заявок Inquiry.
Библиотека моделирования процесов.
Тип заявки в графический редактор. Появится тип заявки Entity (Рис. 1.44).
Создание агента. Шаг 1. Анимация агента (Рис. 1.45).
В поле Имя нового агента: введите Inquiry.
Выберите анимацию агента: установите 2D и выберите из выпадающего списка, например, Сообщение.
Щёлкните Далее.
Создание агента. Шаг 2. Параметры агента (Рис. 1.46).
<добавить…>. В поле Параметр: введите time_vxod (Рис. 1.47).
Тип: выберите double.
<добавить…>. В поле Параметр: введите time_vixod.
Тип: выберите double.
<добавить…>. В поле Параметр: введите col_vxod.
Тип: оставьте int.
(рис 1.44) Появился тип заявки Entity
(рис 1.45) Диалоговое окно Создание агента. Шаг 1. Анимация агента
<добавить…>. В поле Параметр: введите col_vixod.
Тип: оставьте int.
(рис 1.46) Диалоговое окно Создание агента. Шаг 2. Параметры агента
(рис 1.47) Диалоговое окно Создание агента. Шаг 2. Параметры агента с установленными параметрами нестандартного типа заявок Inquiry
Значение по умолчанию мы не устанавливали никаких значений, то всем параметрам будет установлен 0.
(рис 1.48) Окно с параметрами нестандартного типа заявки Inquiry
Готово. Вы увидите окно, в котором будут показаны автоматически созданные параметры нестандартного типа заявок Inquiry (Рис. 1.48). Закройте оно, щелкнув крестик в закладке рядом с его названием.Для сбора статистических данных о времени обработки запросов сервером необходимо добавить элемент статистики. Этот элемент будет запоминать значения времен для каждого запроса. На основе этого он предоставит пользователю стандартную статистическую информацию (среднее, минимальное, максимальное из измеренных значений, среднеквадратичное отклонение и т.д.).
Данные гистограммы с палитры Статистика на диаграмму активного класса.
Имя: на time_obrabotki;
Кол-во интервалов: равным 50;
Нач. размер интервала: 0.01.
(рис 1.49) Элемент сбора статистики о времени обработки запросов
Добавьте еще элемент сбора статистики для определения вероятности обработки запросов.
Данные гистограммы с палитры Статистика на диаграмму активного класса.
Имя: на ver_obrabotki;
Кол-во интервалов: равным 50;
Нач. размер интервала: 0.01.Диаграмма после добавления элементов сбора статистики представлена на Рис. 1.51.
(рис 1.50) Элемент сбора статистики о вероятности обработки запросов
Чтобы создавать заявки нестандартного типа, как в нашем случае Inquiry, вам нужно поместить вызов конструктора этого типа в поле Новая заявка объекта source. Но, несмотря на то, что заявки в потоке теперь и будут типа Inquiry, остальные объекты диаграммы будут продолжать их считать заявками типа Entity.
Поэтому они не позволят явно обращаться к дополнительным полям класса Inquiry. Чтобы разрешить доступ к полям вашего нестандартного типа заявки в коде динамических параметров объектов потоковой диаграммы, вам нужно указать имя нестандартного типа заявки в качестве Типа заявки этого объекта. В нашей потоковой диаграмме с учётом блока source всего пять объектов.
(рис 1.51) Диаграмма после добавления элементов сбора статистики
(рис 1.52) Объект source с изменёнными свойствами
Измените их свойства.
source (Рис. 1.52):Тип заявки:. Это позволит напрямую обращаться к полям типа заявки Inquiry в коде динамических параметров этого объекта;
Inquiry() в поле Новая заявка:. Теперь этот объект будет создавать заявки нашего типа Inquiry;
entity.time_vxod=time(); в поле Действия При выходе:. Код будет сохранять время создания заявки-запроса в параметре time_vxod нашего типа заявки Inquiry.Функция time() возвращает текущее значение модельного времени.
queue:Inquiry в поле Тип заявки:.delay:Inquiry в поле Тип заявки:.sink1:Inquiry в поле Тип заявки:.sink:Inquiry в поле Тип заявки:;
Действие при входе следующие коды:
time_obrabotki.add(time()-entity.time_vxod);
Этот код добавляет время обработки одного запроса в объект сбора данных гистограммы time_obrabotki. Данное время определяется как разность между текущим модельным временем time() и временем входа запроса в модель. add - встроенная функция добавления элемента в массив.
entity.col_vixod=sink.count(); entity.col_vxod=source.count();
Эти коды заносят количество запросов, вошедших в блок sink и вышедших из блока source соответственно. count() - встроенная функция этих блоков, возвращает количество вошедших в блок sink и количество вышедших из блока source заявок.
ver_obrabotki.add(entity.col_vixod/entity.col_vxod);
Этот код добавляет относительную долю обработанных запросов в объект сбора данных гистограммы ver_obrabotki при поступлении каждого обработанного запроса в блок sink. На основе множества таких относительных долей определяется математическое ожидание вероятности обработки запросов сервером.
(рис 1.53) Второе сообщение об ошибке
Продолжить. Появится второе сообщение (Рис. 1.53).
(рис 1.54) Информация об ошибке в панели Консоль
Консоль Main.java.399 (Рис. 1.54). Появится код с выделенными ошибками.Мы установили тип int для col_vxod и col_vixod (см. Рис. 1.42). Изменим этот тип на double.
Обратите внимание, что вам не пришлось использовать поле time_vixod, так как вместо него была использована функция time(), возвращающая, как вам уже известно, текущее значение модельного времени.
Удалите поле time_vixod.
Проект дважды Щёлкните кнопку Inquiry. Откроется окно Inquiry (см. Рис. 1.48).
time_vixod, выделив его и нажав Delete.
col_vxod. Из выпадающего списка Тип: вместо int выберите double (Рис. 1.55).
col_vixod. Из выпадающего списка Тип: вместо int выберите double.
(рис 1.55) Окно после удаления поля time_vixod
Основная элемент Параметр. Дайте ему любое имя и установите Тип: из выпадающего списка. В дальнейшем это поле нестандартного типа заявки вы можете использовать в кодах модели.Итак, все условия постановки задачи выполнены. Чтобы наблюдать за работой модели, установите, что время остановки модели не задано. Запустите модель. (Рис. 1.56).
(рис 1.56) Фрагмент работы модели
Активный объект может иметь параметры. Параметры обычно используются для задания статических характеристик объекта. Но значения параметров при необходимости можно изменять во время работы модели. Для этого нужно написать код обработчика события, то есть действий, которые должны выполняться при изменении значения параметра.
Создайте параметр time_mean объекта delay.
Палитре выделите Основная.
Параметр на диаграмму класса Main и разместите ниже объекта delay, чтобы было видно, к какому объекту относится параметр.
Свойства (Рис. 1.57).
Имя введите имя параметра time_mean (среднее время). По этому имени параметр будет доступен из кода.
double.
(рис 1.57) Окно установки свойств элемента Параметр
Значение по умолчанию установите 180. Если значение не задано явно, по правилам Java оно будет равно нулю.
delay.
Свойства в поле Время задержки вместо выражения exponential(1/180.0) введите выражение exponential(1/time_mean).Пусть вы хотите изменять среднее время обработки запросов time_mean в ходе моделирования. Используйте для этого элемент управления - бегунок.
Элементы управления и перетащите элемент Бегунок из палитры на диаграмму класса Main (Рис. 1.58).
time_mean, чтобы было понятно, что с помощью этого бегунка будет меняться среднее время обработки запросов объектом delay.
Минимальное значение:, а 300 - в поле Максимальное значение: (Рис. 1.59).
Связать с: и в активизированное поле введите time_mean.Пусть теперь вы хотите также изменять ёмкость буфера в ходе моделирования. Используйте для этого также бегунок.
Элементы управления и перетащите элемент Бегунок из палитры на диаграмму класса Main (Рис. 1.59).
(рис 1.58) Установка элемента управления Бегунок
(рис 1.59) Окно установки свойств элемента управления Бегунок
Максимальное значение.
Связать с: и в активизированное поле введите queue.capacity.
Приостановить приостановить работу модели, изменить значения параметров, а затем продолжить моделирование (Рис. 1.60).
Main.Мы научились добавлять элементы Параметр и Бегунок. Но согласитесь, что какие параметры модели нужно будет менять, и в каких интервалах, заранее определить затруднительно. Также при использовании элемента Бегунок существуют трудности точного установления значения характеристики, так как невозможно предусмотреть нужный масштаб или цену деления Бегунка.
(рис 1.60) Фрагмент работы модели с добавленным элементом Параметр и элементами управления
Существует и другой способ изменения свойств объектов во время выполнения модели: нужно щёлкнуть по элементу, войти в режим редактирования и ввести новое значение в одной из закладок всплывающего окна инспекта. Поэтому заранее не нужно продумывать, значения каких параметров планируется изменять, и не добавлять специальные элементы управления (например, бегунки).
Изменение значения в окне инспекта поддерживается для следующих элементов: простая переменная; параметр; накопитель.
И для следующих типов: численные; логический (boolean); текстовый (String).
Бегунок для Параметра time_mean.
Параметра time_mean.
Параметр вы увидите введённое вами значение 240.0.
(рис 1.61) Ввод нового значения параметра в окно инспекта
Теперь добавим на диаграмму нашего потока гистограмму, которая будет отображать собранную временную статистику.
Гистограмма из палитры Статистика в то место графического редактора, куда хотите ее поместить.
Данные имя соответствующего элемента: time_obrabotki (Рис. 1.62). Установите Отображать среднее.
Заголовок: введите Histogram Time obrabotki.Добавим на диаграмму нашего потока гистограмму, которая будет отображать собранную вероятностную статистику.
Гистограмма из палитры Статистика.
Добавить данные и введите в поле Данные имя элемента: ver_obrabotki. Установите Отображать среднее.
Заголовок: введите Histogram Ver obrabotki.
time_mean=180, хотя ранее мы изменили его значение на 240.
(рис 1.62) Окно установки свойств элемента Гистограмма
(рис 1.63) Фрагмент работы модели с элементом управления и гистограммами
Построенная модель соответствует постановке задачи (п. 1.2.1). В ней, с целью упрощения процесса построения первой модели, время обработки запросов сервером было принято распределённым по показательному (экспоненциальному) закону со средним значением T2 = 3 мин.
Однако в модели время обработки поступающих запросов зависит от производительности сервера $$Q=6\cdot 10^5$$ оп/с и вычислительной сложности запросов, распределенной по нормальному закону с математическим ожиданием $$S1=6\cdot 10^7$$ оп и среднеквадратическим отклонением $$S2=2\cdot 10^5$$ оп.
Кроме того, в модели определяется среднее количество запросов, обработанных за время моделирования 3600 с.
Внесите в модель изменения для аналогичного расчёта времени обработки запросов.
Параметр с именем time_mean элемент Бегунок для элемента queue.
Основная перетащите три элемента Параметр на диаграмму класса Main (Рис. 1.64).
Имя каждого из элементов введите S1_, S2_ и Q_ соответственно. Выберите Тип double.
Значение по умолчанию каждого из элементов введите 60000000,200000 и 600000 соответственно.
Переменная.
Имя укажите KolZap.
delay.
Время задержки вместо exponential(1/time_mean) введите:(normal(S2_,S1_))/Q_
sink. В поле Действие при входе к имеющемуся там коду добавьте код:
KolZap=sink.in.count()/9604.0;
Для получения результатов моделирования с доверительной вероятностью $$\alpha =0,95$$ и точностью $$\varepsilon =0,01$$ нужно выполнить 9604 прогонов модели:
$$N=t^2_\alpha \cdot \frac{p\cdot (1-p)}{\varepsilon ^2}=1,96^2\cdot \frac{0,5^2}{0,01^2}\approx 9604$$где $$t_\alpha = 1,96$$ - табулированный аргумент функции Лапласа, p - ожидаемая вероятность исхода события, в данном случае вероятность обаботки запросов сервером.
Расчёт проведен для так называемого "худшего" случая, то есть в предположении, что ожидаемая вероятность обработки запросов p = 0,5.
Увеличим время моделирования в AnyLogic-модели в 9604 раз. А так как статистические данные о количестве обработанных запросов собираются за всё время моделирования, увеличенное в 9604 раз, то для получения среднего значения это количество нужно разделить на 9604, что и предусмотрено в коде.
(рис 1.64) Элементы AnyLogic-модели, соответствующие постановке
Проект выделите Simulation. На странице Модельное время в поле Установить выберите В заданное время.
Конечное время установите 34574400.
Результаты моделирования приведены на Рис. 1.65.
(рис 1.65) Результаты моделирования обработки запросов сервером
Для проведения исследований на модели сделайте ещё несколько дополнений и изменений. Можно было бы обойтись и без них, но они улучшат эксплуатацию модели.
Основная перетащите три элемента Параметр на диаграмму агента Main. Разместите их выше параметров S1_, S2_, Q_. Можно перетащить один параметр, скопировать его и вставить остальные два. Если установить свойства первого элемента Параметр, то они будут и в скопированных элементах. Не будем их устанавливать. Установим после копирования и вставки.
Параметр. В поле Имя: первого параметра введите timeMean - среднее время поступления запросов для обработки на сервере. Оставьте тип double.
Значение по умолчанию введите 120.
source. В поле Время между прибытиями вместо 120.0 введите timeMean. Теперь вам при изменении среднего времени поступления запросов не придётся искать нужный код в свойствах объекта модели.
Параметр. В поле Имя: введите kolProg - количество прогонов модели. Как и в предыдущем случае, при корректировке числа прогонов код в свойствах искать будет не нужно. Оставьте тип double.
Значение по умолчанию введите 9604.
sink.
Действие при входе в имеющемся там коде замените последнюю строку следующей:
KolZap=round(sink.in.count()/kolProg);
На Рис. 1.10. количество обработанных запросов KolZap сервером выдаётся с дробной частью. Теперь, вследствие применения процедуры round, количество запросов будет целым.
Как уже отмечалось, при изменении количества прогонов модели не надо будет искать код для требуемой корректировки. Однако всё-таки потребуется изменить модельное время. Например, если нужно выполнять с моделью 1000 прогонов, то модельное время следует установить равным 3600*1000=3600000.
Параметр. В поле Имя: введите emkBuf - ёмкость в сообщениях входного буфера сервера. Установите тип int.
Значение по умолчанию введите 5.
queue. В поле Вместимость введите emkBuf.
Проведём несколько экспериментов. Будем изменять среднее время поступления запросов timeMean в предположении, что с течением времени количество источников запросов будет расти, то есть timeMean будет уменьшаться. В сторону увеличения будем изменять ёмкость входного буфера emkBuf и производительность Q_ сервера.
(рис 1.66) Результаты моделирования при условиях постановки задачи
Результаты экспериментов приведены в Табл. 1.2.
Из экспериментов 1 и 2 следует, что при увеличении ёмкости входного буфера в два раза вероятность обработки запросов увеличивается незначительно на 0,025, то есть количество обработанных запросов практически одно и тоже. Среднее время обработки одного запроса возрастает в 1,27 раза вследствие увеличения длины очереди в 1,48 раза.
Увеличение интенсивности поступления запросов в три раза при увеличении ёмкости входного буфера в два раза (эксперименты 3 и 4) также не даёт существенного увеличения количества обработанных запросов: 36 вместо 30.
| Показатели | GPSS World | AnyLogic6 | AnyLogic7 |
|---|---|---|---|
| 1) timeMean = 120, emkBuf = 5 | |||
| Количество обработанных запросов | 29 | 29 | 29 |
| Вероятность обработки запросов | 0,97 | 0,971 | 0,97 |
| Среднее время обработки одного запроса | 255,262 | 254,942 | 255,727 |
| Средняя длина очереди запросов к серверу | 1,258 | 1,254 | 1,261 |
| Коэффициент использования сервера | 0,81 | 0,81 | 0,81 |
| 2) timeMean = 120, emkBuf = 10 | |||
| Количество обработанных запросов | 29 | 30 | 30 |
| Вероятность обработки запросов | 0,995 | 0,995 | 0,995 |
| Среднее время обработки одного запроса | 328,328 | 321,54 | 325,017 |
| Средняя длина очереди запросов к серверу | 1,902 | 1,841 | 1,87 |
| Коэффициент использования сервера | 0,833 | 0,831 | 0,831 |
| 3) timeMean = 40, emkBuf = 5 | |||
| Количество обработанных запросов | 36 | 36 | 36 |
| Вероятность обработки запросов | 0,4 | 0,399 | 0,4 |
| Среднее время обработки одного запроса | 1055,335 | 1055,108 | 554,983 |
| Средняя длина очереди запросов к серверу | 4,554 | 4,552 | 4,55 |
| Коэффициент использования сервера | 1 | 1 | 1 |
| 4) timeMean = 40, emkBuf = 10 | |||
| Количество обработанных запросов | 36 | 36 | 36 |
| Вероятность обработки запросов | 0,399 | 0,399 | 0,4 |
| Среднее время обработки одного запроса | 591,86 | 591,304 | 1054,907 |
| Средняя длина очереди запросов к серверу | 9,554 | 9,551 | 9,549 |
| Коэффициент использования сервера | 1 | 1 | 1 |
| 5) timeMean = 40, emkBuf = 10, Q_ = 1000000 | |||
| Количество обработанных запросов | 59 | 60 | 60 |
| Вероятность обработки запросов | 0,666 | 0,665 | 0,667 |
| Среднее время обработки одного запроса | 591,86 | 591,304 | 591,129 |
| Средняя длина очереди запросов к серверу | 8,855 | 8,852 | |
| Коэффициент использования сервера | 1 | 1 | 1 |
| 6) timeMean = 40, emkBuf = 15, Q_ = 2000000 | |||
| Количество обработанных запросов | 90 | 90 | 90 |
| Вероятность обработки запросов | 1 | 1 | 1 |
| Среднее время обработки одного запроса | 74,859 | 75,049 | 75,096 |
| Средняя длина очереди запросов к серверу | 8,864 | 1,096 | 1,128 |
| Коэффициент использования сервера | 0,751 | 0,75 | 0,751 |
При этом уменьшается вероятность обработки запросов в 2,5 раза, а время обработки одного запроса возрастает в 3,25 раза. Возросла и средняя длина очереди запросов к серверу
Коэффициент использования сервера равен 1. Из этого следует, что добиться увеличения вероятности и количества обработанных запросов можно только увеличением производительности сервера.
В экспериментах 5 и 6 увеличена производительность сервера до 1000000 и 2000000 оп/c соответственно.
По сравнению с экспериментом 1 количество обработанных запросов в эксперименте 5 увеличилось в 2 раза, а в эксперименте 6 - в 3 раза (вероятность обработки запросов равна 1). Среднее время обработки одного запроса всё равно примерно в 2 раза больше в эксперименте 5, а в эксперименте 6 - в 3,4 раза меньше. Можно полагать, что такая разница в среднем времени обработки одного запроса вызвана тем, что в эксперименте 5 средняя длина очереди запросов к серверу 8,852, а в эксперименте 6 - 1,128, то есть в 7,85 раза меньше.
Коэффициент использования сервера в эксперименте 6 равен 0,751. Из этого следует, что дальнейщее увеличение производительности сервера приведёт к уменьшению длины очереди и среднего времени обработки одного запроса.
Машинное время выполнения модели в AnyLogic примерно 70…90 с.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.