math-optim/algo/ga/somat3aMigration.go
leo 74109521b0
All checks were successful
continuous-integration/drone/push Build is passing
ga: implement SOMA T3A algorithm
2023-02-21 23:51:52 +01:00

81 lines
1.6 KiB
Go

// Copyright 2023 wanderer <a_mirre at utb dot cz>
// 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))
}