Title: Simulate mosquito populations in C#
A team of researchers at the Imperial College London are trying a new approach to mosquito control. They've genetically modified male mosquitoes to produce offspring who are 95% male. After a few generations, the number of females in the population declines sharply and the whole population crashes. (Click here to read more.)
I built this example to simulate a mosquito population that contains some modified mosquitos. It's not completely realistic, but it gives a pretty good idea of what's happening.
The program uses the following variables to track the populations of female, normal male, and modified male mosquitoes.
// The generation number.
private int GenerationNumber = 0;
// The population limit.
private double PopulationLimit;
// The current numbers of each kind of mosquito.
private int NumFemales = -1, NumRegularMales,
NumModifiedMales, EggsPerClutch;
When you click the Start button, the following code executes.
// Start or stop the simulation.
private void btnStart_Click(object sender, EventArgs e)
{
tmrGeneration.Interval = int.Parse(txtInterval.Text);
tmrGeneration.Enabled = !tmrGeneration.Enabled;
if (tmrGeneration.Enabled)
{
// We just started.
btnStart.Text = "Stop";
}
else
{
// We just stopped.
btnStart.Text = "Start";
}
}
This code toggles the tmrGeneration timer's Enabled property. If the timer is running, the code sets the button's text to Stop. If the timer isn't running, the program sets the button's code to Start.
The following code does the more interesting work when the timer's Tick event fires.
// Simulate a generation.
private void tmrGeneration_Tick(object sender, EventArgs e)
{
// See if we need to start a new run.
if (NumFemales == -1) ResetData();
// Display the generation number.
GenerationNumber++;
lblGeneration.Text = "Gen: " + GenerationNumber;
// Breed.
double prob_regular = NumRegularMales /
(double)(NumRegularMales + NumModifiedMales);
Random rand = new Random();
int num_baby_females = 0;
int num_baby_regular_males = 0;
int num_baby_modified_males = 0;
for (int i = 0; i < NumFemales; i++)
{
// See if this female finds a regular male.
if (rand.NextDouble() < prob_regular)
{
// A regular male.
num_baby_females += EggsPerClutch / 2;
num_baby_regular_males += EggsPerClutch / 2;
}
else
{
// A modified male.
num_baby_females += (int)(EggsPerClutch * 0.05);
num_baby_modified_males += (int)(EggsPerClutch * 0.95);
}
}
// Update the totals.
NumFemales = num_baby_females;
NumRegularMales = num_baby_regular_males;
NumModifiedMales = num_baby_modified_males;
// Reduce to the population limit.
double total_population = NumFemales +
NumRegularMales + NumModifiedMales;
if (total_population > PopulationLimit)
{
NumFemales = (int)(PopulationLimit *
NumFemales / total_population);
NumRegularMales = (int)(PopulationLimit *
NumRegularMales / total_population);
NumModifiedMales = (int)(PopulationLimit *
NumModifiedMales / total_population);
}
// Display the current values.
DisplayCurrentValues();
}
Initially the NumFemales variable is set to -1 to indicate that a simulation is not running. The Tick event handler checks whether NumFemales is -1 and calls the ResetData method if it is. (That method simply reads the initial values you entered into the form's text boxes. It's straightforward so it isn't shown here.)
Next the code increments and displays the generation number.
The program then assumes that each female will breed with a randomly selected male. It uses the number of regular and modified males to calculate the probability that a randomly selected male will be regular.
The code loops through the females to simulate their breeding. For each female, the program generates a random number between 0 and 1. If that number is less than the probability of picking a regular male, the female mates with a regular male and produces half females and half regular males. If the random number is greater than the probability of picking a regular male, the female mates with a modified male and produces 5% females and 95% modified males.
After it has found the numbers of new mosquitoes, the program updates the main count variables. (This is a bit unrealistic here. It assumes the adults die after breeding once, which is not true. In particular the females can live for several weeks and reproduce several times.)
Next if the total population of mosquitoes exceeds the limit you entered, the program reduces the numbers of mosquitoes in each group proportionally. (Again this isn't completely realistic. It's here to take into account the fact that mosquitoes die off at roughly the same rate they are born. If that weren't true, then we'd all be knee deep in mosquitoes in a matter of days.)
Finally the Tick event handler calls the DisplayCurrentValues method to display the current population values. (That method is straightforward so it isn't shown here.)
While this simulation is rather simplistic, it does show the effect fairly well. If the population includes even a single modified male, and that male successfully breeds, the modified males dominate and crash the population in only 10 or 12 generations.
Download the example to experiment with it and to see additional details.
|