// Copyright 2023 wanderer // SPDX-License-Identifier: GPL-3.0-or-later package ga import ( "git.dotya.ml/wanderer/math-optim/bench/cec2020" ) // migration is used in SOMA-type algos. func (p *SOMAT3APopulation) migrate(leader int, migrants []int) { for _, i := range migrants { jumps := make([][]float64, p.Njumps) // jump zero. // jumps[0] = p.jump(i, leader, getStep(0, maxFES)) // bestJump of this migrant is now the jump zero. // bestJump := jumps[0] for j := 0; j < p.Njumps; j++ { step := p.getStep() jump := p.jump(i, leader, step) p.fes += 2 jumps[j] = jump } p.Population[i].Jumps = jumps p.Population[i].PRTVector = p.getPrtVector() } p.PRT = p.getPrt() } func (p *SOMAT3APopulation) jump(migrant, leader int, step float64) []float64 { m := p.Population[migrant] l := p.Population[leader] prtv := m.PRTVector t := step jumpPosition := make([]float64, len(m.CurX)) for i := range m.CurX { jumpPosition[i] = m.CurX[i] + ((l.CurX[i] - m.CurX[i]) * t * prtv[i]) } return jumpPosition } // getPrtVector creates and returns the perturbation vector. func (p *SOMAT3APopulation) getPrtVector() []float64 { prtv := make([]float64, p.Dimen) for i := range prtv { r := p.zeroToOneRNG.Rand() switch { case r < p.PRT: prtv[i] = 1 case r > p.PRT: prtv[i] = 0 } } return prtv } // getPrt calculates the adaptive PRT. func (p *SOMAT3APopulation) getPrt() float64 { return 0.05 + 0.9*float64(p.fes/cec2020.GetMaxFES(p.Dimen)) } // getStep calculates the step size. func (p *SOMAT3APopulation) getStep() float64 { return 0.15 + 0.08*float64(p.fes/cec2020.GetMaxFES(p.Dimen)) }