GPSS-WORLD основы имитационного моделирования на живых примерах

  • Tutorial
Доброй пятницы уважаемые читатели Хабра.
В данном посте я предлагаю вам бегло ознакомиться с возможностью создания имитационной модели процессов в программе GPSS-WORLD. Данный пост нельзя считать полноценным туториалом, но я поделюсь с Вами теми крупицами, что знаю и вполне возможно что уже через пол часа после прочтения статьи Вы проявив фантазию создадите свою собственную имитационную модель. Как говориться в народе: «Тяжело в учении легко в бою».
И пусть местами, данный «туториал» придерживается принципа: «битый не битого везет», но я всё же донесу до вас те знания, которые у меня есть, ну а вы уж сами вольны решать, стоить ли мне доверять или лучше проверять. В любом случае я буду рад аудиту кода от знатоков GPSS-WORLD. Все материалы статьи размещены на GItHub
Изучать самые азы будем сразу на живых примерах — доступных, понятных и близких сердцу многим сотрудникам проводящим свои законные 8 часов в офисах.
От конкретики перейдем к лирике, пятница традиционно располагает задаваться безумными вопросами, и в этот раз мы с моим коллегой DrZugrik задались вопросом: «Сколько нужно сотрудников тех поддержки, чтобы рассказать, как вкрутить лампочку?».
За подробностями сего мысленного эксперимента прошу под кат.

Написание этого мини туториала вместе с разработкой моделей заняло 6 часов чистого времени.
буду признателен если статья доберется до потенциально заинтересованных читателей.


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

первоначальная иллюстрация





Для начала нам понадобиться сам GPSS-World.

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

Итак необходимым инструментарием мы запаслись, теперь осталось подключить фантазию и придумать первую модель.
Меня никак нельзя назвать гуру имитационного моделирования в целом и GPSS-World в частности, подосновой для примеров приведенных тут служили материалы из этой книги . Но думаю, что составляемые модели имеют право на жизнь.
Давайте для начала рассмотрим такой случай.
Дано:
Офис в котором работает 10 сотрудников, Кулер в конце коридора до которого «шкваркать 4 минуты», сотрудники которые желают испить чаю и совершают путешествие к кулеру один раз в час. Время наполнения чаши с пакетиком живительной влагой составляет примерно 2 минуты. Рабочий день составляет 480 минут (8 часов без перерыва на обед так сказать)
Определить:
Коэффициент использования кулера сотрудниками офиса.
Создадим имитационную модель

	GENERATE	,,,10		; 1  Amount office staff
	ADVANCE	4,0.8		; 2  Time to reach the cooler	 
DRINK	QUEUE	STAND	       ; 3  Queue to the cooler. input	
	SEIZE	COOLER	       ; 4  Verification of employment cooler
	DEPART	STAND		; 5  Queue to the cooler. output
	ADVANCE	2,0.8		; 6  Filling the cup with boiling water
	RELEASE	COOLER		; 7  leave the cooler
	ADVANCE	60,10		; 8  Time for tea, time to work, time to get back to the cooler				
	TRANSFER	,DRINK		; 9  Go back to the cooler
	GENERATE	480		; 10 Working day (minutes)
	TERMINATE	1		; 11 Minus one minute
	START	1		; 12 Start from the first minute


