Взаимодействие агентов

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

Функции взаимодействия агентов

Вы можете посылать сообщения вызовами любой из следующих функций.

Отправление сообщений: send() /*рекомендуется*/

Функция

Описание

void sendToAll(Object msg)

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

Параметр:
msg - сообщение

void sendToRandom(Object msg)

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

Параметр:
msg - сообщение

void sendToAllConnected(Object msg)

Отправляет сообщение всем связанным агентам.

Параметр:
msg - сообщение

void sendToRandomConnected
(Object msg)

Отправляет сообщение случайно выбранному из связанных агентов.

Параметр:
msg - сообщение

void sendToAllNeighbors
(Object msg)

Отправляет сообщение всем соседям. Доступно, только если агент находится в дискретном пространстве.

Параметр:
msg - сообщение

void sendToRandomNeighbor
(Object msg)

Отправляет сообщение случайно выбранному соседу. Доступно, только если агент находится в дискретном пространстве.

Параметр:
msg - сообщение

void send(Object msg, Agent dest)

Отправляет сообщение заданному агенту.

Параметры:
msg - сообщение
dest - агент-получатель

void send(Object msg, MessageDeliveryType mode)

Отправляет сообщение агенту или группе агентов, указанных в параметре режима отправки.

Параметры:
msg - сообщение
mode - указывает режим отправки сообщения:

ALL - сообщение будет отправлено всем агентам, обитающим в среде

ALL_CONNECTED - сообщение будет отправлено всем связанным агентам

RANDOM - сообщение будет отправлено случайно выбранному агенту из среды обитания данного агента (это может быть в том числе и агент, который и послал это сообщение)

RANDOM_CONNECTED - сообщение будет отправлено случайно выбранному связанному агенту (если таковой будет)

ALL_NEIGHBORS - (только в дискретном пространстве) сообщение будет отправлено всем агентам, находящимся в соседних ячейках, в соответствии с текущей моделью соседства

RANDOM_NEIGHBOR - (только в дискретном пространстве) сообщение будет отправлено случайно выбранному соседу

Мгновенная доставка сообщений: deliver()

Функция

Описание

void deliverToAllAgentsInside
(Object msg)

Мгновенно доставляет сообщение всем агентам в среде.

Параметр:
msg - сообщение

void deliverToRandomAgentInside
(Object msg)

Мгновенно доставляет сообщение случайному агенту в среде, если в ней имеются другие агенты.

Параметр:
msg - сообщение

void deliverToAllConnected
(Object msg)

Мгновенно доставляет сообщение всем связанным агентам.

Параметр:
msg - сообщение

void deliverToRandomConnected
(Object msg)

Мгновенно доставляет сообщение случайно выбранному из связанных агентов.

Параметр:
msg - сообщение

void deliverToAllNeighbors
(Object msg)

Мгновенно доставляет сообщение всем соседям.

Параметр:
msg - сообщение

void deliverToRandomNeighbor
(Object msg)

Мгновенно доставляет сообщение одному случайно выбранному соседу.

Параметр:
msg - сообщение

void deliver(Object msg, Agent dest)

Мгновенно доставляет сообщение заданному агенту.

Параметры:
msg - сообщение
dest - агент-получатель

void deliver(Object msg, MessageDeliveryType mode)

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

Параметры:
msg - сообщение
mode - указывает режим отправки сообщения:

ALL - сообщение будет доставлено всем агентам, обитающим в среде

ALL_CONNECTED - сообщение будет доставлено всем связанным агентам

RANDOM - сообщение будет доставлено случайно выбранному агенту из среды обитания данного агента (это может быть в том числе и агент, который и послал это сообщение)

RANDOM_CONNECTED - сообщение будет доставлено случайно выбранному связанному агенту (если таковой будет)

ALL_NEIGHBORS - (только в дискретном пространстве) сообщение будет доставлено всем агентам, находящимся в соседних ячейках, в соответствии с текущей моделью соседства

RANDOM_NEIGHBOR - (только в дискретном пространстве) сообщение будет доставлено случайно выбранному соседу

