The key part of the simulator is the inner loop that builds a new
generation
from the current generation
.
Recall that the current generation will be represented by an
array named g, and the next generation by an array ng.
Let
be the number of individuals in g. In the early
stages of the simulation
will be the same as
, the carrying
capacity, since all individuals in a new generation will survive. Toward
the end of the simulation
will be smaller than
.
Recall also that on average each individual is able to reproduce
times,
where
is reproductive factor, another one of the input parameters.
A population of
individuals will thus produce, on average,
offspring.
To create
the next generation, we need to simulate the creation of
individuals, add new mutations to the individuals,
and then select
random survivors to form the new
generation. If the number of survivors is less than
, then all
survivors go into the new generation. Extinction will occur when
none of the
new offspring survive.
is often very large compared to
; in the extreme cases
is 2 and
is
. In these situations it does
not make sense to create all
potential offspring only
to draw
at random to fill up the new generation. Instead,
we use a loop that iterates a maximum of
times
and exit the loop as soon as
survivors are found. Note that
during the meltdown phase fewer than
offspring will survive
to form the next generation and the loop will exit after generating
all potential offspring.
The outline of the build_next_generation procedure is:
limit = n * r; /* max number of iterations */
for (i = 0; i < limit; i++) {
j = random() % n; /* select a random parent */
mom = g[j];
kid = mom + poisson(mu); /* kid is a clone of mom */
if (survivor(kid)) { /* plus new mutations */
ng[nkids] = kid;
nkids = nkids + 1;
if (nkids == k) /* exit loop if the new gen */
break; /* now has k individuals */
}
}
The procedure call survivor(kid) will compute the relative
fitness of the child, compare it to a random number, and return
1 (true) if the child survives.