func ExampleModel() { gp.SetSeed(1) pset := gp.CreatePrimSet(1, "x") pset.Add(num.Add, num.Sub, num.Mul, num.Div, num.Neg, num.V(0), num.V(1)) problem := gp.Model{ PrimitiveSet: pset, Generator: gp.GenFull(pset, 1, 3), PopSize: 500, Fitness: getFitness, Offspring: gp.Tournament(3), Mutate: gp.MutUniform(gp.GenGrow(pset, 0, 2)), MutateProb: 0.2, Crossover: gp.CxOnePoint(), CrossoverProb: 0.5, Threads: 1, } logger := &stats.Logger{MaxGen: 20, TargetFitness: 0.99, PrintStats: true} problem.Run(logger) // Output: // set random seed: 1 // Gen Evals FitMax FitAvg FitStd SizeAvg SizeMax DepthAvg DepthMax // 0 500 0.12 0.025 0.014 6.85 15 1.96 3 // 1 299 0.33 0.0344 0.0204 6.33 27 1.93 6 // 2 286 0.663 0.0469 0.0448 6.26 27 1.9 7 // 3 265 0.663 0.0598 0.0683 6.58 34 2.06 9 // 4 280 0.663 0.0772 0.088 7.51 39 2.39 9 // 5 291 0.663 0.0918 0.1 8.92 32 2.82 8 // 6 302 0.663 0.117 0.133 10.3 35 3.2 10 // 7 294 1 0.152 0.17 11.1 35 3.48 10 // ** SUCCESS ** }
func Example_gp() { // create initial population gp.SetSeed(1) pset := gp.CreatePrimSet(1, "x") pset.Add(num.Add, num.Sub, num.Mul, num.Div, num.Neg, num.V(0), num.V(1)) generator := gp.GenFull(pset, 1, 3) pop, evals := gp.CreatePopulation(500, generator).Evaluate(eval{}, 1) best := pop.Best() fmt.Printf("gen=%d evals=%d fit=%.4f\n", 0, evals, best.Fitness) // setup genetic variations tournament := gp.Tournament(3) mutate := gp.MutUniform(gp.GenGrow(pset, 0, 2)) crossover := gp.CxOnePoint() // loop till reach target fitness or exceed no. of generations for gen := 1; gen <= 40 && best.Fitness < 1; gen++ { offspring := tournament.Select(pop, len(pop)) pop, evals = gp.VarAnd(offspring, crossover, mutate, 0.5, 0.2).Evaluate(eval{}, 1) best = pop.Best() fmt.Printf("gen=%d evals=%d fit=%.4f\n", gen, evals, best.Fitness) } fmt.Println(best.Code.Format()) // Output: // set random seed: 1 // gen=0 evals=500 fit=0.1203 // gen=1 evals=299 fit=0.3299 // gen=2 evals=286 fit=0.6633 // gen=3 evals=265 fit=0.6633 // gen=4 evals=280 fit=0.6633 // gen=5 evals=291 fit=0.6633 // gen=6 evals=302 fit=0.6633 // gen=7 evals=294 fit=1.0000 // (x + (((x / 1) - ((x / 1) * -(((x * x) + x)))) * (1 * x))) }
// build and run model func main() { // get options var maxSize, maxDepth int var trailFile string flag.IntVar(&maxSize, "size", 0, "maximum tree size - zero for none") flag.IntVar(&maxDepth, "depth", 0, "maximum tree depth - zero for none") flag.StringVar(&trailFile, "trail", "santafe_trail.txt", "trail definition file") opts := util.DefaultOptions util.ParseFlags(&opts) // create primitive set config := readTrail(trailFile) pset := gp.CreatePrimSet(0) pset.Add(progN{&gp.BaseFunc{"prog2", 2}}) pset.Add(progN{&gp.BaseFunc{"prog3", 3}}) pset.Add(ifFood{&gp.BaseFunc{"if_food", 2}}) pset.Add(Terminal("left", turn(-1))) pset.Add(Terminal("right", turn(1))) pset.Add(Terminal("step", step)) // setup model problem := &gp.Model{ PrimitiveSet: pset, Generator: gp.GenFull(pset, 1, 2), PopSize: opts.PopSize, Fitness: fitnessFunc(config), Offspring: gp.Tournament(opts.TournSize), Mutate: gp.MutUniform(gp.GenFull(pset, 0, 2)), MutateProb: opts.MutateProb, Crossover: gp.CxOnePoint(), CrossoverProb: opts.CrossoverProb, Threads: opts.Threads, } if maxDepth > 0 { problem.AddDecorator(gp.DepthLimit(maxDepth)) } if maxSize > 0 { problem.AddDecorator(gp.SizeLimit(maxSize)) } problem.PrintParams("== Artificial ant ==") logger := stats.NewLogger(opts.MaxGen, opts.TargetFitness) if opts.Verbose { logger.OnDone = func(best *gp.Individual) { ant := run(config, best.Code) fmt.Println(ant.grid) } } // run if opts.Plot { logger.RegisterSVGPlot("best", createPlot(config, 500, 10)) stats.MainLoop(problem, logger, ":8080", "../web") } else { fmt.Println() logger.PrintStats = true logger.PrintBest = opts.Verbose problem.Run(logger) } }
// main GP routine func main() { opts := util.DefaultOptions util.ParseFlags(&opts) pset := gp.CreatePrimSet(PARITY_FANIN) pset.Add(boolean.And, boolean.Or, boolean.Xor, boolean.Not, boolean.True, boolean.False) problem := &gp.Model{ PrimitiveSet: pset, Generator: gp.GenFull(pset, 3, 5), PopSize: opts.PopSize, Fitness: getFitnessFunc(), Offspring: gp.Tournament(opts.TournSize), Mutate: gp.MutUniform(gp.GenGrow(pset, 0, 2)), MutateProb: opts.MutateProb, Crossover: gp.CxOnePoint(), CrossoverProb: opts.CrossoverProb, Threads: opts.Threads, } problem.PrintParams("== Even parity problem for", PARITY_FANIN, "inputs ==") logger := stats.NewLogger(opts.MaxGen, opts.TargetFitness) if opts.Plot { stats.MainLoop(problem, logger, ":8080", "../web") } else { fmt.Println() logger.PrintStats = true logger.PrintBest = opts.Verbose problem.Run(logger) } }
// setup primitive set func initPset(all bool) *gp.PrimSet { pset := gp.CreatePrimSet(2, "x", "y") pset.Add(Add, Sub, Mul, Div, Neg) if all { pset.Add(V(42), Sqr, Rand, Floor) } return pset }
func getStats(t *testing.T, gen int) *Stats { pset := gp.CreatePrimSet(1, "x") pset.Add(num.Add, num.Sub, num.Mul, num.Div, num.Neg, num.V(0), num.V(1)) pop := gp.CreatePopulation(1000, gp.GenFull(pset, 1, 3)) for i := range pop { pop[i].Fitness = rand.Float64() } s := Create(pop, gen, len(pop)) t.Log(s) return s }
// main GP routine func main() { // get options var maxSize, maxDepth int var dataFile string flag.IntVar(&maxSize, "size", 0, "maximum tree size - zero for none") flag.IntVar(&maxDepth, "depth", 0, "maximum tree depth - zero for none") flag.StringVar(&dataFile, "trainset", "poly.dat", "file with training function") opts := util.DefaultOptions util.ParseFlags(&opts) // create primitive set ercMin, ercMax, trainSet := getData(dataFile) pset := gp.CreatePrimSet(1, "x") pset.Add(num.Add, num.Sub, num.Mul, num.Div) pset.Add(num.Ephemeral("ERC", ercGen(ercMin, ercMax))) // setup model problem := &gp.Model{ PrimitiveSet: pset, Generator: gp.GenRamped(pset, 1, 3), PopSize: opts.PopSize, Fitness: fitnessFunc(trainSet), Offspring: gp.Tournament(opts.TournSize), Mutate: gp.MutUniform(gp.GenGrow(pset, 0, 2)), MutateProb: opts.MutateProb, Crossover: gp.CxOnePoint(), CrossoverProb: opts.CrossoverProb, Threads: opts.Threads, } if maxDepth > 0 { problem.AddDecorator(gp.DepthLimit(maxDepth)) } if maxSize > 0 { problem.AddDecorator(gp.SizeLimit(maxSize)) } problem.PrintParams("== GP Symbolic Regression for ", dataFile, "==") // run logger := stats.NewLogger(opts.MaxGen, opts.TargetFitness) if opts.Plot { gp.GraphDPI = "60" logger.RegisterPlot("graph", plotTarget(trainSet), plotBest(trainSet)) stats.MainLoop(problem, logger, ":8080", "../web") } else { fmt.Println() logger.PrintStats = true logger.PrintBest = opts.Verbose problem.Run(logger) } }
// test evaluating some simple expressions func TestEval(t *testing.T) { pset := gp.CreatePrimSet(2, "A", "B") pset.Add(True, False, And, Or, Xor, Not) exprs := []gp.Expr{ {Xor, And, True, False, Or, True, False, True}, {And, pset.Var(0), Not, pset.Var(1)}, } val := exprs[0].Eval(False, False) t.Log(exprs[0], exprs[0].Format(), " => ", val) if val != True { t.Errorf("Eval(%s) = %v", exprs[0], val) } input := []pair{{False, False}, {False, True}, {True, False}, {True, True}} for i, expect := range []gp.Value{False, False, True, False} { val := exprs[1].Eval(input[i].A, input[i].B) t.Log("input:", input[i], exprs[1].Format(), "->", val) if val != expect { t.Errorf("Eval(%s) = %v", exprs[1], val) } } }
// build and run model func main() { // get options var maxSize, maxDepth int var configFile string flag.IntVar(&maxSize, "size", 0, "maximum tree size - zero for none") flag.IntVar(&maxDepth, "depth", 0, "maximum tree depth - zero for none") flag.StringVar(&configFile, "config", "desert.txt", "grid definition file") opts := util.DefaultOptions util.ParseFlags(&opts) // create primitive set grid := readGrid(configFile) pset := gp.CreatePrimSet(0) pset.Add(Terminal("x", func(ant *Ant) int { return ant.col })) pset.Add(Terminal("y", func(ant *Ant) int { return ant.row })) pset.Add(Terminal("carrying", func(ant *Ant) int { return ant.carrying })) pset.Add(Terminal("color", func(ant *Ant) int { return ant.grid.cells[ant.row][ant.col].color })) pset.Add(Terminal("go-n", move(0))) pset.Add(Terminal("go-e", move(1))) pset.Add(Terminal("go-s", move(2))) pset.Add(Terminal("go-w", move(3))) pset.Add(Terminal("go-rand", func(ant *Ant) int { return move(ant.grid.rng.Intn(4))(ant) })) pset.Add(Terminal("pickup", pickUp)) pset.Add(IfElse("iflte", 4, ifLessThanOrEqual)) pset.Add(IfElse("ifltz", 3, ifLessThanZero)) pset.Add(IfElse("ifdrop", 2, ifDrop)) // setup model problem := &gp.Model{ PrimitiveSet: pset, Generator: gp.GenFull(pset, 1, 2), PopSize: opts.PopSize, Fitness: fitnessFunc(grid), Offspring: gp.Tournament(opts.TournSize), Mutate: gp.MutUniform(gp.GenFull(pset, 0, 2)), MutateProb: opts.MutateProb, Crossover: gp.CxOnePoint(), CrossoverProb: opts.CrossoverProb, Threads: opts.Threads, } if maxDepth > 0 { problem.AddDecorator(gp.DepthLimit(maxDepth)) } if maxSize > 0 { problem.AddDecorator(gp.SizeLimit(maxSize)) } problem.PrintParams("== Artificial ant ==") logger := stats.NewLogger(opts.MaxGen, opts.TargetFitness) if opts.Verbose { logger.OnDone = func(best *gp.Individual) { g, _ := run(grid, best.Code) fmt.Println(g) } } // run if opts.Plot { logger.RegisterSVGPlot("best", createPlot(grid, 500, 40)) stats.MainLoop(problem, logger, ":8080", "../web") } else { fmt.Println() logger.PrintStats = true logger.PrintBest = opts.Verbose problem.Run(logger) } }