Представьте, что вы месяцами работали над сложной моделью, и вот, когда она уже почти готова, клиент просит вас внести в нее существенные изменения. На горизонте уже маячат еще несколько дней дополнительной работы, реструктуризация модели и попытки вписать в нее то, что изначально там не предполагалось. Не очень радостная перспектива, правда?
Есть ли способ избежать подобных ситуаций или хотя бы сделать их менее болезненными? Ответ – в прочном фундаменте модели, который оставляет место для гибкости и дает вам полный контроль над самой моделью.
Как же построить имитационную модель так, чтобы она не рассыпалась, когда в нее внезапно нужно внести изменения? Об этом эксперт по имитационному моделированию Бенджамин Шуманн рассказал на своем мастер-классе, проведенном на ежегодной конференции AnyLogic в 2022 году.
В этой статье мы даем краткий обзор мастер-класса, в котором на примере модели завода рассматриваются технические нюансы построения надежных и гибких моделей. Будет полезно как для начинающих разработчиков, так и для профессионалов в AnyLogic.
Читайте также нашу статью по более раннему видео от Бена, в котором он затрагивает тему структуры модели, а именно рефакторинг модели и встраивание и наследование агентов.
Содержание:
- Начинающим: визуальная структура и встроенные агенты
- Уверенным пользователям: диаграммы процессов и ООП
- Уверенным пользователям: показатели эффективности и анимация
- Следующий уровень: графики и работа с данными
- Выводы и видео мастер-класса
Начинающим: визуальная структура и встроенные агенты
Те, кто только начинает работать с AnyLogic, обычно строят модели, просто перетаскивая элементы на холст – быстро, просто и может подойти для небольших проектов. Но при работе с большими и сложными моделями Бен предлагает пойти более безопасным, хотя и более долгим путем – сначала заложить прочный фундамент модели.
Вместо того чтобы нагромождать элементы модели на холсте, вы можете сгруппировать их в разноцветные прямоугольники для каждого агента, как показано ниже. Вы также можете определить, что должен делать каждый агент, и написать над этими прямоугольниками. Например, агент Main может хранить только фактическую модель и обрабатывать данные.

Большинство пользователей AnyLogic создают логику модели непосредственно в агенте Main. Бен же предлагает поместить ее в отдельный агент под названием Model, который затем будет встроен в Main. Все это обеспечивает прозрачность и гибкость модели на более поздних этапах проекта.
Для бóльшей гибкости и контроля над агентами всегда следует создавать изначально пустую популяцию, а не одиночного агента.

В модели завода, которая использовалась как пример на мастер-классе, есть два действующих агента – изделия и машины. Для каждого из них Бен создает отдельного агента в Model. Еще одно предложение на этом этапе – нарисовать простую схему иерархии в Main с помощью диаграмм состояний агентов. Она поможет вам отслеживать отношения между агентами в вашей модели.

Проверка «вменяемости» модели и другие приемы, связанные с иерархией агентов, завершают этот раздел в видео.
Уверенным пользователям: диаграммы процессов и ООП
Пользователи склонны размещать логику модели в Main, из-за этого в больших и сложных проектах она может стать беспорядочной и, следовательно, подверженной ошибкам. Один из способов упрощения потоковых диаграмм для моделирования процессов – создание пользовательского блока для повторяющихся последовательностей.
Другое решение – разделить потоковую диаграмму так, чтобы ее части находились в соответствующих агентах. Рассмотрим второй вариант подробнее.
Возвращаемся к примеру модели завода. Допустим, что агент станка (A_Machine) и агент изделия (A_Product) имеют свои собственные диаграммы процессов. У каждого изделия есть список станков, которые оно должно посетить, и оно посещает их по очереди.
Сначала Бен создает функцию, которая позволяет ему контролировать очередность, в которой создаются станки или изделия при запуске модели. Далее он задает параметры, определяющие агентов. Он делает это для каждого агента в отдельности, следуя принципу инкапсуляции объектно-ориентированного программирования. Такой подход поможет ему в будущем: если ему нужно будет изменить модель, ему не придется полностью переписывать код.
Но если у каждого агента есть своя диаграмма процессов, то как все это работает в системе?
Изделие поступает на завод и отправляется на обработку к первому станку:

Затем оно обрабатывается в течение некоторого времени и либо переходит к следующему станку, либо покидает завод:

Когда станок заканчивает обработку изделия и готовит его к отправке с завода, он направляет изделие в блок Sink в агенте Main.

