81 lines
1.6 KiB
Go
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))
|
|
}
|