// 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 Evolve(current evo.Genome, matingPool []evo.Genome) evo.Genome { // Selection: // Select each parent using a simple random binary tournament mom := sel.BinaryTournament(matingPool...).(*tsp) dad := sel.BinaryTournament(matingPool...).(*tsp) // Crossover: // Edge recombination child := &tsp{gene: pool.Get().([]int)} perm.EdgeX(child.gene, mom.gene, dad.gene) // Mutation: // There is an n% chance for the gene to have n random swaps // and an n% chance to undergo n steps of a greedy 2-opt hillclimber for rand.Float64() < 0.1 { perm.RandSwap(child.gene) } for rand.Float64() < 0.1 { child.TwoOpt() } // Replacement: // Only replace if the child is better or equal if current.Fitness() > child.Fitness() { return current } return child }
// 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 (g *Genome) Evolve(suitors ...evo.Genome) evo.Genome { // Creation: child := &Genome{} // Crossover: mom := sel.BinaryTournament(suitors...).(*Genome) dad := sel.BinaryTournament(suitors...).(*Genome) child.UniformX(&mom.Siam, &dad.Siam) // Mutation: for chance := rand.Float64(); chance < 0.2; chance = rand.Float64() { child.Mutate() } // Replacement: return child }
func TestBinaryTournament(t *testing.T) { var stats evo.Stats pop := dummies() for i := 0; i < 1e6; i++ { winner := sel.BinaryTournament(pop...).(dummy) stats = stats.Put(float64(winner)) } if stats.Mean() < 5.5 || 6.5 < stats.Mean() { t.Fail() } }