Example #1
0
// 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
}
Example #2
0
// 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
}
Example #3
0
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
}
Example #4
0
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()
	}
}