Поскольку комментарии я оставлял на своем ломаном английском, то безусловно вижу смысл детально рассказать о функционировании модели.
Строка 1 — GENERATE ,,,10 — сам по себе блок GENERATE задает нам количество входящих требований (в данном случае сотрудников офиса), запись операторов вида ,,,10 говорит нам о том что первые три параметра пропущены, а четвертый параметр указывает на максимальное количество входящих требований. Блок GENERATE. Можно задать и с другими параметрами, но об этом я расскажу немного позже.
Как вы догадались " ;" — отделяет поле комментария. Еще немного о конструкции оформления кода, код читается слева направо, есть несколько блоков, которые желательно разделять табуляцией. Самый левый блок это метка (аналогична метке в др. языках программирования), затем идет сам блок (например generate) затем обычно идут его параметры, затем комментарии. Когда-то давно нас учили разделять эти блоки табуляцией, но это скорее вопрос эстетики. 1 пробела кажется тоже достаточно что бы все запустилось. Кстати там где написано все БОЛЬШИМИ буквами, лучше так и писать, а то может вылететь ошибка при исполнении.
Строка 2 — ADVANCE 4,0.8; Отвечает за временные характеристики процесса, чтобы было понятней в данном случае это значит, что работник идет к кулеру 4 минуты ± 0.4 минуты.
Таким образом первая цифра означает затраченные единицы времени (итерации), вторая цифра означает половину отклонения в большую или меньшую сторону, в книгах написано что значение отклонения генерируется случайным образом, может это и так, но каждый перезапуск система выдает одинаковые значения (не знаю может быть есть аналог randomize из старого доброго паскаля, но я его не нашел). Блок ADVANCE также можно задать с другими значениями, но об этом чуть позже.
Строка 3 — DRINK QUEUE STAND; — вот тут мы встречаем нашу первую метку DRINK, после которой следует блок QUEUE, который создает очередь в эту очередь у нас будут попадать все кто направляется к кулеру промочить горло,. STAND – это скажем так идентификатор очереди.
Строка 4 — SEIZE COOLER – блок SEIZE определяет свободно ли наше устройство, в данном случае идентификатор устройства COOLER (ну или попросту кулер).
Строка 5 DEPART STAND — если прошлый блок дал нам положительный результат (кулер свободен), то срабатывает следующий за ним блок DEPART, который обеспечивает выход человека из очереди STAND.
Строка 6 — ADVANCE 2,0.8 человек, который вышел из очереди будет наливать себе примерно 2 минуты кипяток в кружку (ну плюс успеет поболтать с людьми в очереди к кулеру)
Строка 7 — RELEASE COOLER, сделав свое «мокрое» дело, человек освободит устройство COOLER, для следующего страждущего.
Строка 8 — ADVANCE 60,10 – данный блок учитывает время. Которое человек испивший воды, затратит на то чтобы собраться с силами и прийти к кулеру еще раз (по крайней мере я надеюсь, что моделируется именно это).
Строка 9 — TRANSFER ,DRINK – «И повторится все, как встарь» — сказал бы А. Блок, если бы был знаком с программированием. Данный оператор обеспечивает переход на метку DRINK.
Строка 10 – GENERATE 480 казалось бы с точки зрения программирования после перехода на метку в прошлом блоке, все что лежит ниже не имеет смысла, но это не так.(а почему так, я если честно не сильно вникал, но судя по опыту и выпадающим ошибкам, этот кусок воспринимается немного вне контекста предыдущих 8 блоков). Главное, что данный блок задает нам время выполнения всей модели, а именно 480 минут (8 часов)
Строка 11 — TERMINATE 1 – Этот бок вычитает из каждой счетчика итераций единицу. Без этого блока можно уйти в бесконечный цикл.
Строка 12 — START 1 – Говорит программе с какого момента цикла начать, мы начинаем с первой минуты.

Ух, ну вот мы и закончили с описанием первой модели.
Кому интересны результаты, прошу под спойлер. Если вы любите все проверять самостоятельно то еще раз напомню все модели выложены на GItHub

результаты Модель 1 - коэффициент использования кулера


проанализируем результаты
Итак мы видим, что в среднем наш кулер загружен на 33%, то есть в нашей команде из 10 сотрудников получается примерно так как если бы к нему постоянно прикладывался Администратор Петр, Марья Васильевна из бухгалтерии и Менеджер проекта Василий Чуфыркин, ну и еще 0.33 человека, или например — кот. На самом деле этот блок текста не несет смысловой нагрузки, мне просто очень хотелось нарисовать кота и кулер и Марью Васильевну из бухгалтерии (все кроме кота личности сугубо выдуманные)



