AnyLogic
Развернуть
Размер шрифта

Событие, происходящее при выполнении условия

Если вам нужно отследить выполнение определенного условия и произвести какое-то действие при его происхождении — используйте событие, происходящее при выполнении условия.

Демо-модель: Event Triggered by Stock Reaching Threshold Открыть страницу модели в AnyLogic Cloud. Там можно запустить модель или скачать ее по ссылке Исходные файлы модели.

Чтобы задать событие, происходящее при выполнении заданного условия

  1. Перетащите элемент Событие из палитры Агент на диаграмму типа агентов.
  2. Как только вы создадите событие, вы можете изменить его имя в небольшом текстовом редакторе, который появится справа от элемента в графическом редакторе. Закончив ввод нового имени, нажмите Enter.
  3. Перейдите в панель Свойства и выберите При выполнении условия из выпадающего списка Тип события.
  4. Введите логическое условие срабатывания в поле Условие. Событие произойдет тогда, когда это условие впервые выполнится (результат проверки условия станет равен true).
  5. Задайте действие события в секции Действие. Здесь вы можете написать Java код, который будет выполняться при происхождении этого события. Возможно, более удобно будет задать это действие с помощью функции и поместить сюда вызов этой функции.

Свойства

Основные свойства

Имя — Имя события. Имя используется для идентификации события и доступа к нему из кода.

Отображать имя — Если опция выбрана, то имя события будет отображаться в графическом редакторе.

Исключить — Если опция выбрана, то событие будет исключено из модели.

Видимость — Если опция выбрана, то событие будет отображаться на презентации во время выполнения модели.

Тип события — Тип события:

По таймауту — Событие происходит по истечению таймаута. Событие будет происходить согласно выбранному Режиму
С заданной интенсивностью — Событие происходит с заданной интенсивностью (которая задается в поле Интенсивность)
При выполнении условия — Событие происходит при выполнении заданного условия (которое задается в поле Условие)

Режим — [Свойство отображается, только если Тип события: По таймауту] Выберите здесь режим события, срабатывающего по таймауту:

"Ручной" — вы будете самостоятельно управлять событием, планируя его происхождение на нужные вам моменты времени. Такое событие будет происходить только при вызове пользователем метода restart() этого события, которому в качестве аргумента передано значение времени, которое должно будет пройти от текущего момента времени до его срабатывания, например: myEvent.restart(15).
Если таймаут будет иметь фиксированное (одно и то же) значение, то можно просто ввести это значение в поле Таймаут и вызывать метод myEvent.restart(), без задания значения таймаута с помощью параметра метода.
Срабатывает один раз — Событие произойдет только один раз, в момент времени, заданный в поле Время срабатывания (абсолютное). Время срабатывания может быть задано как календарная дата (модельного времени!) или как число единиц модельного времени, которое должно пройти от момента запуска модели.
Обратите внимание, что здесь вы задаете абсолютное время, и если это значение будет меньше текущего значения модельного времени, когда вы создадите это событие, то такое событие никогда не произойдет.
Циклический — Событие будет происходить периодически. Вы задаете Время первого срабатывания (абсолютное) и Период. Время первого срабатывания может быть задано как календарная дата (модельного времени!) или как число единиц модельного времени, которое должно пройти от момента запуска модели.
Обратите внимание, что здесь вы оперируете абсолютным временем. Если вы хотите использовать относительные времена (т.e. отсчитывать время первого срабатывания от момента создания события), то используйте функцию time() в поле Время первого срабатывания (абсолютное). Функция time() возвращает текущее значение модельного времени (в данном контексте она будет возвращать время создания события).

Таймаут — [Свойство отображается, только если Тип события: По таймауту и выбран Режим "Ручной"]Выражение, вычисляющее значение времени, которое должно пройти от момента планирования события пользователем (путем вызова метода restart() этого события) до происхождения этого события.

Время срабатывания (абсолютное) — [Свойство отображается, только если Тип события: По таймауту и Режим: Срабатывает один раз] Абсолютное время срабатывания события, заданное как календарная дата (модельного времени!) или как число единиц модельного времени, которое должно пройти от момента запуска модели.

