func main() { seed := time.Now().UTC().UnixNano() rand.Seed(seed) fmt.Println("Using seed:", seed) // Test expr // The initialization function creates a tree with specified max depth // And it's a closure over the primitives exprInit := func(maxDep int) *node.Node { return node.MakeTreeHalfAndHalf(maxDep, expr.Functionals, expr.Terminals) } exprMutate := node.MakeSubtreeMutation(MAX_D, exprInit) fmt.Println("Testing representation: expr") exprErrorAvg, exprErrorVar := testRepr(exprInit, exprMutate, expr.Draw) fmt.Println("expr error avg:", exprErrorAvg, "var:", exprErrorVar) // Test ts tsInit := func(maxDep int) *node.Node { return node.MakeTreeHalfAndHalf(maxDep, ts.Functionals, ts.Terminals) } tsMutate := node.MakeSubtreeMutation(MAX_D, tsInit) fmt.Println("Testing representation: TS") tsErrorAvg, tsErrorVar := testRepr(tsInit, tsMutate, ts.Draw) fmt.Println("TS error avg:", tsErrorAvg, "var:", tsErrorVar) // Test vhs vhsInit := func(maxDep int) *node.Node { return node.MakeTreeHalfAndHalf(maxDep, vhs.Functionals, vhs.Terminals) } vhsMutate := node.MakeSubtreeMutation(MAX_D, vhsInit) fmt.Println("Testing representation: VHS") vhsErrorAvg, vhsErrorVar := testRepr(vhsInit, vhsMutate, vhs.Draw) fmt.Println("VHS error avg:", vhsErrorAvg, "var:", vhsErrorVar) }
func (s *Solution) Mutate() { subtrMut := node.MakeSubtreeMutation(s.Conf.MaxDepth, func(maxDep int) *node.Node { return node.MakeTreeHalfAndHalf(maxDep, s.Conf.Functionals, s.Conf.Terminals) }) subtrMut(s.Node) }
func makeMultiMutation(s *base.Settings, multiMut, enbSin, enbNod, enbSub, enbAre, enbLsubt, enbLoc bool) func(float64, *base.Individual) bool { // La mutazione a che profondità avviene? // Quanto è profondo l'albero che vado a generare? // Quanto è profondo l'albero che vado a sostituire? // Separare foglie e nodi countInt := func(name string, v int) { if _, ok := s.IntCounters[name]; !ok { s.IntCounters[name] = new(counter.IntCounter) } s.IntCounters[name].Count(v) } countBool := func(name string, v bool) { if _, ok := s.Counters[name]; !ok { s.Counters[name] = new(counter.BoolCounter) } s.Counters[name].Count(v) } statFuncSin := func(nDepth, replDepth int, isLeaf bool) { countInt(mut_single_node_depth, nDepth) countInt(mut_single_node_repld, replDepth) countBool(mut_single_node_leaves, isLeaf) } statFuncNod := func(nDepth, replDepth int, isLeaf bool) { countInt(mut_multi_node_depth, nDepth) countInt(mut_multi_node_repld, replDepth) countBool(mut_multi_node_leaves, isLeaf) } statFuncTree := func(nDepth, replDepth int, isLeaf bool) { countInt(mut_tree_node_depth, nDepth) countInt(mut_tree_node_repld, replDepth) countBool(mut_tree_node_leaves, isLeaf) } statFuncArea := func(nDepth, replDepth int, isLeaf bool) { countInt(mut_area_node_depth, nDepth) countInt(mut_area_node_repld, replDepth) countBool(mut_area_node_leaves, isLeaf) } statFuncLevSubtr := func(nDepth, replDepth int, isLeaf bool) { countInt(mut_lsubt_node_depth, nDepth) countInt(mut_lsubt_node_repld, replDepth) countBool(mut_lsubt_node_leaves, isLeaf) } singleMut := node.MakeTreeSingleMutation(s.Functionals, s.Terminals, statFuncSin) // func(*Node) nodeMut := node.MakeTreeNodeMutation(s.Functionals, s.Terminals, statFuncNod) // funcs, terms []gp.Primitive)// func(*Node) int { subtrMut := node.MakeSubtreeMutation(s.MaxDepth, s.GenFunc, statFuncTree) areaMut := node.MakeSubtreeMutationGuided(s.MaxDepth, s.GenFunc, node.ArityDepthProbComputer, statFuncArea) subtLevelMut := node.MakeSubtreeMutationGuided(s.MaxDepth, s.GenFunc, node.UniformDepthProbComputer, statFuncLevSubtr) const neighbSize = 5 // Neighborhood size for local search return func(pMut float64, ind *base.Individual) bool { perm := rand.Perm(6) // Randomly permutate the algorithms to pick evCount := 0 // Number of events (mutations performed) for _, v := range perm { event := rand.Float64() < pMut // Perform mutation? switch v { case 0: if enbSin { ind.CountEvent(mut_single_event, event) if event { evCount++ fit := ind.Evaluate() singleMut(ind.Node) newFit := ind.Evaluate() ind.CountEvent(mut_single_improv, s.BetterThan(newFit, fit)) } if !multiMut { return event } } case 1: if enbNod { fit := ind.Evaluate() event = nodeMut(pMut, ind.Node) != 0 ind.CountEvent(mut_multi_event, event) if event { evCount++ newFit := ind.Evaluate() ind.CountEvent(mut_multi_improv, s.BetterThan(newFit, fit)) } if !multiMut { return event } } case 2: if enbSub { ind.CountEvent(mut_tree_event, event) if event { evCount++ fit := ind.Evaluate() subtrMut(ind.Node) newFit := ind.Evaluate() ind.CountEvent(mut_tree_improv, s.BetterThan(newFit, fit)) } if !multiMut { return event } } case 3: if enbAre { ind.CountEvent(mut_area_event, event) if event { evCount++ fit := ind.Evaluate() areaMut(ind.Node) newFit := ind.Evaluate() ind.CountEvent(mut_area_improv, s.BetterThan(newFit, fit)) } if !multiMut { return event } } case 4: if enbLsubt { ind.CountEvent(mut_lsubt_event, event) if event { evCount++ fit := ind.Evaluate() subtLevelMut(ind.Node) newFit := ind.Evaluate() ind.CountEvent(mut_lsubt_improv, s.BetterThan(newFit, fit)) } if !multiMut { return event } } default: if enbLoc { // Local search ind.CountEvent(mut_local_event, event) if event { evCount++ fit := ind.Evaluate() for i := 0; i < neighbSize; i++ { mutated := ind.Copy().(*base.Individual) // Copy individual singleMut(mutated.Node) // Apply mutation if s.BetterThan(mutated.Fitness(), ind.Fitness()) { // If improved, save the individual ind.Node = mutated.Node // Invalidate! ind.Invalidate() } } // Perform singleMut K times newFit := ind.Evaluate() ind.CountEvent(mut_local_improv, s.BetterThan(newFit, fit)) } if !multiMut { return event } } } // In the case we don't execute anything, go to the next method } // If this happens, all the mutations were disabled, or all the mutations // were performed when multi mutation was enabled if multiMut { countInt(mut_count_multi, evCount) } return evCount > 0 } }