Хотя черт побери после того как я прочел это, могу смело утверждать, что кулер мог бы напоить 12 милых котиков =)



Но вернемся к теме.



Давайте рассмотрим, результаты выдачи.

Facility – это список всех наших работающих устройств, в данном случае только кулер.
Entries 79 – означает число подходов на обслуживание к устройству, в данном случае число человек с пустыми чашками составило 79 – за всю рабочую смену.
Util – коэффициент использования оборудования, Он говорит нам о том, что кулер бездествовал (1-0.33)*100%=67% всего времени.
AVE. TIME – среднее время использования кулера 1 человеком 2.002 минуты
AVAIL. – Доступность кулера, не знаю что это значит видимо еденица говрит, что он был доступен
DELAY = 0 – говрит нам о том, что чсло людей которые просто подошли к кулеру, расстроились и ушли с пустыми руками (кружкой), равно нулю.

Теперь переедем к нашей очереди (QUEUE)
Как видите тут указано имя созданной нами ранее очереди,
В которой максимально находилось 9 человек, в которую было 79 входов, и 48 нулевых входов (по всей видимости входов без ожидания в очереди), среднее время проведенное человеком в очереди равно 1.5 минуты. Cont. = 0 говорит нам о том, что на момент окончания моделирования в очереди никого не было.

Ну вот вроде бы все не плохо, но что будет если мы вернемся в сытый 2006
Год и наймем еще 30 сотрудников в наш офис?

результаты Модель 1 - коэффициент использования кулера при 40 сотрудниках




Как видно из модели, наш кулер почти перестанет простаивать, а среднее время в очереди составит аж 20 минут, что наводит на мысли либо о том, что нужен второй кулер, либо о том, что пора всех лишать премии за долгие чаепития.
Может быть данная модель, простовата, но даже она при проявлении некоторой фантазии позволяет нам оценить количество кулеров которое необходимо на этаже.
Но на текущий момент мы с вами еще не умеем, разрабатывать многоканальные модели обслуживания. Так убьем же двух зайцев, научимся многоканальному обслуживанию и заодно ответим на вопросов, которым мы с коллегой задались в самом начале статьи. (кто внимательный и помнит — молодец, тому счастья добра и безпохмельных выходных: )

При создании модели операторы call центра и абоненты, зададимся такими условиями
Дано:
2 оператора техподдержки обслуживают пользовталей, которые звонят пимерно раз в две минуты, Если один оператор занят трубку берет другой. Рабочий день составляет 480 минут (8 часов без перерыва на обед так сказать)
Определить:
Коэффициент загруженности сотрудников службы поддержки.

HELPDESK        STORAGE       2	        			 ;1   Number of operators helpdesk
**************************************************************************************************
	GENERATE        6,3					 ;2   The number of subscribers Ticket
	ADVANCE         (Exponential(1,0,2)),,			 ;3   during dialing
          ENTER            HELPDESK              			 ;4   incoming call
	TRANSFER         ALL,OPR1,OPR2,3       			 ;5   definition of operator availability
OPR1      SEIZE            OP1                               ;6   Verification of employment operator number 1
	ASSIGN          1,OP1                              ;7   If the operator is free in this case, accept a call
	TRANSFER        ,COME                              ;8   Jump to the process of service
OPR2      SEIZE            OP2                               ;9   Verification of employment operator number 1.
	ASSIGN          1,OP2                              ;10  If the operator is free in this case, accept a call
COME      LEAVE            HELPDESK                          ;11  Beginning the process of providing technical support
	ADVANCE         10,8              			 ;12  Service time
	RELEASE          P1                                ;13  The release of the operator
	TERMINATE       0                      			 ;14  Removes the Active Transaction from the simulation
	GENERATE        480                                ;15  Working day (minutes)
	TERMINATE       1                                  ;16  Minus one minute
	    START           1                                  	 ;17  Start from the first minute



Как и в прошлый раз опишу построчно

