Covid Simulation, an agent-based approach

Louis Nicolle
8 min readOct 13, 2021

--

Recently, my little brother asked me for some help with a school project. He wanted to study the propagation of an infection inside a crowd (I think he was inspired by some kind of recent event) and was having issues with the simulation part. I quickly became really interested in this idea and had a lot of fun designing an agent-based simulation, trying to understand the impacts of agent behaviors or infection characteristics. I’m now sharing the project’s results. If you too love graphs I hope you will be entertained and if you have some fun ideas to implement, send them all.

I wonder where the inspiration came from

On the first day, God created the world and its first inhabitants

I used the mesa framework in order to have a nice visualization quickly. You can see the whole code on this GitHub.

It’s alive

I started with hypotheses as simple as possible:

  • The world is a rectangular grid.
  • Humans move randomly in a neighbor cell each turn.
  • Humans can be either healthy, infected, or immune to the disease.
  • The infection lasts 50 turns and can infect neighboring humans. After that, the infected human becomes healthy and immune.
  • However, at each turn, infected humans have a chance to die.
  • At the beginning of the world, I infect 1 human randomly.

With those hypotheses, we can already see a neat graph. At the beginning of the infection, there is an explosion in the case number, each infected speeding the process. Then, around turn 100, the number of dead or immune humans has pushed the potential victim density under a breaking point. The infection stops progressing as it can’t find a new bearer and then slowly disappears.

This is fun but what if we changed this? And that?

Ok so now starts the exploration process, I want to change each and every parameter to see how it impacts the whole process. So I started breaking the system into different variables:

  • The number of humans (and with this the density)
  • The infection probability, which is the chance of a human passing its disease to a neighbor.
  • Infection duration, the number of turns before becoming healthy again and immune.
  • The death probability is the chance of dying of the infection after each turn (Beware, with this system, even a small death probability has a big impact.)

In the previous graph we had the following setup:

100 humans, infection_probability 10%, death probability 0,5%, infection duration 50 turns.

Mesa comes with an easy-to-setup slider system so I added them all to the application. It allowed us to play aimlessly with it and try a lot of combinations.

Sliders party

As we can see extreme parameters have extreme consequences on our infection. Here, with a big density of humans and with 100% of infected neighbors, the infection spreads nearly instantly and then disappears really quickly. But since we did not change the death probability, even though all humans were infected, the mortality rate has not critically increased compared to our first experience.

If instead of increasing the infection probability we increased the death probability, we can observe a really different result:

infection probability 10%, death probability 10%

Here the infection is slower (45 turns before peak compared to 10 turns with high infection probability) but as it spreads we can see the human population disappearing with it.

If you want to play with those sliders all by yourself, I encourage you to install the project from GitHub, if you have issues ask them there, I’ll try and help you.

Trying to mimic real life

Ok so now we can change a lot of infection parameters to try and replicate a true infection. But since the beginning, we did not change our humans at all.

They are so basic Orelsan did not even bother to evoke them.

Orelsan, Basique clip

However, during the pandemic some behaviors started to appear: some people went under lockdown when they knew about their disease. Others, tired of restrictions, avoided testing centers and went to as many parties as possible. Finally, some friends with important jobs and a nice but capitalist heart tried to respect the lockdown but took the plane to join a big meeting if their job asked them to.

So I designed 4 different agents to mimic these behaviors.

Self lockdown and testing centers

First of all, I replaced all the humans with law-abiding humans: if they become aware of their infection they are trying to avoid other humans. In a more accurate description, they are looking at all the cells they could move to and choose the one where there are as few humans as possible. This way they limit the number of interactions and the chances to spread the disease. However, they won’t discover by themselves that they are infected, in order to mimic a real infection as much as possible.

So I added some kind of medic. Their job is to warn people of the disease and thus make them go in self lockdown. In order to be efficient and test as many people as possible, I chose to make the medic try to touch as many people as possible (This is the exact opposite of self lockdown). They are represented by a tiny red cross. And in the simulation the infected but in lockdown humans are yellow. This is an example of a result.

infection probability 10%, death probability 0,5%, medic percentage 5%

Ok so this behaviour change had a drastic impact on the evolution, as long as they are not many cases medic and lockdown are able to slow the infection a lot (peak is reached at turn 200 here) and in many simulations, they are able to stop the infection entirely. However when the number of cases reach a threshold, medics are overwhelmed and we can see an evolution closer to the previous ones.

Party Monsters

After the second lockdown, some people became really tired and switched their behaviour radically. They wanted to enjoy life as much as possible to compensate for the lost year. In order to do so, they started to see a lot of people and tried to attend as many parties as possible.

We will call them party monsters and we will define their behaviour like this. Each turn a party monster tries to move to a position that allows him to see as much humans as possible. (This is the same movement as a medic when they look for people)

infection probability 10%, death probability 0,5%, party monsters 25%

In this simulation I made 10% of the population chose this behaviour. Compared to our first experience we can see the infection is way quicker: the peak is reached at turn 50 and not 100. We can also see some stairs in the infection number evolution when a cluster of party monsters is infected.

Business Men

The first behaviors I added were a bit extreme, so I wanted to add a more subtle one after this. The idea of businessmen came from 2 reasons. Firstly it is inspired by a friend of mine: he wanted to respect the lockdown whenever it was possible, but from time to time he had a really important meeting and felt he couldn’t skip it. So he took the plane and fly there. Secondly, since the beginning, the infection is growing from one point of the grid in a wave fashion, centered around the starting point. By allowing humans to move fastly around the whole grid I wanted to see if this pattern could be broken.

The precise behaviour of a Business Man is the following: most of the time he is a basic human and follows the random movement or the lockdown one if he is aware of the disease. However, from time to time (Arbitrarily 5% of the time), its job asks him to join an important meeting. In that case, he moves by plane to a new random position of the grid.

infection probability 10%, death probability 0,5%, businessmen 50%

As we can see it really speeds up the infection by creating a new starting point all over the grid. The peak point is, as for party monsters, really sped up (Turn 60 here). Except for this acceleration, the graph is following the same trend as the initial one.

The Grand Finale

Let’s mix all these people together and try to see if trends emerge.

Medic 5%, Party Monsters 25%, Business Man 50%

This simulation is a bit hard to follow with so much information all over the place. It’s also a bit messy to conclude anything on this since evolution changes a lot each time I hit the play button. But it’s fun and it was the primary goal of this all project.

Conclusion

As always in a fun personal project answering 2 questions create 10 new ideas. However, displaying them all in this article would be a bit painful to read, so I will write 2 other articles to detail the new ideas of this project.

The 2 main tracks I want to follow now are: try to have more robust results to be able to draw a real conclusion on it and not be fooled by variance, so I want to be able to run 100 simulations with the same initial parameters and see the average of 100 runs. On the other hand, one of the biggest issues with viruses is their extraordinary skills of mutation and I want to add this notion in the simulation.

I hope you had fun with all the graphs. If you have questions or ideas of new behaviour or parameters to change or graph to plot, please share them with me.

Thanks a lot to Edouard who gave me the initial idea of this project.

Louis And Cécile for the team Bricolle

--

--

Louis Nicolle

I am a French freelance developper, don’t hesitate to call me if you need help.