Пример:

Давайте рассмотрим модель со следующей структурой:

Типы агентов:

Агент Main содержит две популяции агентов: people[..] (агенты типа Person) и trucks[..] (агенты Truck), а также одного агента warehouse типа Warehouse.

Допустим, нам нужно, чтобы один агент person отправил сообщение "Buy!" любому другому агенту person.

Для отправки сообщения мы используем подходящую функцию send...(), вызывая ее из поля Действие агента Person или какого-либо элемента, принадлежащего этому агенту (событие, элемент управления, диаграмма состояний и т.д.).

Если вызвать функцию sendToRandom("Buy!");, сообщение отправится случайному агенту из всех агентов, находящихся в одном пространстве. В нашем случае это может быть агент из популяции trucks, агент из популяции people или агент warehouse.

Чтобы отправить сообщение случайному агенту из конкретной популяции (в нашем случае это популяция people), используйте другую функцию:

send("Buy!", randomFrom( people ) );

Функция randomFrom() выбирает случайного агента из указанной популяции. Более подробную информацию об этой функции вы можете найти в статье о том, как выбрать случайного агента.

Вы можете еще больше сузить диапазон выбора агента, применив дополнительные фильтры. Ниже представлены несколько примеров фильтрации:

send("Buy!", randomFrom( people.findAll( p -> p.income > 5000 ) );

Здесь сообщение отправляется только тем агентам из популяции people, чей доход превышает 5000.

send("Buy!", randomFrom( filter( people, p -> p.inState( Person.PotentialUser ) );

Этот код отправляет сообщение только тем агентам из популяции people, которые в диаграмме состояний находятся в состоянии PotentialUser.

Функции, которые используются для фильтрации (filter(), findFirst(), findAll(), randomWhere(), top()), описаны в статье про выбор элемента из коллекции.

Примечание: Все эти функции должны вызываться только из агентов, находящихся в одном пространстве. При вызове функции для отправки сообщения из агента верхнего уровня (в нашем случае это агент Main) появится сообщение об ошибке "Environment must be defined".

Когда мы говорим о вызове функции из агента Main, мы подразумеваем вызов функции из какого-либо поля в разделе свойств Действия агента Main (например, действие При запуске), или из поля Действие любых элементов управления, событий или диаграмм состояния, расположенных на диаграмме агента Main.

Выбор функции send() или deliver()

Разница между методами send() и deliver() заключается в следующем: send() планирует доставку/получение с помощью отдельного события, которое будет выполнено сразу после окончания текущего события (спустя нулевое модельное время), в то время, как deliver() выполняет доставку/получение прямо в теле текущего события. Если при обработке полученного сообщения получатели будут пытаться взаимодействовать с другими агентами, то использование метода deliver() может привести к нежелательным зацикливаниям, и поэтому рекомендуется использовать метод send().

Реакция на получение сообщения

У каждого агента, обитающего в среде, имеется видимый неудаляемый элемент connections, который содержит связи с контактами этого агента и задает настройки взаимодействия. Вы можете найти этот элемент над осью X в графическом редакторе:

Чтобы задать реакцию агента на получение сообщения

  1. Откройте диаграмму агента-получателя сообщения.
  2. Прокрутите страницу вверх, найдите и щелкните мышью элемент connections.
  3. Откройте секцию свойств Взаимодействие.
  4. Введите соответствующий код в свойстве Действие при получении сообщения. Полученное сообщение доступно здесь как msg (локальная переменная типа Object*), а агент-отправитель сообщения доступен как sender (если сообщение было послано централизованно с помощью среды, то эта переменная равна null).

* вы можете указать тип сообщения в свойстве Тип сообщения, расположенном чуть выше.

Как только сообщение будет доставлено агенту, будет выполнено Действие при получении сообщения, если оно для него задано.

Если, например, вы хотите перенаправить сообщение в диаграмму состояний агента, вам нужно будет выбрать эту диаграмму в таблице Перенаправлять сообщение в:


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