func Test_mtdeb01(tst *testing.T) { //verbose() chk.PrintTitle("mtdeb01. Deb's mutation") var ops OpsData ops.SetDefault() ops.Pm = 1.0 ops.Xrange = [][]float64{{-3, 3}, {-4, 4}} ops.EnfRange = true rnd.Init(0) A := []float64{-1, 1} io.Pforan("before: A = %v\n", A) FltMutationDeb(A, 10, &ops) io.Pforan("after: A = %v\n", A) ha0 := rnd.Histogram{Stations: utl.LinSpace(-3, 3, 11)} nsamples := 1000 aa := make([]float64, len(A)) a0s := make([]float64, nsamples) for _, t := range []int{0, 50, 100} { for i := 0; i < nsamples; i++ { copy(aa, A) FltMutationDeb(aa, t, &ops) a0s[i] = aa[0] } ha0.Count(a0s, true) io.Pf("\ntime = %d\n", t) io.Pf("%s", rnd.TextHist(ha0.GenLabels("%.1f"), ha0.Counts, 60)) } }
func Test_ind01(tst *testing.T) { //verbose() chk.PrintTitle("ind01. representation and copying") rnd.Init(0) nbases := 3 A := get_individual(0, nbases) B := A.GetCopy() chk.Scalar(tst, "ova0", 1e-17, B.Ovas[0], 123) chk.Scalar(tst, "ova1", 1e-17, B.Ovas[1], 345) chk.Scalar(tst, "oor0", 1e-17, B.Oors[0], 10) chk.Scalar(tst, "oor1", 1e-17, B.Oors[1], 20) chk.Scalar(tst, "oor2", 1e-17, B.Oors[2], 30) fmts := map[string][]string{"int": {" %d"}, "flt": {" %.1f"}, "str": {" %q"}, "key": {" %x"}, "byt": {" %q"}, "fun": {" %q"}} oA := A.Output(fmts, false) oB := B.Output(fmts, false) io.Pfyel("\n%v\n", oA) io.Pfyel("%v\n\n", oB) chk.String(tst, oA, " 1 20 300 4.4 5.5 666.0 \"abc\" \"b\" \"c\" 53 47 41 \"ABC\" \"DEF\" \"GHI\" \"f0\" \"f1\" \"f2\"") chk.String(tst, oB, " 1 20 300 4.4 5.5 666.0 \"abc\" \"b\" \"c\" 53 47 41 \"ABC\" \"DEF\" \"GHI\" \"f0\" \"f1\" \"f2\"") A.SetFloat(1, 33) A.SetFloat(2, 88) oA = A.Output(fmts, false) io.Pfyel("\n%v\n", oA) chk.String(tst, oA, " 1 20 300 4.4 33.0 88.0 \"abc\" \"b\" \"c\" 53 47 41 \"ABC\" \"DEF\" \"GHI\" \"f0\" \"f1\" \"f2\"") }
func Test_binmut01(tst *testing.T) { //verbose() chk.PrintTitle("binmut01. mutation: binary") var ops OpsData ops.SetDefault() ops.Pm = 1.0 ops.Tmax = 10 ops.Nchanges = 3 rnd.Init(0) A := []int{0, 1, 1, 1, 0, 0, 1, 0, 1, 1} a := make([]int, len(A)) copy(a, A) io.Pforan("before: A = %v\n", A) IntBinMutation(A, 0, &ops) io.Pforan("after: A = %v\n", A) ndiff := 0 for i := 0; i < len(A); i++ { if A[i] != a[i] { ndiff++ } } io.Pforan("number of changes = %v\n", ndiff) if ndiff != ops.Nchanges { tst.Errorf("binary mutation failed\n") } }
func Test_intordmut01(tst *testing.T) { //verbose() chk.PrintTitle("intordmut01") var ops OpsData ops.SetDefault() ops.Pm = 1 rnd.Init(0) a := []int{1, 2, 3, 4, 5, 6, 7, 8} io.Pforan("before: a = %v\n", a) ops.OrdSti = []int{2, 5, 4} IntOrdMutation(a, 0, &ops) io.Pfcyan("after: a = %v\n", a) chk.Ints(tst, "a", a, []int{1, 2, 6, 7, 3, 4, 5, 8}) nums := utl.IntRange2(1, 9) sort.Ints(a) chk.Ints(tst, "asorted = 12345678", a, nums) a = []int{1, 2, 3, 4, 5, 6, 7, 8} io.Pforan("\nbefore: a = %v\n", a) ops.OrdSti = nil IntOrdMutation(a, 0, &ops) io.Pfcyan("after: a = %v\n", a) sort.Ints(a) chk.Ints(tst, "asorted = 12345678", a, nums) }
func Test_pop02(tst *testing.T) { //verbose() chk.PrintTitle("pop02") rnd.Init(0) genes := [][]float64{ {1, 5}, // 0 {1, 3}, // 1 {5, 7}, // 2 {1, 2}, // 3 {2, 4}, // 4 {3, 6}, // 5 {4, 8}, // 6 {4, 6}, // 7 {1, 3}, // 8 {0, 0}, // 9 } // objective values, oor and demerits // 0 1 2 3 4 5 6 7 8 9 ovs := []float64{11, 21, 10, 12, 13, 31, 41, 11.1, 31.5, 11.5} dem := []float64{0.2, 0.7, 0.1, 0.5, 0.6, 0.8, 1.0, 0.3, 0.9, 0.4} // init population ninds := len(genes) nova := 1 noor := 0 nbases := 2 var pop Population pop = make([]*Individual, ninds) for i := 0; i < ninds; i++ { pop[i] = NewIndividual(nova, noor, nbases, genes[i]) pop[i].Ovas[0] = ovs[i] pop[i].Demerit = dem[i] } pop.Sort() genes_sorted := [][]float64{ {5, 7}, // 2 {1, 5}, // 0 {4, 6}, // 7 {0, 0}, // 9 {1, 2}, // 3 {2, 4}, // 4 {1, 3}, // 1 {3, 6}, // 5 {1, 3}, // 8 {4, 8}, // 6 } for i, ind := range pop { for j := 0; j < ind.Nfltgenes; j++ { chk.Scalar(tst, io.Sf("i%dg%d", i, j), 1e-14, ind.GetFloat(j), genes_sorted[i][j]) } } }
func main() { // GA parameters C := goga.ReadConfParams("tsp-simple.json") rnd.Init(C.Seed) // location / coordinates of stations locations := [][]float64{ {60, 200}, {180, 200}, {80, 180}, {140, 180}, {20, 160}, {100, 160}, {200, 160}, {140, 140}, {40, 120}, {100, 120}, {180, 100}, {60, 80}, {120, 80}, {180, 60}, {20, 40}, {100, 40}, {200, 40}, {20, 20}, {60, 20}, {160, 20}, } nstations := len(locations) C.SetIntOrd(nstations) C.CalcDerived() // objective value function C.OvaOor = func(ind *goga.Individual, idIsland, time int, report *bytes.Buffer) { L := locations ids := ind.Ints dist := 0.0 for i := 1; i < nstations; i++ { a, b := ids[i-1], ids[i] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) } a, b := ids[nstations-1], ids[0] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) ind.Ovas[0] = dist return } // evolver nova, noor := 1, 0 evo := goga.NewEvolver(nova, noor, C) evo.Run() // results io.Pfgreen("best = %v\n", evo.Best.Ints) io.Pfgreen("best OVA = %v (871.117353844847)\n\n", evo.Best.Ovas[0]) // plot travelling salesman path if C.DoPlot { plt.SetForEps(1, 300) X, Y := make([]float64, nstations), make([]float64, nstations) for k, id := range evo.Best.Ints { X[k], Y[k] = locations[id][0], locations[id][1] plt.PlotOne(X[k], Y[k], "'r.', ms=5, clip_on=0, zorder=20") plt.Text(X[k], Y[k], io.Sf("%d", id), "fontsize=7, clip_on=0, zorder=30") } plt.Plot(X, Y, "'b-', clip_on=0, zorder=10") plt.Plot([]float64{X[0], X[nstations-1]}, []float64{Y[0], Y[nstations-1]}, "'b-', clip_on=0, zorder=10") plt.Equal() plt.AxisRange(10, 210, 10, 210) plt.Gll("$x$", "$y$", "") plt.SaveD("/tmp/goga", "test_evo04.eps") } }
func Test_ind02(tst *testing.T) { //verbose() chk.PrintTitle("ind02. copy into") rnd.Init(0) nbases := 1 A := get_individual(0, nbases) B := get_individual(1, nbases) fmts := map[string][]string{ "int": {"%2d", "%4d", "%5d"}, // ints "flt": {"%6g", "%6g", "%5g"}, // floats "str": {"%4s", "%2s", "%2s"}, // strings "key": {"%3x", "%3x", "%3x"}, // keys "byt": {"%4s", "%4s", "%4s"}, // bytes "fun": {"%3s", "%3s", "%3s"}, // funcs } io.Pfpink("A = %v\n", A.Output(fmts, false)) io.Pfcyan("B = %v\n", B.Output(fmts, false)) var ops OpsData ops.SetDefault() ops.Pc = 1.0 ops.Cuts = []int{1, 2} ops.Xrange = [][]float64{{0, 1}, {-20, 20}, {-300, 300}} a := A.GetCopy() b := A.GetCopy() IndCrossover(a, b, A, B, 0, &ops) io.Pforan("a = %v\n", a.Output(fmts, false)) io.Pfblue2("b = %v\n", b.Output(fmts, false)) chk.Ints(tst, "a.Ints ", a.Ints, []int{1, -20, 300}) chk.Ints(tst, "b.Ints ", b.Ints, []int{-1, 20, -300}) chk.Strings(tst, "a.Strings", a.Strings, []string{"abc", "Y", "c"}) chk.Strings(tst, "b.Strings", b.Strings, []string{"X", "b", "Z"}) // TODO: add other tests here io.Pf("\n") x := get_individual(0, nbases) x.Ovas = []float64{0, 0} x.Oors = []float64{0, 0, 0} io.Pfblue2("x = %v\n", x.Output(fmts, false)) B.CopyInto(x) chk.Scalar(tst, "ova0", 1e-17, x.Ovas[0], 200) chk.Scalar(tst, "ova1", 1e-17, x.Ovas[1], 100) chk.Scalar(tst, "oor0", 1e-17, x.Oors[0], 15) chk.Scalar(tst, "oor1", 1e-17, x.Oors[1], 25) chk.Scalar(tst, "oor2", 1e-17, x.Oors[2], 35) io.Pforan("x = %v\n", x.Output(fmts, false)) chk.String(tst, x.Output(fmts, false), B.Output(fmts, false)) }
func Test_pop03(tst *testing.T) { //verbose() chk.PrintTitle("pop03") rnd.Init(0) C := NewConfParams() C.NumInts = 7 pop := PopBinGen(0, C) io.Pforan("%v\n", pop.Output(C)) }
func Test_cxdeb01(tst *testing.T) { //verbose() chk.PrintTitle("cxdeb01. Deb's crossover") var ops OpsData ops.SetDefault() ops.Pc = 1.0 ops.Xrange = [][]float64{{-3, 3}, {-4, 4}} ops.EnfRange = true rnd.Init(0) A := []float64{-1, 1} B := []float64{1, 2} a := make([]float64, len(A)) b := make([]float64, len(A)) FltCrossoverDeb(a, b, A, B, 0, &ops) io.Pforan("A = %v\n", A) io.Pforan("B = %v\n", B) io.Pfcyan("a = %.6f\n", a) io.Pfcyan("b = %.6f\n", b) nsamples := 1000 a0s, a1s := make([]float64, nsamples), make([]float64, nsamples) b0s, b1s := make([]float64, nsamples), make([]float64, nsamples) for i := 0; i < nsamples; i++ { FltCrossoverDeb(a, b, B, A, 0, &ops) a0s[i], a1s[i] = a[0], a[1] b0s[i], b1s[i] = b[0], b[1] } ha0 := rnd.Histogram{Stations: []float64{-4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5, 0, 0.5, 1}} hb0 := rnd.Histogram{Stations: []float64{0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 5.5, 6}} ha1 := rnd.Histogram{Stations: utl.LinSpace(-4, 4, 11)} hb1 := rnd.Histogram{Stations: utl.LinSpace(-4, 4, 11)} ha0.Count(a0s, true) hb0.Count(b0s, true) ha1.Count(a1s, true) hb1.Count(b1s, true) io.Pforan("\na0s\n") io.Pf("%s", rnd.TextHist(ha0.GenLabels("%.1f"), ha0.Counts, 60)) io.Pforan("b0s\n") io.Pf("%s", rnd.TextHist(hb0.GenLabels("%.1f"), hb0.Counts, 60)) io.Pforan("\na1s\n") io.Pf("%s", rnd.TextHist(ha1.GenLabels("%.1f"), ha1.Counts, 60)) io.Pforan("b1s\n") io.Pf("%s", rnd.TextHist(hb1.GenLabels("%.1f"), hb1.Counts, 60)) }
func Test_simplechromo01(tst *testing.T) { //verbose() chk.PrintTitle("simplechromo01") rnd.Init(0) nbases := 2 for i := 0; i < 10; i++ { chromo := SimpleChromo([]float64{1, 10, 100}, nbases) io.Pforan("chromo = %v\n", chromo) chk.IntAssert(len(chromo), 3*nbases) chk.Scalar(tst, "gene0", 1e-14, chromo[0]+chromo[1], 1) chk.Scalar(tst, "gene1", 1e-14, chromo[2]+chromo[3], 10) chk.Scalar(tst, "gene2", 1e-13, chromo[4]+chromo[5], 100) } }
func Test_ends02(tst *testing.T) { //verbose() chk.PrintTitle("ends02") rnd.Init(0) size := 20 ncuts := 10 nsamples := 100 hist := rnd.IntHistogram{Stations: utl.IntRange(size + 3)} for i := 0; i < nsamples; i++ { ends := GenerateCxEnds(size, ncuts, nil) hist.Count(ends, false) } io.Pf("%s\n", rnd.TextHist(hist.GenLabels("%d"), hist.Counts, 60)) }
func Test_mwicz01(tst *testing.T) { //verbose() chk.PrintTitle("mwicz01. Michalewicz mutation") var ops OpsData ops.SetDefault() ops.Pm = 1.0 ops.Tmax = 10 rnd.Init(0) ops.Xrange = [][]float64{{0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}} T := utl.IntRange(int(ops.Tmax)) for _, t := range T { io.Pf("t=%v Δ=%v\n", t, ops.MwiczDelta(float64(t), 1)) } for _, t := range T { A := []float64{0, 1, 2, 3, 4} FltMutationMwicz(A, t, &ops) io.Pforan("A = %.8f\n", A) } if chk.Verbose { b := 2.0 f := func(r, tb float64) float64 { return math.Pow(r, math.Pow(1.0-tb, b)) } np := 21 r, tb := utl.MeshGrid2D(0, 1, 0, 1, np, np) // tb = t/tmax z := la.MatAlloc(np, np) for i := 0; i < np; i++ { for j := 0; j < np; j++ { z[i][j] = f(r[i][j], tb[i][j]) } } plt.Surface(tb, r, z, "linewidth=0.8") plt.Gll("tb", "r", "") plt.SaveD("/tmp/goga", "test_mwicz01.eps") //plt.Show() } }
func Test_flt01(tst *testing.T) { //verbose() chk.PrintTitle("flt01. quadratic with inequalities") // parameters C := NewConfParams() C.Pll = false C.Nisl = 1 C.Ninds = 12 C.GAtype = "crowd" C.CrowdSize = 3 C.DiffEvol = true C.RangeFlt = [][]float64{ {-2, 2}, // gene # 0: min and max {-2, 2}, // gene # 1: min and max } C.PopFltGen = PopFltGen if chk.Verbose { C.DoPlot = chk.Verbose } C.CalcDerived() rnd.Init(C.Seed) // functions fcn := func(f, g, h []float64, x []float64) { f[0] = x[0]*x[0]/2.0 + x[1]*x[1] - x[0]*x[1] - 2.0*x[0] - 6.0*x[1] g[0] = 2.0 - x[0] - x[1] // ≥ 0 g[1] = 2.0 + x[0] - 2.0*x[1] // ≥ 0 g[2] = 3.0 - 2.0*x[0] - x[1] // ≥ 0 g[3] = x[0] // ≥ 0 g[4] = x[1] // ≥ 0 } // simple problem sim := NewSimpleFltProb(fcn, 1, 5, 0, C) sim.Run(chk.Verbose) // plot sim.Plot("test_flt01") }
func Test_blx01(tst *testing.T) { //verbose() chk.PrintTitle("blx01. blended crossover") var ops OpsData ops.SetDefault() ops.Pc = 1.0 ops.Xrange = [][]float64{{-1, 2}, {0, 3}, {1, 4}, {3, 6}, {4, 7}} rnd.Init(0) A := []float64{0, 1, 2, 4, 5} B := []float64{1, 2, 3, 5, 6} a := make([]float64, len(A)) b := make([]float64, len(A)) FltCrossoverBlx(a, b, A, B, 0, &ops) io.Pforan("A = %v\n", A) io.Pforan("B = %v\n", B) io.Pfcyan("a = %v\n", a) io.Pfcyan("b = %v\n", b) }
func Test_flt03(tst *testing.T) { //verbose() chk.PrintTitle("flt03. sin⁶(5 π x) multimodal") // configuration C := NewConfParams() C.Nova = 1 C.Noor = 2 C.Nisl = 4 C.Ninds = 24 C.GAtype = "crowd" C.DiffEvol = true C.CrowdSize = 3 C.ParetoPhi = 0.01 C.CompProb = true C.Tf = 100 C.Dtmig = 60 C.RangeFlt = [][]float64{{0, 0.9999999999999}} C.PopFltGen = PopFltGen C.CalcDerived() rnd.Init(C.Seed) // post-processing function values := utl.Deep3alloc(C.Tf/10, C.Nisl, C.Ninds) C.PostProc = func(idIsland, time int, pop Population) { if time%10 == 0 { k := time / 10 for i, ind := range pop { values[k][idIsland][i] = ind.GetFloat(0) } } } // functions yfcn := func(x float64) float64 { return math.Pow(math.Sin(5.0*math.Pi*x), 6.0) } fcn := func(f, g, h []float64, x []float64) { f[0] = -yfcn(x[0]) } // simple problem sim := NewSimpleFltProb(fcn, 1, 0, 0, C) sim.Run(chk.Verbose) // write histograms and plot if chk.Verbose { // write histograms var buf bytes.Buffer hist := rnd.Histogram{Stations: utl.LinSpace(0, 1, 13)} for k := 0; k < C.Tf/10; k++ { for i := 0; i < C.Nisl; i++ { clear := false if i == 0 { clear = true } hist.Count(values[k][i], clear) } io.Ff(&buf, "\ntime=%d\n%v", k*10, rnd.TextHist(hist.GenLabels("%4.2f"), hist.Counts, 60)) } io.WriteFileVD("/tmp/goga", "test_flt03_hist.txt", &buf) // plot plt.SetForEps(0.8, 300) xmin := sim.Evo.Islands[0].Pop[0].GetFloat(0) xmax := xmin for k := 0; k < C.Nisl; k++ { for _, ind := range sim.Evo.Islands[k].Pop { x := ind.GetFloat(0) y := yfcn(x) xmin = utl.Min(xmin, x) xmax = utl.Max(xmax, x) plt.PlotOne(x, y, "'r.',clip_on=0,zorder=20") } } np := 401 X := utl.LinSpace(0, 1, np) Y := make([]float64, np) for i := 0; i < np; i++ { Y[i] = yfcn(X[i]) } plt.Plot(X, Y, "'b-',clip_on=0,zorder=10") plt.Gll("$x$", "$y$", "") plt.SaveD("/tmp/goga", "test_flt03_func.eps") } }
func Test_intordcx01(tst *testing.T) { //verbose() chk.PrintTitle("intordcx01") var ops OpsData ops.SetDefault() ops.Pc = 1 rnd.Init(0) A := []int{1, 2, 3, 4, 5, 6, 7, 8} B := []int{2, 4, 6, 8, 7, 5, 3, 1} a := make([]int, len(A)) b := make([]int, len(A)) ops.Cuts = []int{2, 5} IntOrdCrossover(a, b, A, B, 0, &ops) io.Pforan("A = %v\n", A) io.Pfblue2("B = %v\n", B) io.Pfgreen("a = %v\n", a) io.Pfyel("b = %v\n", b) chk.Ints(tst, "A", A, []int{1, 2, 3, 4, 5, 6, 7, 8}) chk.Ints(tst, "B", B, []int{2, 4, 6, 8, 7, 5, 3, 1}) chk.Ints(tst, "a", a, []int{4, 5, 6, 8, 7, 1, 2, 3}) chk.Ints(tst, "b", b, []int{8, 7, 3, 4, 5, 1, 2, 6}) sort.Ints(a) sort.Ints(b) nums := utl.IntRange2(1, 9) chk.Ints(tst, "asorted = 12345678", a, nums) chk.Ints(tst, "bsorted = 12345678", b, nums) A = []int{1, 3, 5, 7, 6, 2, 4, 8} B = []int{5, 6, 3, 8, 2, 1, 4, 7} ops.Cuts = []int{3, 6} IntOrdCrossover(a, b, A, B, 0, &ops) io.Pforan("\nA = %v\n", A) io.Pfblue2("B = %v\n", B) io.Pfgreen("a = %v\n", a) io.Pfyel("b = %v\n", b) chk.Ints(tst, "A", A, []int{1, 3, 5, 7, 6, 2, 4, 8}) chk.Ints(tst, "B", B, []int{5, 6, 3, 8, 2, 1, 4, 7}) chk.Ints(tst, "a", a, []int{5, 7, 6, 8, 2, 1, 4, 3}) chk.Ints(tst, "b", b, []int{3, 8, 1, 7, 6, 2, 4, 5}) sort.Ints(a) sort.Ints(b) chk.Ints(tst, "asorted = 12345678", a, nums) chk.Ints(tst, "bsorted = 12345678", b, nums) A = []int{1, 2, 3, 4, 5, 6, 7, 8} B = []int{2, 4, 6, 8, 7, 5, 3, 1} ops.Cuts = []int{} IntOrdCrossover(a, b, A, B, 0, &ops) io.Pforan("\nA = %v\n", A) io.Pfblue2("B = %v\n", B) io.Pfgreen("a = %v\n", a) io.Pfyel("b = %v\n", b) sort.Ints(a) sort.Ints(b) chk.Ints(tst, "asorted = 12345678", a, nums) chk.Ints(tst, "bsorted = 12345678", b, nums) C := []int{1, 2, 3} D := []int{3, 1, 2} c := make([]int, len(C)) d := make([]int, len(D)) IntOrdCrossover(c, d, C, D, 0, &ops) io.Pforan("\nC = %v\n", C) io.Pfblue2("D = %v\n", D) io.Pfgreen("c = %v\n", c) io.Pfyel("d = %v\n", d) chk.Ints(tst, "c", c, []int{2, 1, 3}) chk.Ints(tst, "d", d, []int{1, 2, 3}) sort.Ints(c) sort.Ints(d) chk.Ints(tst, "csorted = 123", c, []int{1, 2, 3}) chk.Ints(tst, "dsorted = 123", d, []int{1, 2, 3}) }
// CalcDerived computes derived variables and checks consistency func (o *Parameters) CalcDerived() { // check if o.Nova < 1 { chk.Panic("number of objective values (nova) must be greater than 0") } if o.Nsol < 6 { chk.Panic("number of solutions must greater than 6. Nsol = %d is invalid", o.Nsol) } if o.Ncpu < 2 { o.Ncpu = 1 o.Pll = false o.DtExc = 1 } if o.Ncpu > o.Nsol/2 { chk.Panic("number of CPU must be smaller than or equal to half the number of solutions. Ncpu=%d > Nsol/2=%d", o.Ncpu, o.Nsol/2) } if o.Tf < 1 { o.Tf = 1 } if o.DtExc < 1 { o.DtExc = o.Tf / 10 } if o.DtOut < 1 { o.DtOut = o.Tf / 5 } // derived o.Nflt = len(o.FltMin) o.Nint = len(o.IntMin) if o.BinInt > 0 { o.Nint = o.BinInt } if o.Nflt == 0 && o.Nint == 0 { chk.Panic("either floats and ints must be set (via FltMin/Max or IntMin/Max)") } // floats if o.Nflt > 0 { chk.IntAssert(len(o.FltMax), o.Nflt) o.DelFlt = make([]float64, o.Nflt) for i := 0; i < o.Nflt; i++ { o.DelFlt[i] = o.FltMax[i] - o.FltMin[i] } } // mesh if o.Nflt < 2 { o.UseMesh = false } if o.UseMesh { if o.Nbry < 2 { o.Nbry = 2 } o.NumXiXjPairs = (o.Nflt*o.Nflt - o.Nflt) / 2 o.NumXiXjBryPts = (o.Nbry-2)*4 + 4 o.NumExtraSols = o.NumXiXjPairs * o.NumXiXjBryPts io.PfYel("NumXiXjPairs=%d NumXiXjBryPts=%d NumExtraSols=%d\n", o.NumXiXjPairs, o.NumXiXjBryPts, o.NumExtraSols) o.Nsol += o.NumExtraSols } // generic ints if o.BinInt == 0 && o.Nint > 0 { chk.IntAssert(len(o.IntMax), o.Nint) o.DelInt = make([]int, o.Nint) for i := 0; i < o.Nint; i++ { o.DelInt[i] = o.IntMax[i] - o.IntMin[i] } } if o.Nint != o.Nflt { o.ClearFlt = false } // number of cuts and changes in ints if o.Nint > 0 { if o.IntNcuts > o.Nint { o.IntNcuts = o.Nint } if o.IntNchanges > o.Nint { o.IntNchanges = o.Nint } } // initialise random numbers generator rnd.Init(o.Seed) }
func Test_pop01(tst *testing.T) { //verbose() chk.PrintTitle("pop01") rnd.Init(0) // genes genes := [][]float64{ {1, 5, -200}, {1, 3, -300}, {5, 7, -400}, {1, 2, -500}, {2, 4, -300}, } // objective values and fitness values ovs := []float64{11, 21, 10, 12, 13} // init population ninds := len(genes) nova := 1 noor := 0 nbases := 2 var pop Population pop = make([]*Individual, ninds) for i := 0; i < ninds; i++ { pop[i] = NewIndividual(nova, noor, nbases, genes[i]) pop[i].Ovas[0] = ovs[i] } // check floats and subfloats for i, ind := range pop { for j := 0; j < ind.Nfltgenes; j++ { chk.Scalar(tst, io.Sf("before: i%dg%d", i, j), 1e-12, ind.GetFloat(j), genes[i][j]) } } // print bases io.Pf("\nbases (before)\n") io.Pf("%s\n", pop.OutFloatBases("%10.4f")) // change subfloats bases := [][]float64{ {10, 1, 14, 5, -10, -1}, {10, 1, 12, 1, -20, -1}, {10, 5, 12, 1, -30, -1}, {10, 1, 12, 2, -40, -1}, {10, 2, 11, 1, -20, -1}, } for i, b := range bases { copy(pop[i].Floats, b) } // print bases io.Pfyel("bases (after)\n") io.Pfyel("%s\n", pop.OutFloatBases("%4g")) // checkf floats chk.Scalar(tst, "after: i0g0", 1e-16, pop[0].GetFloat(0), 11) chk.Scalar(tst, "after: i0g1", 1e-16, pop[0].GetFloat(1), 19) chk.Scalar(tst, "after: i0g2", 1e-16, pop[0].GetFloat(2), -11) chk.Scalar(tst, "after: i1g0", 1e-16, pop[1].GetFloat(0), 11) chk.Scalar(tst, "after: i1g1", 1e-16, pop[1].GetFloat(1), 13) chk.Scalar(tst, "after: i1g2", 1e-16, pop[1].GetFloat(2), -21) chk.Scalar(tst, "after: i2g0", 1e-16, pop[2].GetFloat(0), 15) chk.Scalar(tst, "after: i2g1", 1e-16, pop[2].GetFloat(1), 13) chk.Scalar(tst, "after: i2g2", 1e-16, pop[2].GetFloat(2), -31) chk.Scalar(tst, "after: i3g0", 1e-16, pop[3].GetFloat(0), 11) chk.Scalar(tst, "after: i3g1", 1e-16, pop[3].GetFloat(1), 14) chk.Scalar(tst, "after: i3g2", 1e-16, pop[3].GetFloat(2), -41) chk.Scalar(tst, "after: i4g0", 1e-16, pop[4].GetFloat(0), 12) chk.Scalar(tst, "after: i4g1", 1e-16, pop[4].GetFloat(1), 12) chk.Scalar(tst, "after: i4g2", 1e-16, pop[4].GetFloat(2), -21) }
func Test_int01(tst *testing.T) { //verbose() chk.PrintTitle("int01. organise sequence of ints") io.Pf("\n") // initialise random numbers generator rnd.Init(0) // 0 => use current time as seed // parameters C := NewConfParams() C.Nova = 1 C.Noor = 0 C.Nisl = 1 C.Ninds = 20 C.RegTol = 0 C.NumInts = 20 //C.GAtype = "crowd" C.CrowdSize = 2 C.Tf = 50 C.Verbose = chk.Verbose C.CalcDerived() // mutation function C.Ops.MtInt = func(A []int, time int, ops *OpsData) { size := len(A) if !rnd.FlipCoin(ops.Pm) || size < 1 { return } pos := rnd.IntGetUniqueN(0, size, ops.Nchanges) for _, i := range pos { if A[i] == 1 { A[i] = 0 } if A[i] == 0 { A[i] = 1 } } } // generation function C.PopIntGen = func(id int, cc *ConfParams) Population { o := make([]*Individual, cc.Ninds) genes := make([]int, cc.NumInts) for i := 0; i < cc.Ninds; i++ { for j := 0; j < cc.NumInts; j++ { genes[j] = rand.Intn(2) } o[i] = NewIndividual(cc.Nova, cc.Noor, cc.Nbases, genes) } return o } // objective function C.OvaOor = func(ind *Individual, idIsland, time int, report *bytes.Buffer) { score := 0.0 count := 0 for _, val := range ind.Ints { if val == 0 && count%2 == 0 { score += 1.0 } if val == 1 && count%2 != 0 { score += 1.0 } count++ } ind.Ovas[0] = 1.0 / (1.0 + score) return } // run optimisation evo := NewEvolver(C) evo.Run() // results ideal := 1.0 / (1.0 + float64(C.NumInts)) io.PfGreen("\nBest = %v\nBestOV = %v (ideal=%v)\n", evo.Best.Ints, evo.Best.Ovas[0], ideal) }
func Test_int02(tst *testing.T) { //verbose() chk.PrintTitle("int02. TSP") // location / coordinates of stations locations := [][]float64{ {60, 200}, {180, 200}, {80, 180}, {140, 180}, {20, 160}, {100, 160}, {200, 160}, {140, 140}, {40, 120}, {100, 120}, {180, 100}, {60, 80}, {120, 80}, {180, 60}, {20, 40}, {100, 40}, {200, 40}, {20, 20}, {60, 20}, {160, 20}, } nstations := len(locations) // parameters C := NewConfParams() C.Nova = 1 C.Noor = 0 C.Nisl = 4 C.Ninds = 24 C.RegTol = 0.3 C.RegPct = 0.2 //C.Dtmig = 30 C.GAtype = "crowd" C.ParetoPhi = 0.1 C.Elite = false C.DoPlot = false //chk.Verbose //C.Rws = true C.SetIntOrd(nstations) C.CalcDerived() // initialise random numbers generator rnd.Init(0) // objective value function C.OvaOor = func(ind *Individual, idIsland, t int, report *bytes.Buffer) { L := locations ids := ind.Ints //io.Pforan("ids = %v\n", ids) dist := 0.0 for i := 1; i < nstations; i++ { a, b := ids[i-1], ids[i] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) } a, b := ids[nstations-1], ids[0] dist += math.Sqrt(math.Pow(L[b][0]-L[a][0], 2.0) + math.Pow(L[b][1]-L[a][1], 2.0)) ind.Ovas[0] = dist return } // evolver evo := NewEvolver(C) // print initial population pop := evo.Islands[0].Pop //io.Pf("\n%v\n", pop.Output(nil, false)) // 0,4,8,11,14,17,18,15,12,19,13,16,10,6,1,3,7,9,5,2 894.363 if false { for i, x := range []int{0, 4, 8, 11, 14, 17, 18, 15, 12, 19, 13, 16, 10, 6, 1, 3, 7, 9, 5, 2} { pop[0].Ints[i] = x } evo.Islands[0].CalcOvs(pop, 0) evo.Islands[0].CalcDemeritsAndSort(pop) } // check initial population ints := make([]int, nstations) if false { for i := 0; i < C.Ninds; i++ { for j := 0; j < nstations; j++ { ints[j] = pop[i].Ints[j] } sort.Ints(ints) chk.Ints(tst, "ints", ints, utl.IntRange(nstations)) } } // run evo.Run() //io.Pf("%v\n", pop.Output(nil, false)) io.Pfgreen("best = %v\n", evo.Best.Ints) io.Pfgreen("best OVA = %v (871.117353844847)\n\n", evo.Best.Ovas[0]) // best = [18 17 14 11 8 4 0 2 5 9 12 7 6 1 3 10 16 13 19 15] // best OVA = 953.4643474956656 // best = [8 11 14 17 18 15 12 19 16 13 10 6 1 3 7 9 5 2 0 4] // best OVA = 871.117353844847 // best = [5 2 0 4 8 11 14 17 18 15 12 19 16 13 10 6 1 3 7 9] // best OVA = 871.1173538448469 // best = [6 10 13 16 19 15 18 17 14 11 8 4 0 2 5 9 12 7 3 1] // best OVA = 880.7760751923065 // check final population if false { for i := 0; i < C.Ninds; i++ { for j := 0; j < nstations; j++ { ints[j] = pop[i].Ints[j] } sort.Ints(ints) chk.Ints(tst, "ints", ints, utl.IntRange(nstations)) } } // plot travelling salesman path if C.DoPlot { plt.SetForEps(1, 300) X, Y := make([]float64, nstations), make([]float64, nstations) for k, id := range evo.Best.Ints { X[k], Y[k] = locations[id][0], locations[id][1] plt.PlotOne(X[k], Y[k], "'r.', ms=5, clip_on=0, zorder=20") plt.Text(X[k], Y[k], io.Sf("%d", id), "fontsize=7, clip_on=0, zorder=30") } plt.Plot(X, Y, "'b-', clip_on=0, zorder=10") plt.Plot([]float64{X[0], X[nstations-1]}, []float64{Y[0], Y[nstations-1]}, "'b-', clip_on=0, zorder=10") plt.Equal() plt.AxisRange(10, 210, 10, 210) plt.Gll("$x$", "$y$", "") plt.SaveD("/tmp/goga", "test_evo04.eps") } }
func Test_flt02(tst *testing.T) { //verbose() chk.PrintTitle("flt02. circle with equality constraint") // parameters C := NewConfParams() C.Eps1 = 1e-3 C.Pll = false C.Nisl = 4 C.Ninds = 12 C.Ntrials = 1 if chk.Verbose { C.Ntrials = 40 } C.Verbose = false C.Dtmig = 50 C.CrowdSize = 3 C.CompProb = false C.GAtype = "crowd" C.DiffEvol = true C.RangeFlt = [][]float64{ {-1, 3}, // gene # 0: min and max {-1, 3}, // gene # 1: min and max } C.Latin = true C.PopFltGen = PopFltGen if chk.Verbose { C.FnKey = "" if C.Ntrials == 1 { C.DoPlot = true } } C.Ops.EnfRange = true C.NumFmts = map[string][]string{"flt": {"%8.4f", "%8.4f"}} C.ShowDem = true C.RegTol = 0.01 C.CalcDerived() rnd.Init(C.Seed) // geometry xe := 1.0 // centre of circle le := -0.4 // selected level of f(x) ys := xe - (1.0+le)/math.Sqrt2 // coordinates of minimum point with level=le y0 := 2.0*ys + xe // vertical axis intersect of straight line defined by c(x) xc := []float64{xe, xe} // centre nx := len(xc) // functions fcn := func(f, g, h []float64, x []float64) { res := 0.0 for i := 0; i < nx; i++ { res += (x[i] - xc[i]) * (x[i] - xc[i]) } f[0] = math.Sqrt(res) - 1 h[0] = x[0] + x[1] + xe - y0 } // simple problem sim := NewSimpleFltProb(fcn, 1, 0, 1, C) sim.Run(chk.Verbose) // stat io.Pf("\n") sim.Stat(0, 60, -0.4) // plot sim.PltExtra = func() { plt.PlotOne(ys, ys, "'o', markeredgecolor='yellow', markerfacecolor='none', markersize=10") } sim.Plot("test_flt02") }
func Test_flt04(tst *testing.T) { //verbose() chk.PrintTitle("flt04. two-bar truss. Pareto-optimal") // configuration C := NewConfParams() C.Nisl = 4 C.Ninds = 24 C.GAtype = "crowd" C.DiffEvol = true C.CrowdSize = 3 C.ParetoPhi = 0.05 C.Tf = 100 C.Dtmig = 25 C.RangeFlt = [][]float64{{0.1, 2.25}, {0.5, 2.5}} C.PopFltGen = PopFltGen C.CalcDerived() rnd.Init(C.Seed) // data // from Coelho (2007) page 19 ρ := 0.283 // lb/in³ H := 100.0 // in P := 1e4 // lb E := 3e7 // lb/in² σ0 := 2e4 // lb/in² // functions TSQ2 := 2.0 * math.Sqrt2 fcn := func(f, g, h []float64, x []float64) { f[0] = 2.0 * ρ * H * x[1] * math.Sqrt(1.0+x[0]*x[0]) f[1] = P * H * math.Pow(1.0+x[0]*x[0], 1.5) * math.Sqrt(1.0+math.Pow(x[0], 4.0)) / (TSQ2 * E * x[0] * x[0] * x[1]) g[0] = σ0 - P*(1.0+x[0])*math.Sqrt(1.0+x[0]*x[0])/(TSQ2*x[0]*x[1]) g[1] = σ0 - P*(1.0-x[0])*math.Sqrt(1.0+x[0]*x[0])/(TSQ2*x[0]*x[1]) } // objective value function C.OvaOor = func(ind *Individual, idIsland, t int, report *bytes.Buffer) { x := ind.GetFloats() f := make([]float64, 2) g := make([]float64, 2) fcn(f, g, nil, x) ind.Ovas[0] = f[0] ind.Ovas[1] = f[1] ind.Oors[0] = utl.GtePenalty(g[0], 0, 1) ind.Oors[1] = utl.GtePenalty(g[1], 0, 1) } // simple problem sim := NewSimpleFltProb(fcn, 2, 2, 0, C) sim.Run(chk.Verbose) // results if chk.Verbose { // reference data _, dat, _ := io.ReadTable("data/coelho-fig1.6.dat") // Pareto-front feasible := sim.Evo.GetFeasible() ovas, _ := sim.Evo.GetResults(feasible) ovafront, _ := sim.Evo.GetParetoFront(feasible, ovas, nil) xova, yova := sim.Evo.GetFrontOvas(0, 1, ovafront) // plot plt.SetForEps(0.75, 355) plt.Plot(dat["f1"], dat["f2"], "'k+',ms=3") x := utl.DblsGetColumn(0, ovas) y := utl.DblsGetColumn(1, ovas) plt.Plot(x, y, "'r.'") plt.Plot(xova, yova, "'ko',markerfacecolor='none',ms=6") plt.Gll("$f_1$", "$f_2$", "") plt.SaveD("/tmp/goga", "test_flt04.eps") } }
func Test_mut01(tst *testing.T) { //verbose() chk.PrintTitle("mut01") var ops OpsData ops.SetDefault() ops.Pm = 1 rnd.Init(0) A := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} ops.Nchanges = 3 ops.Mmax = 10 io.Pforan("before: A = %v\n", A) IntMutation(A, 0, &ops) io.Pforan("after: A = %v\n", A) io.Pf("\n") B := []float64{1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9} io.Pforan("before: B = %v\n", B) FltMutation(B, 0, &ops) io.Pforan("after: B = %v\n", B) io.Pf("\n") C := []string{"a", "b", "c", "d", "e", "f"} ops.Nchanges = 2 io.Pforan("before: C = %v\n", C) StrMutation(C, 0, &ops) io.Pforan("after: C = %v\n", C) io.Pf("\n") D := []byte("abcdefghijklm") ops.Nchanges = 3 io.Pforan("before: D = %s\n", D) KeyMutation(D, 0, &ops) io.Pforan("after: D = %s\n", D) io.Pf("\n") E := [][]byte{[]byte("abc"), []byte("def"), []byte("ghi"), []byte("jkl")} io.Pforan("before: E = %s\n", E) BytMutation(E, 0, &ops) io.Pforan("after: E = %s\n", E) io.Pf("\n") F := []Func_t{ func(o *Individual) string { return "f0" }, func(o *Individual) string { return "f1" }, func(o *Individual) string { return "f2" }, func(o *Individual) string { return "g0" }, func(o *Individual) string { return "g1" }, func(o *Individual) string { return "g2" }, } io.Pforan("before: F =") for _, f := range F { io.Pforan(" %q", f(nil)) } FunMutation(F, 0, &ops) io.Pforan("\nafter: F =") for _, f := range F { io.Pforan(" %q", f(nil)) } io.Pf("\n") io.Pf("\n") }