Agent Based Model Practical 1

1. Introduction

This series of practicals develops a simple spatial Agent Based Model (ABM) - a type of model useful for studying behaviour and emergence in complex systems.

The ABM will represent individual 'agents' which will have varying characteristics. It will run iteratively such that each agent will do things in simulation steps (iterations of the model) which represent the passage of time. What the agents do will in some ways change their characteristics, the characteristics of other agents, and the spatial 'environment' in which they are located and which is represented as a different kind of entity.

In building an ABM, you will put theory into practise and learn more about:

The agents will have simple behaviours and will interact with the environment. The model will be initialised by reading data read from files. The model simulation will be visualised as an animation. Model progress will be printed to the console. Additional outputs from the model will be saved in files.

2. Getting started

Initially two agents are going to be represented in an absrtact two dimensional plane. The location of these agents will be given by cartesian coordinates: (x0, y0) and (x1, y1). They will be initialised at the same location and will move randomly one step. Code will be written to calculate the distance between cartesian coordinates.

The way this is done by following the instructions is imperfect. The code will be refactored and rewritten in subsequent practicals so it is done in a better ways as you learn more theory.

The algorithm to implement for this practical can be written as follows:

# Initialise variable x0
# Initialise variable y0
# Change x0 and y0 randomly
# Initialise variable x1
# Initialise variable y1
# Change x1 and y1 randomly
# Calculate the Euclidean distance between (x0, y0) and (x1, y1)

In your local code repository create a new directory called 'src' and within this create a new directory called 'abm1'.

Open Spyder and save the file as 'model.py' in the 'abm1' directory.

Copy the algorithm above and paste it into the file.

Add a line after the line "# Initialise a variable x0' to initialise a variable 'x0' with the value '0' and print this out:

x0 = 0
print("x0", x0)

Save and run the program. The output from running the program should be:

x0 0

Note that two parameters are passed into the print function. These are printed out sequentially with a space delimiter by default.

Do the same for variable 'y0'.

3. Randomly changing values

The Python standard library random module implements pseudo-random number generators for various distributions and provides a way to change variable values randomly. To use the module it has to be imported. Towards the top of 'model.py' add the following import statement:

import random

It is good practice to organise import statements at the top of files as this makes them easy to find and makes it less likely that a module is imported multiple times, which does not raise excpetions and stop code executing as expected, but clutters code and makes it less efficient.

Use an if statement to determine whether to increase or decrease 'x0' based on the value obtained from a call to the function random: First obtain and print a pseudo-random number in the range [0, 1) as follows:

rn = random.random()
print(rn)

Run your program a few times to observe that the value of 'rn' varies randomly.

What is happening, is that the start (seed) of pseudo-random sequence used to generate numbers randomly is being set from the computer clock time (which moves on incrementally at a high frequency.

Declare an 'if statement' so that if the value 'rn' is less that '0.5' increase 'x0' by '1', otherwise decrease 'x0' by '1':

if rn < 0.5:
    x0 = x0 + 1
else:
    x0 = x0 - 1
print("x0", x0)

Run your program a few times to observe that sometimes the value of 'x0' increases and sometimes it decreases and this corresponds to the value of 'rn'.

When testing code, it is unhelpful for results to vary randomly in ways that are difficult to repeat, as this makes conditions that only occassionally happen difficult to investigate. So, it is sensible to 'set the seed' of random and in doing so ensure that the same results are produced each time. After the import statements add the following:

# Set the pseudo-random seed for reproducibility
random.seed(0)

When you run the program, you should get the following output:

x0 0
y0 0
rn 0.8444218515250481
b False
x0 - 1 

For different results pass in a different value into the 'seed' function (e.g. random.seed(1)), for more random results the time could be input as the 'seed'.

Similarly modify the value of 'y0'. Then similarly initialise the variables 'x1' and 'y1' and then similarly modify these randomly. Test that the movements vary for different seeds and that changes in each coordinate are independent of how the other coordinates change.

4. Calculate the Euclidean distance

Use the Pythogorean theorem to calculate the distance between the cartesian coordinates (x0, y0) and (x1, y1). The algorithm is:

# Calculate the difference in the x coordinates.
# Calculate the difference in the y coordinates.
# Square the differences and add the squares
# Calculate the square root

At the end of your source code set: 'x0' and 'y0' to equal '0'; 'x1' to equal '3', and 'y1' to equal '4'. Then add the algorithm above into your source code and try to calculate the distance between the cartesian coordinates(0, 0) and (3, 4). The symbol '**' can be used to raise a number to the power of another number. So, raising a number to the power of '0.5' calculates the square root. (Alternatively, import the standard library math module and use the sqrt function). The expected distance between (0, 0) and(3, 4) is 5.

5. Review, commit and look ahead

Hopefully, you managed to develop code that produces the correct answer. If not, do not worry, the important thing is to have tried. Perhaps look ahead to the start of the next ABM practical where some code that does everything is provided.

There is a lot of repetition in the code. The agents are not well defined. There are just some variables that have been changed randomly. If the code that changes the variable randomly was duplicated the coordinates would move as many times as that code is duplicated. But, there is a better to do this with less code repetition and that results in easier to understand and maintain code.

Add and commit to your local git repository and assuming you are using GitHub - push your changes to GitHub.

In the next ABM practical: Each pair of coordinates will be stored together in a container, for loops will be used to create and move more agents, and the model will be visualised.