Время первого срабатывания (абсолютное) — [Свойство отображается, только если Тип события: По таймауту и Режим: Циклический] Абсолютное время первого срабатывания циклического события, заданное как календарная дата (модельного времени!) или как число единиц модельного времени, которое должно пройти от момента запуска модели.

Период — [Свойство отображается, только если Тип события: По таймауту и Режим: Циклический] Период срабатывания циклического события.

Интенсивность — [Свойство отображается, только если Тип события: С заданной интенсивностью] Интенсивность, с которой будет происходить данное событие. С математической точки зрения, событие будет происходить с таймаутом, вычисляемым согласно экспоненциальному закону распределения с параметром, равным заданному в этом поле значению. Т.e., если интенсивность равна 5, то событие будет происходить в среднем 5 раз в единицу модельного времени.

Условие — [Свойство отображается, только если Тип события: При выполнении условия] Условие, при выполнении которого произойдет данное событие.

Вести журнал в базе данных — Если опция выбрана, то информация о всех происходящих событиях будет добавляться в журнал выполнения модели events_log (если в свойствах базы данных выбрана опция вести журналы).

Действие

Java код, выполняемый при происхождении данного события.

Как продолжить отслеживать условие после того, как однажды оно уже произойдет?

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

Однако в некоторых случаях вам может понадобиться продолжать отслеживать выполнение заданного условия для того, чтобы определить, когда оно выполнится в следующий раз. Если вы хотите продолжать отслеживание выполнения условия после того, как событие уже произошло, то поместите в конец кода Действия этого события строку event.restart();, которая будет производить перезапуск события.

Чтобы предотвратить немедленное происхождение события (приводящее к зацикливанию), не забывайте добавлять здесь же код, который будет сбрасывать результат заданного условия срабатывания события в false (добавляйте код прямо перед строкой, выполняющей перезапуск события).

Когда происходит проверка выполнения условия?

Такой тип события происходит, когда заданное логическое условие становится истинно (результат его вычисления становится равен true). Если условие выполняется изначально, то событие происходит немедленно. Иначе оно будет выполнено, как только заданное условие станет истинным.

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

  • Если у агента есть непрерывно изменяющиеся переменные, то численный решатель постоянно отслеживает выполнение условия, т.e. условие проверяется на каждом шаге решателя численных уравнений. Это делается потому, что условие может выполниться в результате решения уравнений, поскольку оно может содержать переменные, непрерывно изменяющиеся согласно заданным дифференциальным уравнениям. Точка переключения — момент, когда условие станет истинным, будет определяться AnyLogic с заданной вами точностью.
  • В чисто дискретных моделях условие проверяется, если в агенте происходят какие-то изменения, например:
    • если в этом агенте происходит какое-то событие, например, срабатывает переход, происходит какое-то другое событие, вызывается Действие при изменении параметра, в порт агента приходит сообщение и т.д
    • если пользователь явно вызовет метод onChange() агента
    Если изменения происходят во вложенном агенте, то условие при этом не проверяется!

    Если вам нужно проверять условия во вложенных агентах или популяциях, то вы можете установить периодическую проверку таких условий следующим образом. Выберите опцию Выполнять шаги в секции свойств Пространство и сеть агента верхнего уровня, на диаграмме которого заданы эти агенты. Добавьте вызов функции onChange(); в поле Действие на шаге (в секции свойств Действия агента) того вложенного агента, где вы хотите проверять условия с заданной периодичностью. Это будет более эффективным решением по сравнению с добавлением циклически срабатывающего события с вызовом функции onStep() в каждого такого агента.

Проблема чувствительности

При задании условия вы должны учитывать так называемую проблему чувствительности. Пусть событие ожидает выполнения условия x>=5, а переменная x непрерывно изменяет свое значение, как показано на приведенном ниже рисунке:

Проблема чувствительности

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

Программное управление событиями

Вы можете программно управлять событием этого типа с помощью соответствующего программного интерфейса:

Управление событиями
Функция Описание
void reset() Отменяет запланированное событие (если в текущий момент это событие запланировано на какой-то момент в будущем). Прекращает ожидание выполнения заданного условия (оно может быть впоследствии продолжено путем вызова метода restart()).
void restart() Продолжает отслеживание выполнения условия. Может быть вызван в коде действия события, либо в тот момент, когда событие является неактивным.
Как мы можем улучшить эту статью?