Строка 1 — HELPDESK STORAGE 2 – Создаем накопитель Служба поддержки емкостью 2 сотрудника
Строка 2 — GENERATE 6,3; вот мы и подошли к другому способу задачи блока генерации, в даннмо случае цифра 6 означает что примерно раз в 6 мнут появляется 1 звонок, цифра 3 означает что отклонения от шести минут составлят ± 1.5 минуы. Еще блок GENERATE можно было задать так
(Exponential(1,0,6)), вообще то что справедливо для ADVANCE, во многом справедливо и для GENERATE.
Строка 3 – ADVANCE (Exponential(1,0,2)),, — говорит нам о том сколько времени у звонящего уходит на то чтобы вспомнить телефон тех поддержки и набрать номер, а уходит у нас в среднем 2 минуты по экспоненциальному распределению. цифра 1 – выбирает генератор случайных чисел (от 1-7 как с ними работать я не разобрался), цифра 0 – определяет смещение (пока для меня тоже загадка), цифра 2 собственно минуты. Хочу добавить что существуют и другие законы распределения, по которым можно задать временной промежуток, но о них лучше почитать в учебнике. Который я указал вначале статьи.
Строка 4 — ENTER HELPDESK – вход в накопитель (входящий звонок)
Строка 5 — TRANSFER ALL,OPR1,OPR2,3 – говорит нам что данное событие обрабатывается для всех входящих вызовов (ALL), что операторы обработки начинаются с метки OPR1 и движутся с шагом в 3 блока пока не доберутся до метки OPR2
Строка 6 — OPR1 SEIZE OP1 — вот и наш первая метка, на которой происходит проверка занятости первого оператора службы поддержки (OP1)
Строка 7 — ASSIGN 1,OP1 – В случае если оператор 1 свободен. То мы передаем входящий звонок ему, если нет то через три строки (от 6-й) идем на строку 9
Строка 8 — TRANSFER ,COME — нет нужды узнавать о занятости второго оператора, переходим на метку COME
Строка 9 OPR2 SEIZE OP2 — если первый оператор был занят, проверяем второго
Строка 10 — - ASSIGN 1,OP2 – и отдаем звонок ему.
Строка 11 — COME LEAVE HELPDESK – звонок покидает накопитель служб поддержки
Строка 12 — ADVANCE 10,8 – время которое оператор затрачивает на то чтобы дать человеку совет как правильно вкрутить лампочку.
Строка 13 — RELEASE P1; — оператор помог человеку и освободился. P1 в данном случае это ссылка на некий указатель (или параметр ), этот момент я не могу объяснить, но он работает.
Строка 14 – TERMINATE – (ноль можно не писать по умолчанию и так ноль), если верить справки то в данном случае этот блок расскажет системе о том, что пора выводить эту итерацию из активного цикла и переходить к следующей. В любом случае без него система выдаст нам ошибку.
Строки 15- 17 аналогичны строкам первой модели.

В результате получим следующие данные

результаты Модель 2 - коэффициент использования операторов



Структура вывода похожа на структуру вывода первой модели, разве что вместо очереди — накопитель предлагаю вам с ней разобраться самостоятельно. Кстати параметры генерации отчета можно настроить (на этом компьютере у меня не установлен GPSS и нет желания его ставить, поэтому поверьте пока на слово, что в настройках программы есть такая возможность ну, а я если не забуду допишу в понедельник сюда, как это сделать)
Итак, мы видим, что наши операторы вполне приемлемо загружены примерно на 75% и 87 % соответственно. Будем считать, что двух операторов вполне достаточно, чтобы посоветовать людям как правильно вкрутить лампочку. Но мы же с вами — народ любопытный, давайте посмотрим, что будет если к ребятам подсадить еще одно нахлебника с телефоном.
Для этого рассмотрим немного модифицированную модель. Предлагаю вам разобраться с ней самостоятельно.

