func (p *Particle) Move(gbest *optim.Point, vmax []float64, inertia, social, cognition float64) { // update velocity for i, currv := range p.Vel { // random numbers r1 and r2 MUST go inside this loop and be generated // uniquely for each dimension of p's velocity. r1 := optim.RandFloat() r2 := optim.RandFloat() p.Vel[i] = inertia*currv + cognition*r1*(p.Best.Pos[i]-p.Pos[i]) + social*r2*(gbest.Pos[i]-p.Pos[i]) if math.Abs(p.Vel[i]) > vmax[i] { p.Vel[i] = math.Copysign(vmax[i], p.Vel[i]) } } // update position for i := range p.Pos { p.Pos[i] += p.Vel[i] } p.Val = math.Inf(1) }
// NewPopulation initializes a population of particles using the given points // and generates velocities for each dimension i initialized to uniform random // values between minv[i] and maxv[i]. github.com/rwcarlsen/optim.Rand is // used for random numbers. func NewPopulation(points []*optim.Point, vmax []float64) Population { pop := make(Population, len(points)) for i, p := range points { pop[i] = &Particle{ Id: i, Point: p, Best: p.Clone(), Vel: make([]float64, len(vmax)), } for j, v := range vmax { pop[i].Vel[j] = v * (1 - 2*optim.RandFloat()) } } return pop }