AnyLogic
Expand
Font size

Communication between agents

Agents living in one environment can communicate via sending messages to each other.

Agent functions for communication

You can send the messages by calling one of the functions listed below.

Sending messages: send() (recommended)
Function Description
void sendToAll(Object msg) Sends a message to all agents in the same environment where this agent lives in.

msg — a message
void sendToRandom(Object msg) Sends a message to a randomly chosen agent in the same environment this agent lives in.

msg — a message
void sendToAllConnected(Object msg) Sends a message to all connected agents.

msg — a message
void sendToRandomConnected(Object msg) Sends a message to a randomly chosen connected agent.

msg — a message
void sendToAllNeighbors(Object msg) Sends a message to all neighbors. Available only if this agent lives in discrete space environment.

msg — a message
void sendToRandomNeighbor(Object msg) Sends a message to a randomly chosen neighbor. Available only if this agent lives in discrete space environment.

msg — a message
void send(Object msg, Agent dest) Sends a message to a given agent.

msg — a message
dest — the destination agent
void send(Object msg, MessageDeliveryType mode) Sends a message to an agent or a group of agents, as specified by the mode parameter.

msg — a message
mode — specifies the message sending mode, one of the following:
  • ALL — the message will be delivered to all agents in the environment
  • ALL_CONNECTED — the message will be delivered to all connected agents
  • RANDOM — the message will be delivered to one randomly chosen agent in the environment (including the message sender)
  • RANDOM_CONNECTED — the message will be delivered to one randomly chosen connected agent, if any
  • ALL_NEIGHBORS — (in discrete space only) the message will be delivered to all agents in the neighboring cells, subject to the current neighborhood model
  • RANDOM_NEIGHBOR — (in discrete space only) the message will be delivered to one randomly chosen neighbor, subject to the current neighborhood model
Instant message delivery: deliver()
Function Description
void receive(Object msg) Immediately delivers a message to this agent. Sender is set to null.

msg — the message
void deliverToAllAgentsInside(Object msg) Immediately delivers a message to all agents in the environment.

msg — the message
void deliverToRandomAgentInside(Object msg) Immediately delivers a message to a random agent in the environment, if there are any agents.

msg — the message
void deliverToAllConnected(Object msg) Delivers a message to all connected agents.

msg — the message
void deliverToRandomConnected(Object msg) Delivers a message to a randomly chosen connected agent.

msg — a message
void deliverToAllNeighbors(Object msg) Delivers a message to all neighbors. Available only if this agent lives in discrete space environment.

msg — the message
void deliverToRandomNeighbor(Object msg) Delivers a message to a randomly chosen neighbor. Available only if this agent lives in discrete space environment.

msg — a message
void deliver(Object msg, Agent dest) Delivers a message to a given agent immediately during this method call.

msg — a message
dest — the destination agent
void deliver(Object msg, MessageDeliveryType mode) Delivers a message to an agent or a group of agents, as specified by the mode parameter immediately during this method call.

msg — the message
mode — specifies the message sending mode, one of the following:
  • ALL — the message will be delivered to all agents in the environment
  • ALL_CONNECTED — the message will be delivered to all connected agents
  • RANDOM — the message will be delivered to one randomly chosen agent in the environment (including the message sender)
  • RANDOM_CONNECTED — the message will be delivered to one randomly chosen connected agent, if any
  • ALL_NEIGHBORS — (in discrete space only) the message will be delivered to all agents in the neighboring cells, subject to the current neighborhood model
  • RANDOM_NEIGHBOR — (in discrete space only) the message will be delivered to one randomly chosen neighbor, subject to the current neighborhood model

Example:

Assume we have a model of the following structure:

Agent types:

  •  Main (top-level agent)
    •  Person
    •  Truck
    •  Warehouse

On  Mainthere are two agent populations: people[..] (agents of type  Person) and trucks[..] (agents of type  Truck), and a single agent warehouse of type  Warehouse.

Say, we want one person to send a "Buy!" message to another person.

To send a message, you call the suitable send() function from an action of the  Person or one of its items (event, control, statechart, etc.).

If you call sendToRandom("Buy!"); you will send the message to a randomly chosen agent from the whole environment. In our case it can be either any agent from the trucks[..] population, or from people[..] population, or the warehouse agent itself.

To send a message to an agent randomly chosen from a specific population (in our case, people[..]), use the following function:

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

randomFrom() function randomly chooses one item from a specified population. You can find more information on this function in the article on how to select a random agent.

You can narrow down the selection even more by using the filtering conditions. Here are just a few examples:

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

Here the message is sent only to those agents from people[..] population whose income exceeds 5000.

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

This code sends the message only to those agents from people[..] population who are currently residing in the statechart's  PotentialUser state.

The filtering functions filter(), findFirst(), findAll(), randomWhere(), top() are described in the article on how to select an element from a collection.

All these functions should be called only from agents living in some environment. However, calling any message-sending function from the top-level agent (in our case,  Main) will cause the "Environment must be defined" runtime error.

By calling from  Main we mean calling these functions either from the  Main agent actions (e.g. its On startup code), or action code of any control, event, or statechart located on the  Main diagram.

send() vs. deliver()

The difference between send() and deliver() is the following: send() schedules the message delivery/reception in a separate event that will be executed after the current event in 0 time, while deliver() executes the delivery/reception directly inside its body. If the recipients may try to communicate other agents during incoming message handling, using deliver() may cause undesirable loops, and it is recommended to use send(). The mode parameter may have the following values:

  • ALL — the message will be delivered to all agents in the environment
  • ALL_CONNECTED — the message will be delivered to all connected agents
  • RANDOM — the message will be delivered to one randomly chosen agent in the environment (including the message sender)
  • RANDOM_CONNECTED — the message will be delivered to one randomly chosen connected agent, if any
  • ALL_NEIGHBORS — (in discrete space only) the message will be delivered to all agents in the neighboring cells, subject to the current neighborhood model
  • RANDOM_NEIGHBOR — (in discrete space only) the message will be delivered to one randomly chosen neighbor, subject to the current neighborhood model

Reacting on the message reception

Every agent that lives in environment has visual non-removable element connections that stores links to the contacts of this agent and defines communication settings. On the graphical diagram, you can find it above the X-axis:

Here you can define the reaction of the agent-recipient on the message reception.

To define agent's reaction on message arrival

  1. Open the diagram of the agent that receives messages.
  2. Scroll the graphical diagram a bit up and click on connections element.
  3. Open the Communication section of the properties.
  4. Type the reaction code in the On message received section. Use msg to access the received message and sender to access the sender agent. By default, the message is of the Object type. If necessary, you can specify the type of the message in the Message type control.

Once the message is delivered to a destination agent, its action code is executed, if defined.

If you need to forward messages to a statechart inside the agent, select the checkbox corresponding to the required statechart in the Forward message to table.

Having done this, you enable message processing by the statechart. If there are some active transitions that are triggered by the message reception, they will occur (if the received message satisfies the optional filters defined in the transition properties).

How can we improve this article?