next up previous

5.3 Death from Fixed Mutations     continued...

To put this observation into practice, we can cut down on the number of iterations of the main loop in build_next_generation. The unoptimized code is

  limit = n * r;
  for (i = 0; i < limit; i++) {
    mom = random() % n;
    dad = random() % n;
    mate(g[mom],g[dad],ng[nkids]);
    nm = poisson(mu);
    if (survivor(g[nkids]),nm) {
      add_mutations(g[nkids],nm);
      nkids += 1;
      if (nkids == K)
        break;
    }
  }
Since we know that some portion of the new offspring will die from fixed mutations, we can use a smaller value for limit. If the percentage of individuals who will survive the fixed mutations is p, then it is only necessary to create potential offspring.

The technique is to draw a random number from a binomial distribution with and number of trials equal to :

  limit = binomial(pow(1-2*s,nf),n*r);
  for (i = 0; i < limit; i++) {
    mom = random() % n;
    ...
  }
The binomial number generator is used in situations like this where we want to estimate the number of occurrences of n events, each of which occurs with probability p. In this case, the number of events is n*r (the number of offspring created) and the probability that any one survives nf fixed mutations is . A binomial random number generator can be found in Numerical Recipes [3].

Since the effects of fixed mutations are already taken into account when setting the value of limit, they need to be taken out of the fitness function in calls to survivior(). In other words, we need to edit the fitness function so it uses , the health according to segregating mutations. Note that this is simply the original fitness function before we introduced the ``garbage collection'' optimization and the use of the nf counter.