HELPDESK        STORAGE       3	        			 ;1   Number of operators helpdesk
**************************************************************************************************
	GENERATE        6,3					 ;2   The number of subscribers Ticket
	ADVANCE         (Exponential(1,0,2)),,			 ;3   during dialing
          ENTER            HELPDESK              			 ;4   incoming call
	TRANSFER         ALL,OPR1,OPR3,3       			 ;5   definition of operator availability
OPR1      SEIZE            OP1                               ;6   Verification of employment operator number 1
	ASSIGN          1,OP1                              ;7   If the operator is free in this case, accept a call
	TRANSFER        ,COME                              ;8   Jump to the process of service
	SEIZE            OP2                               ;9   Verification of employment operator number 1.
	ASSIGN          1,OP2                              ;10   If the operator is free in this case, accept a call
	TRANSFER        ,COME                              ;11   Jump to the process of service
OPR3      SEIZE            OP3                               ;12   Verification of employment operator number 1.
	ASSIGN          1,OP3                              ;13  If the operator is free in this case, accept a call
COME      LEAVE            HELPDESK                          ;14  Beginning the process of providing technical support
	ADVANCE         10,8              			 ;15  Service time
	RELEASE          P1                                ;16  The release of the operator
	TERMINATE       0                      			 ;17  Removes the Active Transaction from the simulation
	GENERATE        480                                ;18  Working day (minutes)
	TERMINATE       1                                  ;19  Minus one minute
	START           1                                  ;20  Start from the first minute




Результат под спойлером

результаты Модель 2 - коэффициент использования трех операторов



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

На последок хочется вам рассказать о том, что GPSS-WORLD представляет более обширные возможности для моделирования, чем те о которых я вам поведал. Просто ввиду ограниченности моих знаний я не могу вам их адекватно продемонстрировать. Но, тем не менее в качестве бонуса приведу пример работы с переменными

	INITIAL X$APPLES,3		;1 Set Variable
	GENERATE	1		;2 set count of cicles
	SAVEVALUE APPLES-,1		;3 set APPLES=APPLES-1
	TERMINATE 1		;4 delete one iteration
	START	1		;5 1 Start from the first cicle



Давайте опять построчно

Строка 1 — INITIAL X$APPLES,3 ;1 задаем значение переменной, X$ в данном случае нам как-то указывает на название переменной, а цифра три это значение которое мы запишем в переменю APPLES (кстати я не фанат продукции APPLE просто в тот момент на общем столе лежало 3 яблока, а одно я забрал себе, прям как в детсадовских задачах по математике)
Строка – 2 GENERATE 1 – создадим 1 итерацию
Строка 3 — SAVEVALUE APPLES-,1; – сохраним в переменную яблоки ее значение минус один.
Строки 4-5 помогут нам закончить программу.

результаты Модель 3 - переменные



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

Ну что же теперь вы знаете об одном из инструментов с помощью, которого можно создать имитационную модель процесса, инструмент не самый удобный и уже похоже не дорабатываемый разработчиками, но тем не менее если вы проявите фантазию то за один два дня сможете провести исследование какой-нибудь модели и например опубликовать его в научном журнале или на конференции (об этом я уже писал раньше )
В любом случае теперь у вас есть еще 1 инструмент, чтобы творить, развиваться и делать мир лучше. Право слово это интереснее чем лопать шарике на смартфоне, сидя в общественном транспорте.
Всем хороших выходных, счастья добра и удачи :)
Метки:
  • +4
  • 85,4k
  • 6
Поделиться публикацией
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 6
  • +2
    Помню это безобразие в версии под DOS'ом. Долго искал ошибку как-то, оказалось, что маленькие буквы нельзя было использовать.
    • 0
      Сам сегодня с той же бедой мучался. правда уже под Windows
    • +1
      А мы вот у себя в институте студентов обучаем на AnyLogic. Пробовали?
      • 0
        Нет у нас был весьма отсталый факультет, им дай волю они бы нас учили только фортрану :) Но спасибо что упомянули о AnyLogic на досуге поковыряю, может пригодиться
      • +1
        о, нет! эта картинка в начале поста, она же пропагандирует…

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.