import random
5.7. Agent-based Models#
Agent-based models are used to describe actions and interactions of individuals (agents), which occur with various likelihoods. Simulations on such models can be used to make predictions about the future state of the agents. In this section, we refer to agents acting independently. We do not address multi-agent systems in which individuals collaborate with one another in groups.
Like random walks, agent-based models can be used to capture practical processes probabilistically in a variety of areas of study. They can predict the spread of disease, forecast the segregation (separation) of different populations in a certain region, optimize traffic conditions, and describe behaviors within social networks.
In a classic example, consider that we often hear news from other people we know. If a piece of information is shared, how might it spread, from one agent to another?
Let us develop an agent-based model and use the model to simulate how a piece of information spreads over time. As with any model, we make a few underlying assumptions. Some are very practical. Some are explicit simplifications of a real-life scenario to make the problem easier to solve. In modeling and simulations, practitioners like to start with simple models and evaluate how well they capture real scenarios. Modelers address some shortcomings in the simulations with changes to the model assumptions. Over time, we typically expand the scope of the model to address additional scenarios. Here we assume:
The population is a closed community. The number of individuals does not change.
Agents who do not have the information do not pass any information to others!
An agent does not pass information to itself.
Once an agent hears the piece of information, it will not forget the information. There is no transition from “knowing” to “not knowing”.
A transmission rate defines how many others hear the information from a given individual in one day.
Each agent has one of the allowed transmission rates with equal probability.
When an agent shares the information with another individual, that individual is selected from all the other members of the population with equal probability.
In models, initial conditions provide “starting information”. Let us take the following initial condition for our problem: On Day 0, 1 individual has the information.
Parameters are changeable values that quantify practical aspects of entities or processes involved in the problem. Let us identify some parameters for the agent-based model and assign them values as follows:
The value of the population parameter is 1000. (There are 1000 agents.)
The allowed transmission rates are 0, 1, 2, 3, 4, and 5.
The way the information could spread is as follows: We have Persons 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,…, 1000. These people might have transmission rates 3, 3, 2, 0, 5, 1, 1, 2, 3, 4, 2, 1, …, 4 respectively. Initially, 1 person knows the information. If that person is Person 1, and Person 1 has a transmission rate of 3, then on the first day of gossip, Person 1 might spread the information to Persons 5, 8, and 9 with transmission rates 5, 2, and 3, respectively. In Day 2 of gossip, Person 1 spreads the information to 3 people, Person 5 to 5 people, Person 8 to 2 people and Person 9 to 3 people. Note these may be some of the same people or people who already know the information. The process continues day-by-day.
Example. Simulate the spread of information under the given assumptions. How many days does it seem to take in general for the information to spread to a quarter of the population?
def rumor_spread(total_population):
# Set a maximum number of iterations.
max_it = 1000
# Inform Agent 0.
informed_status = [1]
# No one else has been informed.
for i in range(total_population-1):
informed_status.append(0)
# Generate a random number from 0 to 5 for each agent and store in a list as the number of transmissions.
transmission_numbers = []
for i in range(total_population):
transmission_numbers.append(random.randint(0, 5))
# Simulation of the process
day = 0
spread_to_quarter = False
day_spread_to_quarter = 0
while informed_status.count(1) != total_population and (day < max_it):
# Record the first day that at least 1/4 of the population has the information.
if not(spread_to_quarter) and informed_status.count(1) >= int(total_population/4):
day_spread_to_quarter = day
spread_to_quarter = True
new_status = informed_status[:]
for agent_index in range(total_population):
# print(informed_status)
if informed_status[agent_index] == 1: # If agent is informed,
# transmit to (inform) the appropriate number of randomly selected agents (excluding self).
for informing in range(transmission_numbers[agent_index]):
recipient_index = random.randrange(total_population)
while recipient_index == agent_index:
recipient_index = random.randrange(total_population) # Ensure agent does not transmit to self.
new_status[recipient_index] = 1
# Copy the lists to ensure that informed_status and new_status point to two different lists in memory.
informed_status = new_status[:]
day += 1
if day_spread_to_quarter > 0:
print(f"(A quarter of the individuals are informed by Day {day_spread_to_quarter}.)")
rumor_spread(1000)
(A quarter of the individuals are informed by Day 5.)
Run the code repeatedly: Typically it seems to take about 5 days for the information to spread to a quarter of the population of 1000. Sometimes the code does not give any output. Why?
To answer this question, notice that the outer while loop counts up the days and continues to repeat while not everyone in the population has been informed and the maximum number of iterations has not been exceeded.
In the exercises, you will add a few lines to the code to print how many days it took for all the individuals to be informed. If not all the individuals were informed within the maximum number of iterations, then your modified code will print a message accordingly.
5.7.1. Exercises#
Exercises
Exercise 1: Simulate the spread of information under the given assumptions. (a) How many days does it seem to take in general for the information to spread to half of the population? Modify the code given in this section to answer this question. (b) Add an if-else statement to the end of your function such that if the number of informed individuals equals the total population (if informed_status.count(1) == total_population), a message is printed that says by what day all the individuals are informed, i.e., include the value of day in the output. Otherwise (if the number of informed individuals does not equal the total population), print a message that not all the individuals were informed within the maximum number of iterations.
Exercise 2: This agent-based model could also be applied to the spread of disease. If “knowing the information” means “having the disease” and “not having the information” means “not having the disease”, what are the interpretations of the assumptions, initial condition, and parameters that are given? Explain how you may find the model compelling in the context of disease, or what changes to the model you recommend to better reflect the spread of disease.