Уверенным пользователям: показатели эффективности и анимация
Один из ключевых принципов качественного моделирования – отделить логику от визуализации. Следуя этому принципу, Бен предлагает создать отдельных агентов, которые будут «шпионить» за другими агентами (в нашем примере это A_Machine и A_Product) и сообщать вам с помощью графиков, как они работают.
Так вы получите полный контроль над общими показателями эффективности, избежите ошибок в измерении активности агентов и повысите скорость работы агентов, которые содержат логику.
Для этого вам понадобятся: капля магии языка Java, создание агентов-шпионов, их параметров и функций. Наконец, вам потребуется еще немного Java-кода, чтобы Main понял, в каком виде отображать показатели эффективности для станков.

Теперь про анимацию. К ней можно применить простое правило: если в модели есть объекты, которые должны двигаться, то задайте анимацию непосредственно в агенте, содержащем логику. Если двигающихся объектов нет, задайте анимацию в агентах-шпионах.
Следующий уровень: графики и обработка данных
Теперь, когда у вас есть агенты-шпионы, отображающие статистику, почему бы не сгруппировать их в новом агенте под названием Dashboard? Так вы сможете создавать любые графики на свое усмотрение. Например, вы можете выбрать отображение только графиков для станков и точное место, где разместить для них анимацию.
Если вам нужно добавить больше типов агентов, скажем, добавить изделия, вы создаете еще один параметр, еще одну популяцию агентов (pop_UI_Product) и функцию, которая будет создавать изделия. Затем расположите графики так, как вы хотите, чтобы они отображались.
Сам агент Dashboard должен быть встроен в Main, и вам нужно создать функцию, которая запускает анимацию.

В конце мастер-класса Бен делится советами по загрузке и хранению данных модели. Общий принцип «хорошего» моделирования – отделение данных от самой модели, но Бен предлагает пойти дальше и добавить между ними прослойку – входные данные модели. Почему он считает этот подход эффективным?
Реальные данные могут быть беспорядочными и меняться со временем, а для работы модели нужны хорошо отформатированные и «чистые» данные. За это и отвечает слой с входными данными – он «переводит» реальные данные для модели. Таким образом, у нее всегда есть «чистые» входные данные для работы.
Кроме того, у такой конфигурации (реальные данные – прослойка с входными данными – модель) есть и другое применение – тестирование.
Поэтому, если реальная структура данных изменится, вам нужно будет внести лишь небольшие изменения в этот промежуточный слой, а модель при этом будет продолжать работать, как ни в чем ни бывало.
Чтобы такая конфигурация работала, сначала нужно добавить данные в таблицу Excel. Затем вы создаете Java-класс под названием POJO (plain old Java object) для каждой структуры данных (например, для станков) и дублируете эту структуру с помощью Java-кода.


Следующий шаг – создание Java-класса под названием InputData. С одной стороны, он будет загружать данные из Excel-файла, а с другой – создавать новые данные для тестирования.

Теперь вы можете задать входные данные модели в агенте Model, используя для этого параметр. Таким образом, когда вам нужно добавить дополнительные характеристики, например, к станкам на заводе, вам не придется создавать десятки новых параметров.
В Main вам нужно будет правильно настроить действия агента: когда вы запускаете модель, Main должен сначала загрузить данные, затем создать модель и ее агентов и, наконец, запустить анимацию (необязательный шаг).
Выводы и видео мастер-класса
На первый взгляд приемы и подходы, описанные в этом мастер-классе, – долгие и сложные, но они обеспечат вам гибкость и полный контроль над моделью. А возможность быстро и гибко что-то поменять становится критически важной в больших и сложных проектах.
Подводя итог, вот четыре основных вывода из этого мастер-класса:
- Если вы только начинаете моделировать в AnyLogic, создавайте и встраивайте агента Model в Main.
- Если вы уже уверенный пользователь, начните инкапсулировать агентов и функции. Помните, что агент определяется параметрами, а функция – аргументами.
- Отделяйте анимацию от логики модели. Создавайте агентов-шпионов, которые будут отслеживать работу других агентов. Нет необходимости в свойствах динамической анимации, у вас есть агенты-шпионы, и вам просто нужно время от времени их обновлять.
- Не просто отделяйте реальные данные от модели – создавайте между ними прослойку для входных данных. Так вы не будете зависеть от данных клиента, а ваша модель будет надежнее.
Смотрите видео мастер-класса How to Structure Your Models So They Never Crumble и стройте надежные модели.
Подпишитесь на ежемесячную рассылку, чтобы получать свежие материалы блога и новости об AnyLogic прямо на почту.