Agent Geography

One of the key strengths of Agent Based Modeling is that it allows us to study the geographic relationship between our agents. So if we are developing a disease model we do not have to assume that all the agents are perfectly mixed together like atoms in a gas (such as we generally would in System Dynamics). Instead, using Agent Based Modeling we can explicitly define the physical relationship between the different agents and study how this geography affects the spread of the disease.

In general when we talk about geography we mean spatial geography: the locations of people within a region in terms of their latitude and longitude (and sometimes their elevation). Insight Maker supports this kind of geography, but it also supports a second kind of geography: network geography. Insight Maker allows the specification of "connections" between agents. This leads to a new type of geography where you have centrally located agents (ones connected to many other agents) and agents far from the network's center (those that are unconnected or just connected to a very few other agents).

Both these types of geographies can be useful in exploring important features of real-world systems. In the following sections, we will introduce their properties and show you how to utilize them in your own models.

Spatial Geography

In Insight Maker, each Agent Population can be given dimensions in terms of a width and a height. By default, agents are placed at a random location within this region. You can, however, choose a different placement method for the starting position of the agents. The following placement methods are available:

Random: The default. Agents are placed at random positions within the geometry specified for the agent population.

Grid: Agents are aligned in a grid within the population. When using this placement method, you will need to ensure that you have enough agents so that the grid is complete. You might need to experiment with increasing or decreasing the number of agents to make the grid fit perfectly for a given set of region dimensions.

Ellipse: Agents are arranged in a single ellipse within the region. If the region geometry is a square, then the agents will be arranged in a circle.

Network:: Assuming network connections between agents have been specified, the agents will be arranged in an attempt to create a pleasing layout of the network structure.

Custom Function: Here you can specify a custom function to control the layout of the agents. This function will be called once for each agent in the population and should return a two-element vector where the first element is the x-coordinate of the agent, and the second element is the y-coordinate. The variable Self in this function will refer to the agent that is being positioned.

Spatial Find Functions

When working with a spatially explicit model, a number of additional find functions are available for you to obtain references to agents that match a given spatial criteria.

FindNearby() is a function that returns a vector of agents that are within a given proximity to a target agent within an agent population. It takes two arguments: the agent target for which you want nearby neighbors and a distance. All agents within the agent population within the specified distance to the target agent will be returned as a vector.

It is useful now to introduce a concept that will be very helpful to you. When used in an Agent, Self always refers to the agent itself. If you have a primitive within an agent, Self can be used from that primitive to get a reference to the agent containing the primitive. So the following equation in an agent will return a vector of agents that are within 15 miles of the agent itself:

[Population].FindNearby(Self, {15 Miles})

Two other useful functions for finding agents in spatial relation to each other are FindNearest() and FindFurthest(). FindNearest returns the nearest agent to the target in a population while FindFurthest returns the agent that is farthest away from it. Each of them also supports an optional second argument determining how many nearby (or far away) agents to return (this optional argument defaults to one when omitted).

For example, the following equation finds the nearest agent to the current agent:

[Population].FindNearest(Self)

While this finds the three agents that are furthest from the current agent:

[Population].FindFurthest(Self, 3)

Movement Functions

You can also move agents to new locations during simulation. To do this, it is helpful to introduce a new primitive we have not yet discussed. This primitive is the Action primitive. Action primitives are designed to execute some action that changes the state of your model. For instance, they can be used to move agents or change the values of the primitives within an agent. An action is triggered in the same way a transition is triggered. Like a transition, there are three possible methods of triggering the action: timeout, probability, and condition.

For instance, we can use an action primitive in an agent and the Move() function to make agents move during the simulation. The Move function takes one argument: a vector containing the x- and y-distances to move the agent. Thus, we could place an action primitive in our agent and give it the following action property to make the agent move randomly over time. The equation will move the agent a random distance between -0.5 and 0.5 units in the x-direction and a random distance between -0.5 and 0.5 units in the y-direction.

Self.Move({rand(), rand()}-0.5)

Another useful movement function is the MoveTowards() function. MoveTowards moves an agent towards (or away from) the location of another agent. MoveTowards takes two arguments: the target agent to move towards and how far to move towards that agent (with negative values indicating movement away). The following command would move an agent one meter closer to its nearest neighbor in the population.

Self.MoveTowards([Population].FindNearest(Self), {1 Meter})

Network Geography

To create connections and remove connections between agents you can use the Connect() and Unconnect() functions. Both of these functions take one argument: the agents that should be connected or disconnected. For example, to connect an agent to its nearest neighbor, you could use the following:

Self.Connect([Population].FindNearest(Self))

To disconnect an agent from its nearest neighbor (assuming they are connected), you would use:

Self.Unconnect([Population].FindNearest(Self))

To obtain a vector of connections to an agent, use the Connected() function:

Self.Connected()

Connections are not directed so creating a connection from agent A to agent B is the same as creating a connection from agent B to agent A. Also only one connection between a given pair of agents will exist at a time. So creating two connections between a given pair of agents will have the same effect as creating a single connection.

By default, no connections are created when a simulation is initially started. If you change the Network Structure configuration property of the agent population primitive, you can specify a function to create connections when the simulation is started. This function is called once for each pair of agents in the model. The agents are available in the function as the variables a and b. If the function evaluates to true, then the agents will start connected. If the function evaluates to false, the agents will not be initially connected.

You could use this function to, for instance, specify that 40% of agents will be directly connected to each other at the start of the simulation. The following equation would do that by generating a random true/false value with 40% probability of returning true each time it is called:

RandBoolean(0.4)