Конкретные предложения.

 

   Попытка осмыслить эту проблему в целом, привела к пониманию,  что начинать все нужно с погружения возможностей языка GPSS в один из хороших языков программирования, обеспечивающих эффективную работу с Windows. Естественно, что в первую очередь рассматривались возможности таких языков, как Delphi, С++ Builder и C# . Очевидно, что реализация основных блоков GPSS не так уж и сложна. Она включает в себя работу со списками заявок и работу с такими объектами, как очереди, устройства, таблицы, и так далее.

  Вопрос о том, как реализовать порядок выполнения блоков, управляемый заявками, имеет свое очевидное решение. Нужно чтобы все  блоки модели были оформлены как вызовы процедур и находились в операторе Switch для языка C++, или в операторе Case для языка Delphi. Тогда выбор  нужного блока (вызова процедуры) можно выполнять на основе номера следующего блока активной заявки, которая продвигается в данный момент. После выполнения очередного блока, управление вновь передается активной заявке. Естественно, что в качестве блоков возможно использование не любых процедур языка высокого уровня, а только тех, которые обеспечивают корректную работу со списками заявок, в частности, с номерами текущего и следующего блока активной заявки.

   Таким образом, основные блоки, команды и стандартные числовые атрибуты языка GPSS можно представить как процедуры и функции языка C++ или Delphi, причем код модели на GPSS может быть адекватно представлен как последовательность соответствующих вызовов процедур языка программирования. Например, это может выглядеть следующим образом на языке Delphi:

  Procedure modeltxt (NextBlock:integer);

  Begin With BL,SYS do case NextBlock of

 {::ng1_}   1:ng1.Generate(100,90);

        2: que1.Queue;

        3: fac1.Seize;

        4: que1.Depart;

        5: Advance(95,90);

        6: fac1.Release;

        7: Buffer;

        8: Terminate(1);

   {//end_model}

 Else modelerror;end;end;

   Эквивалентный код  на языке GPSS World выглядит следующим образом:

        Generate 100,90

        Queue que1

        Seize fac1

        Depart que1

        Advance 95,90

        Release fac1

        Buffer

        Terminate 1

   Для представления списков заявок и работы с ними удобно использовать таблицы баз данных. Таблицы  хорошо подходят и для представления X и P – параметров, а также для представления групп заявок и списков прерывания.

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

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

  Здесь просто и естественно создаются исполнимые файлы (программы) – являющиеся моделями конкретных систем массового обслуживания. Нет никаких проблем в создании новых блоков для построения модели, в том числе и блоков, которые нужны только для конкретной модели. Фактически, возможности разработчика модели более не ограничены набором имеющихся блоков GPSS, а определяются только его потребностями.

   Именно такая система для построения моделей в стиле GPSS и названа автором объектным GPSS. Некоторое увеличение времени набора кода модели и несколько большее процессорное времени моделирования, в сравнении, например, с GPSS World, с избытком компенсируется расширенными возможностями системы.

   То, что для реализации системы выбран язык Delphi, а не C++, или, например, C#  - не является принципиальным. Просто на этом языке код модели выглядит несколько более привычным, по сравнению с аналогичным кодом на  языке C++.  Однако, нет никаких принципиальных трудностей в построении аналогичной системы на языке C++. Правда язык Microsoft C++ плохо сочетается с идеологией предлагаемой системой, для Object GPSS больше подходят RAD языки ( Rapid Application Design).

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

В отличие от других версий GPSS, здесь предусмотрена типизация данных.  Непосредственно в модели можно использовать следующие базовые типы данных: Integer, Double, Boolean, String.  В этой связи, X и P параметры могут быть значениями любого из этих 4 типов.

В рассматриваемой системе, GPSS – модель представляет собой Include –файл, который вставляется в головную программу с помощью указания компилятору вида:

{$INCLUDE model}

Файл Model.pas содержит описание конкретной модели на Delphi  в стиле GPSS.

Весь проект ObjectGPSSProject вместе с моделью, компилируется системой Delphi с получением конкретной модели, с которой уже можно проводить эксперименты.

Всего в проект входят 6 модулей:

ModelingUnit – модуль главной формы модели.

ModelUnit – модуль, в который помещается модель (файл Model.pas)

GPSS_SYS – модуль с основными командами и блоками Object GPSS, ядро всей системы.

AddModelUnit – модуль с дополнительными командами и блоками Object GPSS, используемыми для взаимодействия с главной формой.

InputBoxUnit – модуль с диалоговым окном ввода данных.

TableUnit - модуль с таблицами базы данных.

Все файлы проекта, кроме файла  Model.pas ,  в принципе, не зависят от конкретной модели и вместо их кодов можно использовать DCU – файлы, то есть они могут  быть представлены в виде уже откомпилированных частей, которые нуждаются только в сборке в единую программу. Правда, так как в модуль ModelUnit включается файл Model.pas , то для компиляции всего проекта нужен его код, то есть файл ModelUnit.pas .

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

Взаимные связи модулей отражены на Рис.1.

Рис.1.  Связи модулей проекта Object GPSS.

Пример полного файла Model.pas для приведенной выше модели, выглядит следующим образом.

// Model description auto.

Const modelname='E:\object GPSS\models\trial1.txt’;

ng1_=1; 

num_bl=8; 

  {/sh} {//end_const}

  {/sh} var

{/ng1} ng1: Tgenerate;

{/fac1} fac1: Tfacility;

{/que1} que1: Tqueue;

  {/sh} {//end_var}

  {/sh} {//end_proc_func}

  {/sh} procedure initial; begin

{/ng1}  tgenerate.init(ng1,ng1_,100,90);

{/fac1}  Tfacility.init(fac1);

             setstart(1000);

{/que1}  Tqueue.init(que1);

  {/sh} {//end_init}  end;

  {/sh} procedure closeallobj;  begin  {//begin_close}

{/que1}  que1.freeobj;

{/fac1}  fac1.freeobj;

{/ng1}  ng1.freeobj;

  {/sh}  end;

  {/sh} procedure resetall;  begin

{/fac1}  fac1.reset;

{/que1}  que1.reset;

  {/sh} {//end_reset} end;

  {/sh} procedure  modeltxt(NextBlock:integer);begin

With BL,SYS do case NextBlock of

{/ng1} {::ng1_}   1:ng1.Generate(100,90);

        2: que1. Queue;

        3: fac1.Seize;

        4: que1.Depart;

        5: Advance(95,90);

        6: fac1.Release;

        7: Buffer;

        8: Terminate (1);

  {/sh} {//end_model} else modelerror;end;end;

  {/sh} procedure report; begin

{/fac1}  fac1.report('fac1');

{/que1}  que1.report('que1');

  {/sh} {//end_report} end;

 {/sh}  procedure modeling(tg:integer);  begin

 {/sh}     start(tg);

  {/sh}  end;

Этот файл содержит следующие части:

Описание констант, переменных и объектов модели.

Процедуру   Initial, в которой выполняется инициализация всех переменных и объектов модели.

Процедуру CloseAllObj, в которой выполняется уничтожение всех переменных и объектов модели.

Процедуру  ResetAll, в которой выполняется сброс статистики по объектам модели.

Процедуру  ModelTxt, в которой и описывается собственно модель системы.

Процедуру  Report, в которой выполняется формирование выходной статистики по объектам модели.

Процедуру Modeling, в которой указаны конкретные команды манипуляции с моделью.

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

Если используются массивы объектов, то в частях 2,3,4,6 модели, соответствующие  вызовы процедур должны выполняться в циклах. Причем в части 3 цикл должен выполняться в обратном порядке.

Несмотря на кажущуюся громоздкость описания модели, практически все ее части, кроме «начинки» процедуры ModelTxt, создаются программой – конвертером формирования модели, по сути дела, автоматически.

В данном случае, корректировке была подвергнута только строка

{/ng1}  tgenerate.init(ng1,ng1_,100,90);

и была вставлена строка

setstart(1000); .

Эта строка задает начальное значение  счетчика завершений TG1 , отображаемое  на главной форме.

Модель, в той форме, в какой она представлена в файле Model.pas, не удобна для разработки и модификации, поэтому ее лучше сохранять и создавать в некоторой промежуточной форме. И только непосредственно перед компиляцией их следует конвертировать, с тем, чтобы получить собственно файл модели Model.pas. Это также обеспечивает программа – конвертер.

Наиболее ценная часть всей системы – это модуль GPSS_SYS, который и обеспечивает собственно моделирование.

Головой  модуль системы обеспечивает следующие возможности проведения опытов с моделью.

Запуск модели, то есть вызов процедуры Modeling с указанным значением счетчика TG1.

Временную, точнее досрочную остановку процесса моделирования, с возможностью продолжения текущего моделирования.

Полную очистку модели с возвратом ее в начальное состояние.

Сброс собранной статистики по модели.

Формирование полного или частичного отчета по моделированию.

Настройку перечня  выводимой в отчет информации.

Просмотр выводимой в ходе моделирования, или выведенной по окончании моделирования графической информации.

Завершение моделирования, как с сохранением текущего состояния модели, так и без его сохранения.

Если для модели потребуется другая головная программа, то можно использовать и другую головную программу. Однако она должна соблюдать соглашения о связях. Естественно, это потянет за собой изменения и в других модулях проекта. Однако при соответствующе аккуратности, можно избежать перекомпиляции модуля GPSS_SYS.

Созданная программа может быть переименована и перенесена  в другую папку, правда вместе с файлом, имя которого совпадает с именем файла модели  в промежуточной форме. Его  расширение должно быть GPR. Этот файл нужен для формирования отчета и подготавливается программой - конвертером.

Так как Object GPSS создает модели на основе классов объектов, то при работе с объектами вначале должно указываться имя объекта, затем точка, а затем, имя процедуры или функции из  класса. Например, fac1.Seize – означает «занять устройство с именем fac1»,   fac1.Report('fac1') – «вывести отчет по устройству с именем fac1» и так далее.

Система Object GPSS содержит следующие классы объектов:

Класс TSYS, который содержит основные функции системы GPSS. Фактически это класс нужен только потому, что функции GPSS имеют слишком простые имена, которые могут понадобиться разработчику модели. Так, например, в  GPSS – World есть СЧА M1 – текущее время жизни заявки, TG1 – текущее значение счетчика завершений. Аналогичные функции в Object GPSS будут выглядеть так SYS.M1 и SYS.TG1. Функции этого класса, в основном, совпадают с теми, которые есть, в GPSS World. К существенным изменениям набора функций можно отнести замену СЧА P и X  на функции RP, IP, BP,  SP, RX, IX, BX, SX, которые выдают значения вещественных, целых, логических и строковых P и X параметров соответственно.

В отличие от GPSS – World , X – параметры имеются не только у системы, но и у любого объекта, включая  пустой объект, у которого ничего нет, кроме этих параметров. 

Класс TFUNCTION описывает числовые функции, эквивалентные функциям типов C и D в GPSS World. Аналоги остальных видов функций реализованы непосредственно в виде общих функций системы моделирования. Числовые функции можно задавать при их инициализации и при переопределении. Функции можно также выводить в виде графиков.

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

 Класс TTABLE описывает таблицы, предназначенные для сбора статистики. Он  пополнен процедурой, которая выводят таблицы в виде гистограмм.

 Класс TQUEUE описывает очереди. Его процедуры и функции,  по сути, не отличаются от аналогичных блоков и СЧА GPSS– World.

Класс TSTORAGE описывает многоканальные устройства. Он пополнен блоком SETSTORAGE, который устанавливает новую предельную емкость устройства, и блоком SETGOTO, который задает перенаправление заявок с входа устройства на другой блок, или обеспечивает запрет на вход заявок в многоканальное устройство.

Класс TFACILITY описывает одноканальные устройства. Для таких устройств также имеется блок SETGOTO, и  несколько иначе построена система блоков для реализации прерываний, и для реализации доступности и недоступности устройства. А именно: блоки PREEMPT, RETURN,  FAVAIL и FUNAVAIL  заменены блоками EXTRACT, EXTRACTPREEMPT, PREEMPT, PREEMPT0, RETURN, RETURN0, которые удаляют обслуживаемые и прерванные на устройстве заявки, прерывает обслуживание заявки с занятием и без занятия устройства, а также возвращает из прерывания заявку после обслуживания текущей заявки или принудительно, после периода недоступности устройства.

 Классы TGROUP, TIGROUP, TSGROUP описывают группы для вещественных чисел, целых чисел и для строк. Их процедуры и функции,  по сути, мало отличаются от аналогичных блоков и СЧА GPSS World.

Класс TTGROUP описывает группы заявок. Его набор функций и процедур  заметно расширен, в первых, за счет типизации данных, то есть в данном случае P – параметров, а во вторых, за счет обеспечения доступа к параметрам заявок из списка группы при отборе нужных заявок. Отбор нужных заявок и изменение значений их P – параметров ведется с помощью отдельно описанных функцию выбора и функций вычисления значений. Эта особенность повышает возможности блоков работы с группами заявок. В этом классе блоки SCAN и ALTER заменены  блоками RSCAN, ISCAN, BSCAN, SSCAN и RALTER, IALTER, BALTER, SALTER,  которые отыскивают и изменяют значения вещественных, целых, логических и строковых P  параметров соответственно.

 Класс  TUSER описывает списки пользователя. Его  набор функций заметно расширен за счет доступа к параметрам заявок из списка пользователя при выборе удаляемых заявок. Отбор нужных заявок ведется с помощью отдельно описанных функцию выбора. Эта особенность повышает возможности блоков работы со списками пользователя.

Набор блоков, которые используются без объектов, в основном, совпадает с теми, которые есть в обычном GPSS. Формально, все они отнесены к объекту BL. Однако здесь возможно присваивание значений переменным, в том числе элементам массивов. Для этого используются блоки RLET, ILET, BLET, SLET для вещественных, целых, логических и строковых переменных соответственно.

 P и X  - параметры – типизированы, а поэтому вместо блоков ASSIGN и SAVEVALUE используются блоки RASSIGN, IASSIGN, BASSIGN, SASSIGN и RSAVEVALUE, ISAVEVALUE, BSAVEVALUE, SSAVEVALUE  для вещественных, целых, логических и строковых P и X параметров соответственно. Значения X – параметров можно менять как при моделировании, так и при подготовке к новому моделированию.

 Возможна установка нового значения счетчика завершений в ходе моделирования, блок SETTG1.

 Роль блоков GATE, TEST и TRANSFER   взял на себя расширенный блок TEST, который обеспечивает разветвление на произвольное число направлений, в зависимости от выполнения условий, а также задержку заявки, если  все условия неверны. Блок TRANSFER остался только как блок перехода на подпрограмму, или как блок безусловного перенаправления заявок.

Появился блок розыска указанной заявки FINDXN1, который определяет  для нее текущий и следующий блок, а также список, в котором она находится.

 Модель может использовать и блоки, которые предназначены для использования возможностей конкретной  головной программы. Они,  строятся на основе имеющихся блоков. К ним относятся блоки TOPOINT, TOSTRING, TOVALUE  и CURRENBLOCKS, которые выводят очередную точку, очередную строку, очередное значение и текущую информацию о блоках. 

 Имеется обширный набор функций, которые, в основном, совпадает с теми, которые есть в  GPSS World. Однако к ним добавлены функции, которые выбирают значения по логическим условиям, или по номеру. Это  функции RBYBOOL, IBYBOOL, SBYBOOL, RBYNUN,IBYNUM, SBYNUM для вещественных, целых и строковых значений соответственно.

Значения функций можно получать и из диалогового окна или компонента Memo главного окна. Это  функции RINPUT, IINPUT, BINPUT, SINPUT, INPUTITEM и RGET, IGET, BGET, SGET  для вещественных, целых и строковых значений соответственно.

Имеется также ряд других блоков, процедур и функций для организации моделей и процесса моделирования.

Если возникает необходимость создания новых блоков, то это  возможно сделать следующим образом.

Можно просто вместо блока в процедуре ModelTxt, поместить составной оператор, обрамленный ключевыми словами Begin - End. Составной оператор должен содержать блоки Object GPSS, и должен быть устроен таким образом, чтобы при любых ситуациях, в нем выполнился ровно один блок, из числа описанных в системе. 

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

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

Код модели в промежуточной форме выглядит, например, следующим образом.

  {/sh} {//end_const}

  {/sh} var

{/ng1} ng1:Tgenerate;

{/fac1} fac1:Tfacility;

{/que1} que1:Tqueue;

  {/sh} {//end_var}

  {/sh} {//end_proc_func}

  {/sh} procedure initial; begin

{/ng1}  tgenerate.init(ng1,ng1_,100,90);

{/fac1}  Tfacility.init(fac1);

             setstart(1000);

{/que1}  Tqueue.init(que1);

  {/sh} {//end_init}  end;

  {/sh} procedure closeallobj;  begin  {//begin_close}

{/que1}  que1.freeobj;

{/fac1}  fac1.freeobj;

{/ng1}  ng1.freeobj;

  {/sh}  end;

  {/sh} procedure resetall;  begin

{/fac1}  fac1.reset;

{/que1}  que1.reset;

  {/sh} {//end_reset} end;

  {/sh} procedure  modeltxt(NextBlock:integer);begin

With BL,SYS do case NextBlock of

{/ng1} ::ng1_   *:ng1.Generate(100,90);

        *: que1.Queue;

        *: fac1.Seize;

        *: que1.Depart;

        *: Advance(95,90);

        *: fac1.Release ;

        *: Buffer;

        *: Terminate(1);

  {/sh} {//end_model} else modelerror;end;end;

  {/sh} procedure report; begin

{/fac1}  fac1.report('fac1');

{/que1}  que1.report('que1');

  {/sh} {//end_report} end;

 {/sh}  procedure modeling(tg:integer);  begin

 {/sh}     start(tg);

  {/sh}  end;

Как видно, он мало отличается от кода файла Model.pas .

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

1. Запустить оболочку системы Delphi

2. Открыть в ней проект ObjectGPSSProject.dpr

3. Открыть в ней файл Model.pas .

4. Запустить приложение converter.exe

5. Открыть в нем имеющуюся модель, или создать новую. Если создана новая модель, то ее следует сохранить на диске.

6. Выполнить пункт «convert model» в приложении converter.exe . В системе Delphi появится сообщение об изменении файла Model.pas и предложение перезагрузить его. Нужно выбрать ответ Yes.

7. Затем следует запустить весь проект на выполнение. Если в файле Model.pas имеются ошибки, то нужно их исправить в приложении converter.exe и вновь выполнить шаги 6 и 7. Если  ошибок нет, то запускается приложение с конкретной моделью и с ним можно проводить опыты.

При отладке модели наиболее  опасной ошибкой  является появление блоков вне  процедуры ModelTxt или появления вызовов процедур, не являющихся блоками в процедуре  ModelTxt. Для защиты от такого рода ошибок, можно записывать блоки в формате BL.вызов_процедуры, например, Bl.Advance, вместо Advance. Дело в том, что все блоки находятся в объекте BL, и это дает дополнительную защиту от ошибок. Кроме того, некоторую защиту обеспечивает пункт меню «Test Names», который проверяет, не встречаются ли в модели имена процедур и функций, которые недопустимы в конкретном разделе.

Для создания очередной модели, (её EXE – файла) достаточно повторить пункты 5,6,7.

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

В заключение, следует отметить, что эксперименты с  системой Object GPSS полностью подтвердили реалистичность всех возложенных на нее ожиданий. Она устойчиво работает и создает программы для конкретных моделей систем массового обслуживания на языке Delphi, в том числе и довольно сложных. В системе легко обеспечивается развитие за счет создания новых блоков и функций. Она может взаимодействовать с компонентами головной программы, как в ходе моделирования, так и на стадии подготовки модели к моделированию. Если разработчику понадобится дополнить главное окно системы новыми компонентами, то это также несложно сделать. При этом главный файл (GPSS_SYS) не понадобится даже перекомпилировать.

Система содержит 12 типов объектов, 74 блока, 73 команды для процедуры Modeling и 123 функции. Естественно, что часть этих команд будет использоваться крайне редко, так что реально нужно знать и использовать не более 150 команд, блоков и функций.

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

 
назад

вперед