// Evolve implements the inner loop of the evolutionary algorithm. // The population calls the Evolve method of each genome, in parallel. Then, // each receiver returns a value to replace it in the next generation. func (q *queens) Evolve(matingPool ...evo.Genome) evo.Genome { // Crossover: // We're implementing a diffusion model. For each member of the population, // we receive a small mating pool containing only our neighbors. We choose // a mate using a random binary tournament and create a child with // partially mapped crossover. mate := sel.BinaryTournament(matingPool...).(*queens) child := &queens{gene: pool.Get().([]int)} perm.PMX(child.gene, q.gene, mate.gene) // Mutation: // Perform n random swaps where n is taken from an exponential distribution. mutationCount := math.Ceil(rand.ExpFloat64() - 0.5) for i := float64(0); i < mutationCount; i++ { j := rand.Intn(len(child.gene)) k := rand.Intn(len(child.gene)) child.gene[j], child.gene[k] = child.gene[k], child.gene[j] } // Replacement: // Only replace if the child is better or equal. if q.Fitness() > child.Fitness() { return q } return child }
func TestPMX(t *testing.T) { mom := rand.Perm(8) dad := rand.Perm(8) child := make([]int, 8) perm.PMX(child, mom, dad) validate(t, child) }