// 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. A global // selector object synchronises replacement among the parallel parents. func (ack *ackley) Evolve(suitors ...evo.Genome) evo.Genome { for i := 0; i < 7; i++ { // Creation: // We create the child genome from recycled memory when we can. var child ackley child.gene = vectors.Get().(real.Vector) child.steps = vectors.Get().(real.Vector) // Crossover: // Select two parents at random. // Uniform crossover of object parameters. // Arithmetic crossover of strategy parameters. mom := suitors[rand.Intn(len(suitors))].(*ackley) dad := suitors[rand.Intn(len(suitors))].(*ackley) real.UniformX(child.gene, mom.gene, dad.gene) real.ArithX(1, child.steps, mom.steps, dad.steps) // Mutation: Evolution Strategy // Lognormal scaling of strategy parameters. // Gausian perturbation of object parameters. child.steps.Adapt() child.steps.LowBound(precision) child.gene.Step(child.steps) child.gene.HighBound(bounds) child.gene.LowBound(-bounds) // Replacement: (40,280) // Each child is added to the global selection pool. selector.Put(&child) } // Finally, block until all parallel calls have added their children to the // selection pool and return one of the selected replacements. return selector.Get() }
func TestUniformX(t *testing.T) { mom := real.Random(8, 1) dad := real.Random(8, 1) child := make([]float64, 8) real.UniformX(child, mom, dad) for i := range child { if child[i] != mom[i] && child[i] != dad[i] { t.Fail() } } }