// 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 }
func TestRandSwap(t *testing.T) { a := rand.Perm(8) b := make([]int, 8) copy(b, a) perm.RandSwap(b) swapped := false i, j := 0, 7 for { if j <= i { if !swapped { t.Fail() } return } else if a[i] == b[i] { i++ } else if a[j] == b[j] { j-- } else { if swapped { t.Fail() return } b[i], b[j] = b[j], b[i] swapped = true } } }