Недавно в блоге мы описали и разобрали модель пограничного пункта. На её примере посмотрели, как с помощью моделирования решать бизнес-задачи систем массового обслуживания. Сегодня расскажем о технических особенностях модели: из каких блоков она состоит, как работает, и какие приёмы использовались при её разработке.
Саму модель вы найдёте в программе AnyLogic версии 7.3.7 и выше на начальной странице на вкладке «Примеры моделей», а также в AnyLogic Cloud. Поехали!
Совместная работа библиотек AnyLogic
Чтобы реалистичнее описать процесс пересечения границы, в модели применяются специализированные библиотеки: Библиотека дорожного движения и Пешеходная библиотека. Для взаимосвязи логики поведения транспортных средств и пешеходов используется Библиотека моделирования процессов. Остановимся подробнее на процессах посадки и высадки пассажиров – точках соприкосновения библиотек. Для удобства мы рассмотрим только путешественников на автомобилях.
Пока машина движется по направлению к контрольно-пропускному пункту и ждёт очереди на въезд к точке досмотра, поведение находящихся внутри пассажиров нас не интересует. Автомобили для нас являются единственными агентами, действующими в модели. Ситуация меняется, когда водитель и пассажиры выходят из автомобиля, чтобы пройти пограничный контроль.
Когда автомобиль приехал к точке досмотра, он выходит из блока toCheckpoint (тип – CarMoveTo), и пассажиры, включая водителя, выходят из автомобиля. Этот процесс реализован с помощью блока dropoffPassengers (Split). Почему мы использовали блок Split, а не Dropoff? Дело в том, что блок Dropoff работает с агентом как с контейнером, внутри которого уже есть другие агенты. Мы не рассматриваем процесс посадки пассажиров в автомобиль в начале путешествия, поэтому используем блок Split: он позволяет разделить в модели входящих агентов на пассажиров (агенты Tourist) и их автомобили.
Агент Tourist ещё не обладает логикой поведения пешехода. Чтобы добавить его в пешеходное пространство, мы проводим агента через блок getOffCar (PedEnter). Он задаёт место в пространстве, в котором появляется агент, и его основные характеристики, например, скорость. В нашем случае турист появляется в зоне высадки у точки досмотра, где остановился его автомобиль. С этого момента он рассматривается как пешеход, а связанные с ним процессы идут параллельно с процессами для автомобиля.
Когда пассажиры проходят проверку документов, автомобиль ожидает их в блоке delayOnPassportControl (Delay). Если автомобиль не направили на углублённый досмотр, он проходит общий осмотр инспектором в блоке Inspection (Service).
Когда пассажиры прошли проверку, они выводятся из пешеходного пространства в блоке readyToGetOnCar (PedExit) и встают в виртуальную очередь Queue, где ждут окончания проверки автомобиля. Машина переходит в блок pickupPassengers (Pickup), где забирает пассажиров из очереди. Дальше модель снова рассматривает только движение автомобиля.
Если автомобиль или его пассажиры вызвали подозрение, машину направляют в бокс углублённого досмотра. В этом случае автомобиль переходит в блок pickupDriver (Pickup). У этого блока нет встроенной очереди, поэтому к нему подключена внешняя очередь, в которой скапливаются водители. Чтобы не уехать без водителя, автомобиль начинает движение в тот момент, когда водитель входит в подключённую очередь. Будьте внимательны и учитывайте особенности блока Pickup в своих моделях, чтобы ваши транспортные средства не уезжали без пассажиров ☺
Определение числа автомобилей в очереди к пограничному пункту
В модели рассматривается процесс прохождения путешественниками границы, а вот движение транспортного потока до погранперехода не описано. Его нужно учесть, если количество машин превышает пропускную способность контрольно-пропускного пункта.
Обычно в моделях для создания автомобилей используется блок CarSource. Если все места на дороге заняты, он останавливает генерацию новых объектов. В некоторых случаях важно понимать реальное количество автомобилей в очереди, даже если она выходит за отрезок шоссе в модели. Для этого мы заменили блок CarSource на блоки Source и Queue, не требующие привязки к дороге. Таким образом, если на дороге есть свободное место, автомобиль направляется в блок carAppearsOnRoad (carEnter). Иначе автомобиль находится в виртуальной очереди и ждёт свободного места на дороге в модели. Так машина попадает в дорожную сеть.
Когда автомобиль появился в дорожной сети, он движется с остальными машинами в сторону погранперехода в блоке toCarStopBeforeCheckPoint (carMoveTo). Таким образом, общая очередь к погранпереходу складывается из автомобилей на дороге и в очереди. Эта сумма и используется для сбора статистики по очереди к контрольно-пропускному пункту.
Распределение автомобилей по точкам досмотра
Пользовательский блок CarCheckPointLanes описывает, как автомобиль проезжает пограничный пункт. Блок hold блокирует машины на въезде, поэтому на территорию погранпункта автомобили въезжают по одному. Машина проезжает до разделения основной трассы на полосы (блок toBorder (CarMoveTo)) и останавливается у стоп-линии borderStopLine. Далее автомобиль выбирает полосу и точку досмотра. Когда автомобиль подъезжает к точке досмотра, он выходит из блока toCheckpoint (carMoveTo), а блок hold, в свою очередь, снимает блокировку с потока и позволяет следующему автомобилю въехать на территорию погранпункта. Если доступной точки досмотра нет, машина ожидает у стоп-линии borderStopLine, а основной поток – у стоп-линии carStop.
Процесс выбора точки досмотра имеет свои особенности. Сначала автомобиль выбирает полосу с наибольшим числом доступных точек (функция getLaneWithLessCars()) и резервирует одно из этих мест (функция captureFreeCheckPoint()). На полосе обгон запрещён. Поэтому, если на ближайшей к въезду точке досмотра уже есть автомобиль, а остальные точки свободны, машины не смогут занять их, пока полоса не освободится полностью. В таком случае за машиной резервируется ближайшее к выезду место. В остальных случаях автомобиль занимает точку досмотра, следующую за последней занятой на полосе. Если же автомобиль занимает ближайшую к въезду точку досмотра, другие автомобили не могут въехать на эту полосу. Такой подход позволяет равномерно распределять транспортный поток между полосами досмотра и избежать скученности при въезде на точки досмотра.
Как только автомобиль занимает точку досмотра, функция blockLaneAfterCheckpoint() запрещает ехать следующим за ним машинам на полосе. Они будут оставаться на месте до тех пор, пока первый автомобиль не пересечёт стоп-линию перед ним.
Когда досмотр окончен, автомобили направляются в один из блоков carMoveTo на Main в зависимости от результатов досмотра. Если нарушений не выявлено, автомобиль следует далее в блоке toNeutralZone. Если у водителя проблемы с документами, он не может пересечь границу, и автомобиль возвращается в страну отправления в блоке backToInitialCountry. Если в машине контрабанда, автомобиль едет в специальную зону в блоке ToDetentionCenter.
Иерархия и масштабируемость модели
Чтобы упростить процесс разработки и изучения модели, его можно разделить на несколько этапов и описать каждый из них отдельно. В нашем примере мы группировали несколько блоков диаграммы процессов, связанные общей логикой, в пользовательские блоки: carCrossCheckPoint и busCrossCheckPoint. Они описывают процессы прохождения границы индивидуальными путешественниками на автомобилях и туристическими группами на автобусах. Выделение этих процессов в отдельные блоки делает модель более гибкой. Например, при изменении процедуры прохождения границы туристическими группами достаточно изменить содержание блока busCrossCheckPoint, не затрагивая диаграмму процессов верхнего уровня и блок carCrossCheckpoint. Если вы не умеете создавать пользовательские блоки в AnyLogic, посмотрите наше обучающее видео.
Чтобы увеличить пропускную способность модели пограничного пункта, можно добавить дополнительные пункты досмотра Checkpoint и проходящие через контрольно-пропускной пункт дорожные полосы CheckpointLane. При этом изменять логику модели не потребуется.
Управление параметрами модели с помощью интерактивных элементов
В нашем примере можно менять режим интенсивности прибытия транспортных средств без остановки модели. Это позволяет визуально оценить, насколько быстро сократится очередь у границы, если увеличить число сотрудников пограничной службы или снизить входной поток транспортных средств. Прибытие можно задать автоматически (по расписанию) или настроить вручную, с помощью интерактивного бегунка. Если флажок Use default car rate schedule установлен, автомобили прибывают по расписанию. Как только пользователь снимает флажок или передвигает бегунок, блок carSource (Source) начинает создавать новых агентов с заданной пользователем интенсивностью.
Обычно бегунок напрямую связывается со значением свойства Rate блока Source. Однако, чтобы связать автоматическое и ручное управление расписанием, в примере использовался другой подход.
Для хранения текущего значения интенсивности прибытий был создан параметр carRate с привязанным бегунком carRateSlider. Если прибытие задаётся вручную, параметр указывается в качестве значения свойства Arrival rate блока carSource (Source). А если автомобили приезжают по расписанию, события resetTimeStatsEvent обновляет значение параметра и бегунка каждый час. Таким образом, бегунок всегда отражает текущее значение интенсивности прибытия: при переходе к расписанию он автоматически переключается на заданное значение.
На этом всё. Если вам нравятся публикации с разбором моделей, рекомендуем почитать о модели шоколадной фабрики, автозаправочной станции, а также познакомиться с первой частью рассказа про модель пограничного перехода. Надеемся, эти статьи понравятся вам так же, как и та, которую вы только что прочитали. Ждём ваши вопросы в комментариях.