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))) }
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 }
// calc least squares difference and return as normalised fitness from 0->1 func (e eval) GetFitness(code gp.Expr) (float64, bool) { diff := 0.0 for x := -1.0; x <= 1.0; x += 0.1 { val := float64(code.Eval(num.V(x)).(num.V)) fun := x*x*x*x + x*x*x + x*x + x diff += (val - fun) * (val - fun) } return 1.0 / (1.0 + diff), true }
// returns function to calc least squares difference and return as normalised fitness from 0->1 func fitnessFunc(trainSet []Point) func(gp.Expr) (float64, bool) { return func(code gp.Expr) (float64, bool) { diff := 0.0 for _, pt := range trainSet { val := float64(code.Eval(num.V(pt.x)).(num.V)) diff += (val - pt.y) * (val - pt.y) } return 1.0 / (1.0 + diff), true } }
// function to plot best individual func plotBest(trainSet []Point) func(gp.Population) stats.Plot { return func(pop gp.Population) stats.Plot { plot := stats.NewPlot("Best", len(trainSet)) plot.Color = "#ff0000" code := pop.Best().Code for i, pt := range trainSet { plot.Data[i][0] = pt.x plot.Data[i][1] = float64(code.Eval(num.V(pt.x)).(num.V)) } return plot } }
// function to generate the random constant generator function func ercGen(start, end int) func() num.V { fmt.Println("generate random constants in range", start, "to", end) return func() num.V { return num.V(start + rand.Intn(end-start+1)) } }