// Copyright 2023 wanderer // SPDX-License-Identifier: GPL-3.0-or-later package cec2020 import "math" // BentCigar is the "Bent Cigar Function" of CEC2020. func BentCigar(x []float64) float64 { var sum float64 for i := 1; i < len(x); i++ { sum += math.Pow(x[i], 2) } return (1000000 * sum) + math.Pow(x[0], 2) } // Schwefel is the "Shifted and Rotated Schwefel's Function" of CEC2020. func Schwefel(x []float64) float64 { return SchwefelModified(x) } // LunacekBiRastrigin is the "Shifted and Rotated Lunacek bi-Rastrigin Function" of CEC2020. // ref: https://al-roomi.org/benchmarks/unconstrained/n-dimensions/229-lunacek-s-bi-rastrigin-function. func LunacekBiRastrigin(x []float64) float64 { var sum0 float64 var sum1 float64 var sum2 float64 nx := len(x) fnx := float64(nx) s := 1 - (1 / ((2 * math.Sqrt(fnx+20)) - 8.2)) d := 1.0 mu0 := 2.5 mu1 := -math.Sqrt((math.Pow(mu0, 2) - d) / s) xhat := getMean(x) for i := range x { sum0 += math.Pow(xhat-mu0, 2) sum1 += math.Pow(xhat-mu1, 2) zi := math.Pow(100, 0.5*((float64(i)-1)/fnx-1)) * xhat sum2 += (1 - math.Cos(2*math.Pi*zi)) } return math.Min(sum0, (d*fnx)+(s*sum1)) + 10*sum2 } // RosenbrockGriewank is the "Expanded Rosenbrock's plus Griewank's Function" // of CEC2020. func RosenbrockGriewank(x []float64) float64 { var sum float64 nx := len(x) for i := range x { f := []float64{x[i], x[(i+1)%nx]} sum += Griewank([]float64{Rosenbrock(f)}) } return sum } // Hybrid1 is the "Hybrid Function 1" of CEC2020. func Hybrid1(x []float64) float64 { nx := len(x) fnx := float64(nx) funcs := []func([]float64) float64{ SchwefelModified, Rastrigin, HighConditionedElliptic, } // percentages used to control the amount of contribution of each func. p := []float64{0.3, 0.3, 0.4} gnx := getGnx(p, fnx) var sum float64 for i := range funcs { sum += funcs[i](x) * gnx[i] } return sum } // Hybrid2 is the "Hybrid Function 2" of CEC2020. func Hybrid2(x []float64) float64 { nx := len(x) fnx := float64(nx) funcs := []func([]float64) float64{ SchafferExpanded, HGBat, Rosenbrock, SchwefelModified, } // percentages used to control the amount of contribution of each func. p := []float64{0.2, 0.2, 0.3, 0.3} gnx := getGnx(p, fnx) var sum float64 for i := range funcs { sum += funcs[i](x) * gnx[i] } return sum } // Hybrid3 is the "Hybrid Function 3" of CEC2020. func Hybrid3(x []float64) float64 { nx := len(x) fnx := float64(nx) funcs := []func([]float64) float64{ SchafferExpanded, HGBat, Rosenbrock, SchwefelModified, HighConditionedElliptic, } // percentages used to control the amount of contribution of each func. p := []float64{0.1, 0.2, 0.2, 0.2, 0.3} gnx := getGnx(p, fnx) var sum float64 for i := range funcs { sum += funcs[i](x) * gnx[i] } return sum } // Composition1 is the "Composition Function 1" of CEC2020. func Composition1(x []float64) float64 { nx := len(x) fnx := float64(nx) // optimum positions. o := newOpt(nx) sigma := []float64{10, 20, 30} lambda := []float64{1, 10, 1} bias := []float64{0, 100, 200} omega := make([]float64, nx) funcs := []func([]float64) float64{ Rastrigin, Griewank, SchwefelModified, } var sum float64 weights := make([]float64, len(funcs)) for i := range funcs { wi := getWeight(x, o, sigma[i], fnx) weights = append(weights, wi) var wsum float64 for j := range weights { wsum += weights[j] } omega = append(omega, wi/wsum) sum += (omega[i] * (lambda[i]*funcs[i](x) + bias[i])) + funcs[i](x) } return sum } // Composition2 is the "Composition Function 2" of CEC2020. func Composition2(x []float64) float64 { nx := len(x) fnx := float64(nx) // optimum positions. o := newOpt(nx) sigma := []float64{10, 20, 30, 40} lambda := []float64{10, 1e-6, 10, 1} bias := []float64{0, 100, 200, 300} omega := make([]float64, nx) funcs := []func([]float64) float64{ Ackley, HighConditionedElliptic, Griewank, Rastrigin, } var sum float64 weights := make([]float64, len(funcs)) for i := range funcs { wi := getWeight(x, o, sigma[i], fnx) weights = append(weights, wi) var wsum float64 for j := range weights { wsum += weights[j] } omega = append(omega, wi/wsum) sum += (omega[i] * (lambda[i]*funcs[i](x) + bias[i])) + funcs[i](x) } return sum } // Composition3 is the "Composition Function 3" of CEC2020. func Composition3(x []float64) float64 { nx := len(x) fnx := float64(nx) // optimum positions. o := newOpt(nx) sigma := []float64{10, 20, 30, 40, 50} lambda := []float64{10, 1, 10, 1e-6, 1} bias := []float64{0, 100, 200, 300, 400} omega := make([]float64, nx) funcs := []func([]float64) float64{ Rastrigin, Happycat, Ackley, Discus, Rosenbrock, } var sum float64 weights := make([]float64, len(funcs)) for i := range funcs { wi := getWeight(x, o, sigma[i], fnx) weights = append(weights, wi) var wsum float64 for j := range weights { wsum += weights[j] } omega = append(omega, wi/wsum) sum += (omega[i] * (lambda[i]*funcs[i](x) + bias[i])) + funcs[i](x) } return sum }