AnyLogic поддерживает репликацию блоков диаграммы процессов. Реплицированный блок представляет собой сразу несколько блоков одного типа. Если в вашем процессе в какой-то момент агенты проходят через один из множества однотипных блоков, то с помощью репликации блоков вы можете сделать диаграмму вашего процесса более компактной и простой. С помощью репликации можно в том числе создавать масштабируемые системы, задавая количество элементов реплицированного блока с помощью параметра.
Давайте рассмотрим пример модели, в которой используются реплицированные блоки. Это модель существующего торгового центра (хотя список арендаторов, очевидно, претерпел изменения). Модель изучает проблемы скопления людей в коридорах и в зоне фудкорта, и влияние препятствий в виде скамеек, информационных стендов и киосков на загруженность коридоров.
Демо-модель: Shopping Mall Открыть страницу модели в AnyLogic Cloud. Там можно запустить модель или скачать ее по ссылке Исходные файлы модели.В торговом центре находится несколько десятков магазинов, и у каждого посетителя свой уникальный планируемый "маршрут" из определенных магазинов. Если бы каждый магазин был задан отдельным блоком, а все возможные комбинации маршрутов были заданы графически как блоки, связанные паутиной соединителей и блоков PedSelectOutput, то такая диаграмма процессов была бы огромной и нечитаемой.
Вместо этого в модели используются реплицированные блоки (в данном случае это нестандартные блоки, но принцип работы и с обычными библиотечными блоками точно такой же). Все магазины заданы одним реплицированным блоком shops; если вы откроете свойства блока, то увидите, что количество экземпляров у этого блока: 138. Аналогично флагманские магазины заданы блоком anchorShops (таких магазинов девять), и так далее.
Хорошо, один реплицированный блок задает сразу несколько экземпляров такого типа, то есть один блок на диаграмме будет задавать сразу все магазины в нашей модели. Но как же задан процесс направления пешехода в определенный блок из этого набора? Для этого используется обращение по индексу.
В динамическом поле каждого параметра реплицированного блока вы можете пользоваться локальной переменной index типа int.
К примеру, в этой модели у каждого магазина есть вход, заданный на диаграмме графически с помощью целевой линии. Чтобы задать соответствующую линию каждому отдельному магазину, в модель добавлена коллекция shopEntrances, которая содержит 138 целевых линий входа, по одной для каждого магазина. И в поле параметра Area entrance (вход в магазин) блока shops задано: shopEntrances.get(index). Здесь мы как раз и используем переменную index - индекс каждого отдельного блока, и с его помощью мы задаем каждому блоку целевую линию из коллекции с тем же самым индексом, что и у этого экземпляра реплицированного блока.
- Добавьте на диаграмму блок диаграммы процесса, который вы хотите реплицировать.
- Если это библиотечный блок, то разверните последнюю секцию свойств Специфические и выберите опцию Популяция агентов. Если вы знаете, какое количество блоков вам нужно создать, выберите опцию Популяция: Содержит заданное кол-во агентов и задайте требуемое количество экземпляров этого блока в поле Начальное количество агентов. Если же вы будете создавать блоки согласно имеющимся данным в базе данных, выберите опцию Загружается из базы данных и укажите источник данных с помощью расположенных ниже свойств.
- Если это нестандартный блок, то аналогичные свойства будут расположены в верхней части панели свойств блока:
Вы можете задать количество элементов реплицированного блока не только числом, но и с помощью параметра агента типа int. Такая параметризация может понадобиться в том числе и при необходимости одновременного изменения количества элементов сразу нескольких реплицированных объектов.
В графическом редакторе и в дереве модели в панели Проекты реплицированный блок можно отличить за счет добавления квадратных скобок после имени блока (аналогично индикации популяции агентов). В режиме выполнения модели внутри скобок будет отображаться действительное количество блоков, заданных этим элементом.
Получить доступ к отдельному элементу реплицированного блока, скажем, delay, можно с помощью метода delay.get(), которому в качестве аргумента нужно передать номер - индекс этого элемента в векторе реплицированных блоков (нумерация начинается с 0, индекс последнего элемента можно получить как <имя блока>.size() - 1).
В динамическом поле каждого параметра реплицированного блока вы можете пользоваться локальной переменной index типа int и с ее помощью ссылаться в динамическом выражении на индекс текущего блока.
Почему существует такое ограничение? Все просто — соединяя выходной порт реплицированного блока с другим блоком, вы просто направляете в этот блок всех агентов изо всех экземпляров реплицированного блока, и это нормальное поведение. Но если же вы соедините какой-то блок со входным портом реплицированного блока, то встанет вопрос — в какой именно экземпляр реплицированного блока следовать агентам?
Описанная проблема решается одним из следующих способов. Обычный блок соединяется со входом реплицированного блока виртуально:
- С помощью комбинации блоков Enter и Exit (блок Enter находится внутри нестандартного блока): Демо-модель: Airport Открыть страницу модели в AnyLogic Cloud. Там можно запустить модель или скачать ее по ссылке Исходные файлы модели.
- Или с помощью блоков SelectOutputIn и SelectOutputOut, как в рассмотренном выше примере (блок SelectOutputOut находится внутри нестандартного блока): Демо-модель: Shopping Mall Открыть страницу модели в AnyLogic Cloud. Там можно запустить модель или скачать ее по ссылке Исходные файлы модели.
-
Как мы можем улучшить эту статью?
-