168 детализации. Глубина детализации определяется как необходимой точностью, так и набором исходных данных. В процессе структурного анализа выявляется иерархическая структура модели.
С помощью конструктора Gem системы Pilgrim можно строить
многоуровневые модели, организуя иерархию плоскостей построения модели. Иерархические модели устроены следующим образом: верхний уровень модели содержит ряд узлов, среди которых есть такие, которые детализируются на нижних уровнях.
При этом, создавая детализирующий уровень, пользователь вновь может поместить на нее узлы, которые могут быть детализированы на нижележащих уровнях.
Таким образом, граф модели примет иерархическую структуру. Число уровней вложенности конструктором не ограничено, т.е. пользователь может сколько угодно подробно детализировать и обобщать процессы модели.
Итак, процесс построения графа имитационной модели сопровождается структурным анализом исследуемого процесса. При структурном анализе возникает задача перехода между слоями: нижние слои модели содержат декомпозицию узлов, расположенных выше.
Декомпозиция - это детализация одного узла с помощью совокупности других узлов.
Существуют четыре разновидности декомпозиции процессов:
1) общий случай декомпозиции сложного процесса с помощью узлов типа down;
2) декомпозиция процессов перечисления денег (платежей, бухгалтерских проводок и др.) с помощью узлов типа pay;
3) декомпозиция процессов выделения ресурсов с помощью узлов типа rent;
4) абстрактное объединение группы процессов в один псевдопроцесс с помощью виртуального (мнимого, не существующего в реальности) узла parent без образования нового узла.
Обратим внимание на то, что представленный методологический прием аналогичен методологическому приему, применяемому для построения функциональных моделей в процессе проведения системного анализа. Вместе с тем, важно понимать, что цель создания функциональных моделей отлична от целей создания имитационных моделей. Функциональная модель показывает, каким образом выходные элементы системы получаются из входных без рассмотрения логики преобразований. Модель создается, в первую очередь, для выявления основных подсистем (функций) рассматриваемого объекта и состоит из набора диаграмм потока данных.
В противоположность функциональной модели имитационная модель отображает все существенные действия в процессе их выполнения и создается для изучения поведения исследуемого объекта и параметров его функционирования.
169
Вопрос 2. Использование узла parent.
При создании новой модели пользователь начинает работу с корневого уровня, поэтому некоторые процессы модели с целью дальнейшей детализации могут быть представлены в общем виде. Для выполнения структурной декомпозиции в системе Pilgrim определяется особый тип узла parent, использующийся исключительно как средство создания наглядных многоуровневых моделей. Узел типа parent содержит ссылку на плоскость, его детализирующую, т.е. используется для описания процессов, которые можно рассмотреть на отдельной плоскости. Узел parent не выполняет никаких действий по обработке транзакта и при генерации программного кода просто заменяется своей декомпозицией, т.е. порождаемым им слоем.
Например, если пользователь создал узел типа parent с номером 4, то в программном файле узел с таким номером сгенерирован не будет. С точки зрения генератора программного файла узел parent представляет собой маршрутизатор, который может иметь любое количество входов, ссылку на детализирующий уровень и единственный выход. На рис. 38 в плоскости 1 имеется последовательность узлов Клапан 101
Действие
102
Очередь 103.
Рис. 38. Использование узла parent
Узел Действие 102 является узлом типа parent и содержит детализирующую плоскость с цепочкой Очередь 104
Сервер 105 (рис.
39):
Рис. 39. Узлы на детализирующей плоскости
170
В этой плоскости стрелка, направленная из левого верхнего угла экрана в узел Очередь 104, обозначает, что этот узел является входом на плоскость, а стрелка из узла Сервер 105 в правый верхний угол - выходом с плоскости. При генерации программного файла получим следующую цепочку:
Клапан 101
Очередь 104
Сервер 105
Очередь 103,
т. е. узел Действие 102 является лишь средством реализации
(виртуальным узлом) и будет обработан генератором как узел Pilgrim.
Вопрос 3. Использование узлов pay, rent, down.
Иногда при построении модели может возникнуть необходимость выделения некоторых типовых действий по обработке данных. Это могут быть запросы на выполнение бухгалтерской проводки, требования выделения моделируемого ресурса или какие-либо другие действия. При возникновении такой задачи удобно обозначить подпрограммы, обращение к которым было бы возможно из любого места модели. Для этого используются узлы типа pay, rent, down. Такие узлы, так же как и
parent, содержат переход на более низкий уровень модели, однако имеют несколько иной механизм действия и область применения. Если с помощью узла типа parent можно создавать иерархические модели, имеющие на любой сколько угодно глубоко вложенной плоскости новые узлы parent, то с помощью узлов типа pay, rent, down возможно лишь реализовать подпрограммы на двух слоях модели и невозможно построить общую иерархию уровней.
Рассмотрим принцип работы таких узлов на примере узла pay. На плоскости 1 находится узел типа pay, содержащий обращение к подпрограмме, расположенной в плоскости 2 (рис. 40):
Рис. 40. Узел pay (плоскость 1, слева) и подпрограмма узла
(плоскость 2, справа)
Входом плоскости 2 является узел с названием «Р/счет», а выходом - узел с именем «Бухгалтерия». При генерации программного
171 файла в узле «Бухгалтерия» в качестве параметра, определяющего номер следующего узла, на который переходит транзакт, будет указано не конкретное значение, а специальный параметр транзакта updown. При этом предполагается, что каждый транзакт, попадающий в выходной узел плоскости, содержит в параметре updown номер узла, на который следует выполнить переход.
Параметр транзакта
updown инициализируется в узле типа pay, т.е. в данном случае в узле с названием «Плата поставщику».
Аналогичным образом реализуется переход на подпрограмму с использованием узлов типа rent и down. Они также инициализируют переменную транзакта updown. Таким образом, использовать узлы типа
pay, rent и down для реализации иерархических моделей нельзя: на уровне подпрограммы для узла одного из этих типов нельзя размещать никакой из узлов типа pay, rent, down, поскольку каждый из этих узлов заново выполнит инициализацию параметра updown. Т.е., значение
updown, установленное уровнем выше, заменится, организуя циклическую ссылку, что приведет к семантической ошибке.
Чтобы защитить пользователя от совершения таких ошибок, конструктор не позволяет создавать в текущей плоскости узлы типа pay,
rent, down, если управление передано с более высокого уровня через узел перечисленного типа. Однако узлы обращения к подпрограмме имеют одно важное преимущество перед узлом parent, а именно: транзакт сам «помнит», куда ему необходимо вернуться. Поэтому из нескольких узлов или слоев можно обращаться к общей плоскости, содержащей детальное выполнение типового действия.
Предположим, что в последнем примере имеется некоторая организация, имеющая собственный расчетный счет и выполняющая ряд операций по перечислению средств; часть операций необходимо смоделировать. В плоскости 2 создана подпрограмма «Плата поставщику», выполняющая бухгалтерскую проводку по перечислению средств со счета фирмы. Если возникает необходимость смоделировать аналогичную ситуацию с перечислением средств (например, возврат кредита), то можно создать новый узел типа pay и указать ему в качестве подпрограммы плоскость 2.
В процессе работы с конструктором, при создании нового узла обращения к подпрограмме, появляется диалоговое окно с просьбой указать номер плоскости, на которой должна размещаться подпрограмма.
По умолчанию это номер новой пустой плоскости, однако, пользователь самостоятельно может задать номер уже существующей плоскости.
Иногда в модели можно выделить ряд процессов, независимых на уровне транзактов, но пересекающихся на уровне моделируемых ресурсов. Например, это может быть моделирование процесса производства с участием нескольких независимых торговых компаний, приобретающих товар у производителя и имеющих свой финансовый резерв и рынок сбыта. Тогда можно выделить как независимые
172 процессы торговых компаний и процесс функционирования производителя. Для разработчика модели неудобно располагать в одной корневой плоскости несколько параллельных процессов, поэтому конструктор предоставляет возможность содержать несколько корневых плоскостей с целью размещения в них непересекающихся на уровне транзактов процессов.
Вопрос 4. Многослойная модель бизнес-процесса.
Проиллюстрируем применение описанного механизма на примере модели функционирования производственного предприятия. Пример является также хорошей иллюстрацией другого уже отмеченного ранее достоинства системы Pilgrim – возможности имитации протекания материальных, финансовых и информационных потоков в рамках одной и той же модели.
Моделируемый объект (небольшое предприятие) занимается выпуском товара малыми партиями, размер которых известен.
Произведенная продукция реализуется на рынке, количество единиц реализуемой на рынке продукции в одной партии является случайной величиной, распределенной по равномерному закону.
Структурная схема бизнес-процесса содержит три слоя. На двух из них представлены независимо протекающие процессы производства
(рис. 41).
173
Рис. 41. Модельный граф процесса производства
и сбыта (рис. 42)
Рис. 42. Модельный граф процесса сбыта
продукции предприятия. Независимость протекания процессов означает, что транзакты могут перемещаться только внутри каждого из фрагментов графа модели на каждом слое. Взаимодействие процессов осуществляется только через ресурсы: материальные (в виде готовой продукции) и денежные (в основном через расчетный счет предприятия).
На третьем слое имитируется выполнение финансовых операций, связанных с работой предприятия (рис. 43):
174
Рис. 43. Слой финансовых операций
Если время задержки платежей с расчетного счета моделируемого предприятия (обозначив эту величину через Трс) считать критическим выходным параметром, то модель можно использовать для минимизации этой величины. Основными входными параметрами моделирования будут служить цена единицы продукции, объем выпускаемой партии и сумма кредита, запрашиваемого в банке.
Зафиксировав все остальные параметры (время выпуска партии, число производственных линий, интервал поступления заказа от покупателей, разброс размеров продаваемой партии, стоимость комплектующих изделий и материалов для выпуска партии, стартовый капитал на расчетном счете), можно минимизировать Трс для конкретной рыночной ситуации. Минимум Трс достигается при одном из максимумов среднего размера денежной суммы на расчетном счете. Причем вероятность рискового события - неуплаты долгов по кредитам - близка к минимуму
(это можно доказать во время статистического эксперимента с моделью).
В модели первого слоя (процесс производства) имитируются следующие действия (рис. 41).
Узел 1 имитирует поступления распоряжений на изготовление партий продукции от руководства компании.
Узел 2 инициирует запрос на получение кредита, порождая для этого вспомогательный транзакт (запрос в банк).
В узле 3 запрос ожидает наступления условий, при которых кредит может быть выдан (новый предоставляется, если предыдущий кредит возвращен).
Узел 4 фиксирует наступление этих условий (переводом своего состояния в открытое) и имитирует разрешение на выдачу кредита.
Узел 5 осуществляет перечисление кредита на расчетный счет компании.
175
В узле 6 вспомогательный запрос уничтожается и выдается сигнал блокировки на выдачу следующего кредита (с помощью сигнальной функции hold).
Основной транзакт-распоряжение проходит через узел 2 без задержки.
В узле 7 производится оплата комплектующих, если на расчетном счете есть достаточная сумма (даже если кредит не получен). В противном случае транзакт будет ожидать поступления на расчетный счет предприятия либо кредитных денег, либо денег за проданную продукцию.
В узле 8 транзакт становится в очередь, если все производственные линии заняты.
Узел 9 (конвейерная линия) имитирует изготовление партии продукции.
В узле 10 порождается дополнительный транзакт, имитирующий заявку на возврат взятого кредита.
Эта заявка поступает в узел 11, имитирующий перечисление денег с расчетного счета предприятия в банк (если нужной суммы на счету предприятия нет, заявка ожидает).
После возврата кредита заявка уничтожается в узле 12; в банке появилась информация о том, что кредит возвращен, и компании можно выдать следующий кредит (с помощью сигнальной функции rels).
Транзакт-распоряжение проходит узел 10 без задержки и в узле 13 уничтожается. Далее считается, что партия изготовлена и поступила на склад готовой продукции.
В модели второго слоя (процесс сбыта произведенной продукции) имитируются следующие действия (рис. 42).
Узел 14 является генератором транзактов - покупателей продукции, которые обращаются на склад. Если склад располагает запрошенным количеством товара, то товар отпускается покупателю, в противном случае покупатель (транзакт) ждет.
Узел 16 имитирует отпуск товара и контроль очереди. После получения товара покупатель перечисляет деньги на расчетный счет предприятия (узел 17).
В узле 18 транзакт уничтожается (покупатель обслужен).
В модели третьего слоя (денежные операции) имитируются проводки в бухгалтерии предприятия (рис. 43).
Запросы на проводки поступают с первого слоя (рис. 41) из узлов 5,
7, 11 и из узла 17 (рис. 42). Пунктирными линиями показано движение денежных сумм по счетам 51 (Расчетный счет, узел 20), 60
(Поставщики, подрядчики, узел 22), 62 (Покупатели, заказчики, узел 21) и 90 (Банк, узел 19). Условные номера примерно соответствуют плану счетов бухгалтерского учета.
Узел 23 имитирует работу финансового директора. Обслуженные транзакты после бухгалтерских проводок попадают обратно в узлы,
176 откуда они поступили; номера этих узлов находятся в параметре транзакта t->updown.
Ниже приводится текст программной модели:
#include forward
{ float T_cust=7;
/* интервал поступления заказов */ float T_work=14;
/* время изготовления партии товаров */ float S_bank=10000.00;
/* сумма кредита в банке */ float S_supp=10000.00;
/* сумма платы поставщику */ float The_price=90.00;
/* цена единица продукции */ float Mod_time=730;
/* время моделирования */ int
N_work=2;
/* производственная мощность */ int
Max=1200;
/* размер производимой партии продукции*/ modbeg («Company», 23, Mod_time, (long)1234567890, none, 20, none, 18, none); ag («Заказы»,1,none,norm,T_work,T_work/3,zero,2); ag («Клиенты»,14,none,norm,T_cust,T_cust/3,zero,15); assign (19,add,10000000.00);
/* фонд банка */ assign (20,add,0.00);
/* фонд фирмы */ assign (21,add,10000000.00);
/* фонд покупателей */ network(dummy, dummy)
{
//ПРОИЗВОДСТВО ====================================== top( 2): creat («Развилка_1», 0, 1, none, 3, 7); place; top( 3): queue («ЖдемКредит», none, 4); place; top( 4): key («РазрешКредита», 5); place; top( 5): pay («ПереводКредита», 20, S_bank, 19, none, 19, 6); //на слой 3 place; top( 6): term («ЗапретВыдачи»); hold(4); place; top( 7): pay («ПлатаПоставщикам», 22, S_supp, 20, none, 20, 8); //на слой 3 place; top( 8): queue («ОчередьЗаказов», none, 9); place; top( 9): serv («ВыполнениеЗаказов», N_work, none, norm, T_work, T_work/3, zero, 10); place; top(10): creat («Развилка_2», 0, 1, none, 11, 13); place;