87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
// Copyright 2023 wanderer <a_mirre at utb dot cz>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package ga
|
|
|
|
// mutation strategies iota consts.
|
|
|
|
const (
|
|
best1Exp = iota
|
|
rand1Exp
|
|
randtoBest1Exp
|
|
)
|
|
|
|
// mutations.
|
|
|
|
func clipVals(mutant []float64) []float64 {
|
|
for i := range mutant {
|
|
switch {
|
|
case mutant[i] < 0:
|
|
mutant[i] = 0
|
|
|
|
case mutant[i] > 1:
|
|
mutant[i] = 1
|
|
}
|
|
}
|
|
|
|
return mutant
|
|
}
|
|
|
|
// mutate performs the mutation of choice and returns the mutant.
|
|
func mutate(mutStrategy int, currentIndividual PopulationIndividual, genChamp ChampionIndividual, pop *Population, donors ...PopulationIndividual) []float64 {
|
|
var mutant []float64
|
|
|
|
dim := pop.Dimen
|
|
curF := pop.CurF
|
|
champ := genChamp.X
|
|
curX := currentIndividual.CurX
|
|
|
|
switch mutStrategy {
|
|
case best1Exp:
|
|
mutant = mutBest1Exp(dim, curF, champ, donors...)
|
|
|
|
case rand1Exp:
|
|
mutant = mutRand1Exp(dim, curF, donors...)
|
|
|
|
case randtoBest1Exp:
|
|
mutant = mutRandtoBest1Exp(dim, curF, champ, curX, donors...)
|
|
default:
|
|
return nil
|
|
}
|
|
|
|
// return mutant with values clipped to <0;1>.
|
|
return clipVals(mutant)
|
|
}
|
|
|
|
func mutBest1Exp(dim int, curF float64, champ []float64, donors ...PopulationIndividual) []float64 {
|
|
mutant := make([]float64, dim)
|
|
|
|
for i := 0; i < dim; i++ {
|
|
// mutant[i] = curF + (bestF*(donors[1].CurX[i]) - donors[2].CurX[i])
|
|
mutant[i] = champ[i] + (curF*(donors[1].CurX[i]) - donors[2].CurX[i])
|
|
}
|
|
|
|
return mutant
|
|
}
|
|
|
|
func mutRand1Exp(dim int, curF float64, donors ...PopulationIndividual) []float64 {
|
|
mutant := make([]float64, dim)
|
|
|
|
for i := 0; i < dim; i++ {
|
|
// tmp[n] = popold[r1][n] + curF*(popold[r2][n]-popold[r3][n]);
|
|
mutant[i] = donors[0].CurX[i] + curF*(donors[1].CurX[i]-donors[2].CurX[i])
|
|
}
|
|
|
|
return mutant
|
|
}
|
|
|
|
func mutRandtoBest1Exp(dim int, curF float64, champ, currentIndividual []float64, donors ...PopulationIndividual) []float64 {
|
|
mutant := make([]float64, dim)
|
|
|
|
for i := 0; i < dim; i++ {
|
|
mutant[i] += currentIndividual[i] + (curF*champ[i] - currentIndividual[i]) + (curF * (donors[0].CurX[i] - donors[1].CurX[i]))
|
|
}
|
|
|
|
return mutant
|
|
}
|