// EvolveOneGroup evolves one group (CPU) func (o *Optimiser) EvolveOneGroup(cpu int) (nfeval int) { // auxiliary G := o.Groups[cpu].All // competitors (old and new) I := o.Groups[cpu].Indices P := o.Groups[cpu].Pairs // compute random pairs rnd.IntGetGroups(P, I) np := len(P) // create new solutions z := o.Groups[cpu].Ncur // index of first new solution for k := 0; k < np; k++ { l := (k + 1) % np m := (k + 2) % np n := (k + 3) % np A := G[P[k][0]] A0 := G[P[l][0]] A1 := G[P[m][0]] A2 := G[P[n][0]] B := G[P[k][1]] B0 := G[P[l][1]] B1 := G[P[m][1]] B2 := G[P[n][1]] a := G[z+P[k][0]] b := G[z+P[k][1]] if o.Nflt > 0 { DiffEvol(a.Flt, A.Flt, A0.Flt, A1.Flt, A2.Flt, &o.Parameters) DiffEvol(b.Flt, B.Flt, B0.Flt, B1.Flt, B2.Flt, &o.Parameters) } if o.Nint > 0 { o.CxInt(a.Int, b.Int, A.Int, B.Int, &o.Parameters) o.MtInt(a.Int, &o.Parameters) o.MtInt(b.Int, &o.Parameters) } if o.BinInt > 0 && o.ClearFlt { for i := 0; i < o.Nint; i++ { if a.Int[i] == 0 { a.Flt[i] = 0 } if b.Int[i] == 0 { b.Flt[i] = 0 } } } o.ObjFunc(a, cpu) o.ObjFunc(b, cpu) nfeval += 2 } // metrics o.Groups[cpu].Metrics.Compute(G) // tournaments for k := 0; k < np; k++ { A := G[P[k][0]] B := G[P[k][1]] a := G[z+P[k][0]] b := G[z+P[k][1]] o.Tournament(A, B, a, b, o.Groups[cpu].Metrics) } return }
// Solve solves optimisation problem func (o *Optimiser) Solve() { // benchmark if o.Verbose { t0 := gotime.Now() defer func() { io.Pf("\nnfeval = %d\n", o.Nfeval) io.Pfblue2("cpu time = %v\n", gotime.Now().Sub(t0)) }() } // output if o.Output != nil { o.Output(0, o.Solutions) } // perform evolution done := make(chan int, o.Ncpu) time := 0 texc := time + o.DtExc for time < o.Tf { // run groups in parallel. up to exchange time for icpu := 0; icpu < o.Ncpu; icpu++ { go func(cpu int) { nfeval := 0 for t := time; t < texc; t++ { if cpu == 0 && o.Verbose { io.Pf("time = %10d\r", t+1) } nfeval += o.EvolveOneGroup(cpu) } done <- nfeval }(icpu) } for cpu := 0; cpu < o.Ncpu; cpu++ { o.Nfeval += <-done } // compute metrics with all solutions included o.Metrics.Compute(o.Solutions) // exchange via tournament if o.Ncpu > 1 { if o.ExcTour { for i := 0; i < o.Ncpu; i++ { j := (i + 1) % o.Ncpu I := rnd.IntGetUnique(o.Groups[i].Indices, 2) J := rnd.IntGetUnique(o.Groups[j].Indices, 2) A, B := o.Groups[i].All[I[0]], o.Groups[i].All[I[1]] a, b := o.Groups[j].All[J[0]], o.Groups[j].All[J[1]] o.Tournament(A, B, a, b, o.Metrics) } } // exchange one randomly if o.ExcOne { rnd.IntGetGroups(o.cpupairs, utl.IntRange(o.Ncpu)) for _, pair := range o.cpupairs { i, j := pair[0], pair[1] n := utl.Imin(o.Groups[i].Ncur, o.Groups[j].Ncur) k := rnd.Int(0, n) A := o.Groups[i].All[k] B := o.Groups[j].All[k] B.CopyInto(o.tmp) A.CopyInto(B) o.tmp.CopyInto(A) } } } // update time variables time += o.DtExc texc += o.DtExc time = utl.Imin(time, o.Tf) texc = utl.Imin(texc, o.Tf) // output if o.Output != nil { o.Output(time, o.Solutions) } } }