[1]:
import numpy as np
import time
from scipy.optimize import differential_evolution, minimize, dual_annealing
import matplotlib.pyplot as plt
import concurrent.futures
import threading, multiprocessing
import sys
sys.path.append("../")
import minionpy as mpy
import minionpy.test_functions as mpytest
import time
Minimizing Basic Functions
In this section, we minimize basic functions such as Sphere, Rosenbrock, and Rastrigin. The search space is shifted to prevent algorithms from converging near the origin, as some algorithms tend to favor that region.
[2]:
def sphere(x) :
x =np.asarray(x)-1
return 100+np.sum(x**2)
def rosenbrock(x):
#if x[0]<-1 or x[0]>1 : print(x, "bound violated")
x = np.asarray(x)-5.0
return 100+np.sum(100 * (x[1:] - x[:-1]**2)**2 + (1 - x[:-1])**2)
def rastrigin(x):
x = np.asarray(x)-1.0
A = 10
return 100+A * len(x) + np.sum(x**2 - A * np.cos(2 * np.pi * x))
#remember that in minion, objective function must be vectorized. Suppose you want to
func = rosenbrock
def objective_function(X) :
"""
Here, X is a list of x, where x is an input vector.
"""
return [func(x) for x in X]
#Now minimize the function using minion
dimension = 5 #set dimension of the problem
maxevals = 1000 #number of function calls
x0 = [[0.0]*dimension] # initial guesses
min = mpy.Minimizer(func=objective_function, x0=x0, bounds=[(-1, 1)]*dimension, algo="ARRDE", relTol=0.0,
maxevals=10000, callback=None, seed=None, options={"minimum_population_size":4})
result = min.optimize()
print("The minimum of the function is ", "\n\t x : ", result.x, "\n\t f(x) : ", result.fun)
The minimum of the function is
x : [0.9999999999999998, 0.9999999999999996, 0.9999999999999997, 1.0, 0.9999999999999999]
f(x) : 160200.0
Using Basic Test Functions
Minionpy provides a variety of test functions for evaluating optimization algorithms. The dictionary testFunctionDict below contains some of the fundamental functions available. Many of these functions have a global minimum at the origin, which can be problematic since some algorithms naturally converge toward it. To address this issue, CEC benchmark functions apply rotation and shifting to these basic functions, making them more representative of real-world optimization scenarios.
The test functions in minionpy.test_functions are vectorized by default. They accept input as a 2D NumPy array.
[3]:
testFunctionDict = {
"sphere" : mpytest.sphere,
"rosenbrock" : mpytest.rosenbrock,
"rastrigin" : mpytest.rastrigin,
"schaffer2" : mpytest.schaffer2,
"griewank" : mpytest.griewank,
"ackley" : mpytest.ackley,
"zakharov" : mpytest.zakharov,
"bent_cigar" : mpytest.bent_cigar,
"levy" : mpytest.levy,
"discus" : mpytest.discus,
"drop_wave" : mpytest.drop_wave,
"goldstein_price" : mpytest.goldstein_price,
"exponential" : mpytest.exponential,
"quartic" : mpytest.quartic,
"hybrid_composition1" : mpytest.hybrid_composition1,
"hybrid_composition2" : mpytest.hybrid_composition2,
"hybrid_composition3" : mpytest.hybrid_composition3,
"happy_cat" : mpytest.happy_cat,
"michalewics" : mpytest.michalewicz,
"scaffer6" : mpytest.scaffer6,
"hcf" : mpytest.hcf,
"grie_rosen" : mpytest.grie_rosen,
"dixon_price" : mpytest.dixon_price,
"eosom" : mpytest.easom,
"hgbat" : mpytest.hgbat,
"styblinski_tang" : mpytest.styblinski_tang,
"step" : mpytest.step,
"weierstrass" : mpytest.weierstrass,
"sum_squares" : mpytest.sum_squares
}
The performance of different algorithms to minimize these functions can be compared as shown below.
[4]:
dimension = 10
maxevals = 10000
np.random.seed(1)
shift = 10 * np.random.rand(dimension) # Shift randomly
bounds = [(-10, 10)] * dimension
x0 = [10 * np.random.rand(dimension)] # Initial guesses
np.random.seed(None)
for func_name in testFunctionDict:
#if func_name not in ["schaffer2", "ackley", "rastrigin", "rosenbrock"]:
# continue # Minimize only these functions; comment this line to compare all test functions
print(f"Function: {func_name}")
N = 0
def objective_function(X):
"""Shifted objective function for minimization."""
global N
X = np.array(X) - shift # Shift the space
N += len(X)
return testFunctionDict[func_name](X)
def objective_function_scipy(X):
"""Objective function for SciPy optimizers."""
global N
N += 1
return testFunctionDict[func_name]([X])[0]
algoList = [
"DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
"ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES"
]
for algo in algoList:
t_start = time.time()
N = 0
result = mpy.Minimizer(
func=objective_function, x0=x0, bounds=bounds, algo=algo,
relTol=0.0, maxevals=maxevals, callback=None, seed=None,
options={"population_size": 0}
).optimize()
elapsed_time = time.time() - t_start
print(f"\tAlgorithm: {algo:<18} f(x): {result.fun:<15.8g} Elapsed: {elapsed_time:.3f} s")
# Compare to SciPy algorithms
algorithms_scipy = [
("Scipy Nelder-Mead", minimize, {"x0": x0[0], "method": "Nelder-Mead",
"bounds": bounds, "options": {"maxfev": maxevals, "adaptive": True}}),
("Scipy L-BFGS-B", minimize, {"x0": x0[0], "method": "L-BFGS-B",
"options": {"maxfun": maxevals}, "bounds": bounds}),
("Scipy DA", dual_annealing, {"bounds": bounds, "maxfun": maxevals, "x0": x0[0], "no_local_search": False})
]
for name, func, kwargs in algorithms_scipy:
t_start = time.time()
N = 0
result = func(objective_function_scipy, **kwargs)
elapsed_time = time.time() - t_start
print(f"\tAlgorithm: {name:<18} f(x): {result.fun:<15.8g} Elapsed: {elapsed_time:.3f} s")
print("")
Function: sphere
Algorithm: DE f(x): 6.4594316e-07 Elapsed: 0.024 s
Algorithm: ABC f(x): 1.0122429e-06 Elapsed: 0.015 s
Algorithm: LSHADE f(x): 4.8582737e-10 Elapsed: 0.029 s
Algorithm: LSHADE_cnEpSin f(x): 6.3487577e-11 Elapsed: 0.023 s
Algorithm: JADE f(x): 9.2561239e-17 Elapsed: 0.024 s
Algorithm: jSO f(x): 3.23311e-11 Elapsed: 0.029 s
Algorithm: j2020 f(x): 2.5152134e-12 Elapsed: 0.096 s
Algorithm: LSRTDE f(x): 7.735322e-11 Elapsed: 0.015 s
Algorithm: NLSHADE_RSP f(x): 3.8201629e-10 Elapsed: 0.016 s
Algorithm: ARRDE f(x): 2.2758254e-25 Elapsed: 0.024 s
Algorithm: GWO_DE f(x): 3.8637342e-06 Elapsed: 0.016 s
Algorithm: NelderMead f(x): 4.6709368e-30 Elapsed: 0.031 s
Algorithm: DA f(x): 4.7770251e-15 Elapsed: 0.066 s
Algorithm: L_BFGS_B f(x): 8.5184112e-31 Elapsed: 0.000 s
Algorithm: PSO f(x): 2.4934109e-16 Elapsed: 0.015 s
Algorithm: DMSPSO f(x): 1.0116816e-15 Elapsed: 0.013 s
Algorithm: SPSO2011 f(x): 9.646589e-09 Elapsed: 0.018 s
Algorithm: CMAES f(x): 2.8681543e-13 Elapsed: 0.008 s
Algorithm: BIPOP_aCMAES f(x): 8.7623091e-11 Elapsed: 0.008 s
Algorithm: Scipy Nelder-Mead f(x): 5.8359322e-09 Elapsed: 0.034 s
Algorithm: Scipy L-BFGS-B f(x): 6.9420299e-12 Elapsed: 0.004 s
Algorithm: Scipy DA f(x): 2.4294687e-16 Elapsed: 0.280 s
Function: rosenbrock
Algorithm: DE f(x): 5.8036054 Elapsed: 0.016 s
Algorithm: ABC f(x): 4.4393332 Elapsed: 0.014 s
Algorithm: LSHADE f(x): 2.7117536 Elapsed: 0.026 s
Algorithm: LSHADE_cnEpSin f(x): 2.7873194 Elapsed: 0.026 s
Algorithm: JADE f(x): 2.3302768 Elapsed: 0.022 s
Algorithm: jSO f(x): 4.2779572 Elapsed: 0.027 s
Algorithm: j2020 f(x): 6.2863117 Elapsed: 0.137 s
Algorithm: LSRTDE f(x): 5.5999934 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 4.9742818 Elapsed: 0.018 s
Algorithm: ARRDE f(x): 2.9238755 Elapsed: 0.025 s
Algorithm: GWO_DE f(x): 7.5983039 Elapsed: 0.016 s
Algorithm: NelderMead f(x): 3.1653044e-27 Elapsed: 0.067 s
Algorithm: DA f(x): 1.2793334e-09 Elapsed: 0.112 s
Algorithm: L_BFGS_B f(x): 2.7409974e-12 Elapsed: 0.005 s
Algorithm: PSO f(x): 4.0906843 Elapsed: 0.014 s
Algorithm: DMSPSO f(x): 3.2080645 Elapsed: 0.018 s
Algorithm: SPSO2011 f(x): 6.3594034 Elapsed: 0.020 s
Algorithm: CMAES f(x): 0.1977988 Elapsed: 0.026 s
Algorithm: BIPOP_aCMAES f(x): 8.3126645e-11 Elapsed: 0.027 s
Algorithm: Scipy Nelder-Mead f(x): 8.9958364e-09 Elapsed: 0.064 s
Algorithm: Scipy L-BFGS-B f(x): 1.1061741e-10 Elapsed: 0.012 s
Algorithm: Scipy DA f(x): 6.1826579e-11 Elapsed: 0.318 s
Function: rastrigin
Algorithm: DE f(x): 15.91933 Elapsed: 0.016 s
Algorithm: ABC f(x): 0.0020894837 Elapsed: 0.014 s
Algorithm: LSHADE f(x): 2.8265663 Elapsed: 0.026 s
Algorithm: LSHADE_cnEpSin f(x): 1.2984332 Elapsed: 0.019 s
Algorithm: JADE f(x): 0.0005493625 Elapsed: 0.022 s
Algorithm: jSO f(x): 2.7930212 Elapsed: 0.029 s
Algorithm: j2020 f(x): 0.99495906 Elapsed: 0.131 s
Algorithm: LSRTDE f(x): 22.064574 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 2.2162852 Elapsed: 0.019 s
Algorithm: ARRDE f(x): 1.9899388 Elapsed: 0.027 s
Algorithm: GWO_DE f(x): 3.2014875 Elapsed: 0.017 s
Algorithm: NelderMead f(x): 102.47964 Elapsed: 0.020 s
Algorithm: DA f(x): 2.9848772 Elapsed: 0.097 s
Algorithm: L_BFGS_B f(x): 102.47964 Elapsed: 0.001 s
Algorithm: PSO f(x): 13.929397 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): 13.015082 Elapsed: 0.021 s
Algorithm: SPSO2011 f(x): 19.370493 Elapsed: 0.028 s
Algorithm: CMAES f(x): 5.9697543 Elapsed: 0.080 s
Algorithm: BIPOP_aCMAES f(x): 10.944545 Elapsed: 0.047 s
Algorithm: Scipy Nelder-Mead f(x): 254.70399 Elapsed: 0.032 s
Algorithm: Scipy L-BFGS-B f(x): 237.78983 Elapsed: 0.004 s
Algorithm: Scipy DA f(x): 6.3948846e-14 Elapsed: 0.356 s
Function: schaffer2
Algorithm: DE f(x): 0.17246644 Elapsed: 0.224 s
Algorithm: ABC f(x): 0.16649813 Elapsed: 0.194 s
Algorithm: LSHADE f(x): 0.28156973 Elapsed: 0.222 s
Algorithm: LSHADE_cnEpSin f(x): 0.41557792 Elapsed: 0.202 s
Algorithm: JADE f(x): 0.23437661 Elapsed: 0.199 s
Algorithm: jSO f(x): 0.26111586 Elapsed: 0.209 s
Algorithm: j2020 f(x): 0.43476573 Elapsed: 0.253 s
Algorithm: LSRTDE f(x): 0.92118071 Elapsed: 0.208 s
Algorithm: NLSHADE_RSP f(x): 0.18376438 Elapsed: 0.194 s
Algorithm: ARRDE f(x): 0.13212947 Elapsed: 0.209 s
Algorithm: GWO_DE f(x): 0.56071983 Elapsed: 0.192 s
Algorithm: NelderMead f(x): 0.18775994 Elapsed: 0.117 s
Algorithm: DA f(x): 1.2267964e-14 Elapsed: 0.255 s
Algorithm: L_BFGS_B f(x): 0.18775994 Elapsed: 0.025 s
Algorithm: PSO f(x): 0.17015076 Elapsed: 0.198 s
Algorithm: DMSPSO f(x): 0.14245968 Elapsed: 0.190 s
Algorithm: SPSO2011 f(x): 0.89992984 Elapsed: 0.200 s
Algorithm: CMAES f(x): 0.47136894 Elapsed: 0.201 s
Algorithm: BIPOP_aCMAES f(x): 0.54929968 Elapsed: 0.234 s
Algorithm: Scipy Nelder-Mead f(x): 0.38943872 Elapsed: 0.072 s
Algorithm: Scipy L-BFGS-B f(x): 0.38943873 Elapsed: 0.020 s
Algorithm: Scipy DA f(x): 0.087443189 Elapsed: 0.436 s
Function: griewank
Algorithm: DE f(x): 0.039382435 Elapsed: 0.017 s
Algorithm: ABC f(x): 0.012211673 Elapsed: 0.018 s
Algorithm: LSHADE f(x): 0.041705992 Elapsed: 0.027 s
Algorithm: LSHADE_cnEpSin f(x): 0.0024145917 Elapsed: 0.021 s
Algorithm: JADE f(x): 0.044212076 Elapsed: 0.023 s
Algorithm: jSO f(x): 0.032435159 Elapsed: 0.032 s
Algorithm: j2020 f(x): 0.017241088 Elapsed: 0.169 s
Algorithm: LSRTDE f(x): 0.0073966469 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 0.025184437 Elapsed: 0.029 s
Algorithm: ARRDE f(x): 0.0073960405 Elapsed: 0.032 s
Algorithm: GWO_DE f(x): 0.019931597 Elapsed: 0.018 s
Algorithm: NelderMead f(x): 0.02461003 Elapsed: 0.032 s
Algorithm: DA f(x): 0.07529705 Elapsed: 0.095 s
Algorithm: L_BFGS_B f(x): 0.02461003 Elapsed: 0.002 s
Algorithm: PSO f(x): 0.078792042 Elapsed: 0.015 s
Algorithm: DMSPSO f(x): 0.017226294 Elapsed: 0.015 s
Algorithm: SPSO2011 f(x): 0.045022134 Elapsed: 0.018 s
Algorithm: CMAES f(x): 1.956213e-13 Elapsed: 0.010 s
Algorithm: BIPOP_aCMAES f(x): 7.4974693e-11 Elapsed: 0.008 s
Algorithm: Scipy Nelder-Mead f(x): 0.046729411 Elapsed: 0.040 s
Algorithm: Scipy L-BFGS-B f(x): 0.024637062 Elapsed: 0.014 s
Algorithm: Scipy DA f(x): 0.019697357 Elapsed: 0.361 s
Function: ackley
Algorithm: DE f(x): 2.4158131e-05 Elapsed: 0.017 s
Algorithm: ABC f(x): 0.0017400868 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 0.0001666456 Elapsed: 0.028 s
Algorithm: LSHADE_cnEpSin f(x): 9.7505205e-06 Elapsed: 0.022 s
Algorithm: JADE f(x): 8.8892138e-10 Elapsed: 0.024 s
Algorithm: jSO f(x): 1.094312e-05 Elapsed: 0.031 s
Algorithm: j2020 f(x): 1.3658807e-10 Elapsed: 0.218 s
Algorithm: LSRTDE f(x): 5.2449461e-06 Elapsed: 0.018 s
Algorithm: NLSHADE_RSP f(x): 3.4322147e-05 Elapsed: 0.026 s
Algorithm: ARRDE f(x): 5.8943961e-12 Elapsed: 0.031 s
Algorithm: GWO_DE f(x): 0.0033328706 Elapsed: 0.018 s
Algorithm: NelderMead f(x): 9.0738777 Elapsed: 0.032 s
Algorithm: DA f(x): 9.2588487e-08 Elapsed: 0.104 s
Algorithm: L_BFGS_B f(x): 9.4529928 Elapsed: 0.001 s
Algorithm: PSO f(x): 5.102173e-08 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): 1.3402275e-08 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): 8.8838955e-05 Elapsed: 0.019 s
Algorithm: CMAES f(x): 6.6835426e-13 Elapsed: 0.019 s
Algorithm: BIPOP_aCMAES f(x): 5.9202865e-11 Elapsed: 0.016 s
Algorithm: Scipy Nelder-Mead f(x): 12.719749 Elapsed: 0.028 s
Algorithm: Scipy L-BFGS-B f(x): 12.719749 Elapsed: 0.004 s
Algorithm: Scipy DA f(x): 1.8047509e-08 Elapsed: 0.384 s
Function: zakharov
Algorithm: DE f(x): 0.0050356294 Elapsed: 0.018 s
Algorithm: ABC f(x): 16.031338 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 7.2962653e-06 Elapsed: 0.028 s
Algorithm: LSHADE_cnEpSin f(x): 1.5206326e-10 Elapsed: 0.021 s
Algorithm: JADE f(x): 5.1068813e-10 Elapsed: 0.026 s
Algorithm: jSO f(x): 5.8762452e-06 Elapsed: 0.030 s
Algorithm: j2020 f(x): 0.087694588 Elapsed: 0.233 s
Algorithm: LSRTDE f(x): 6.1099831e-09 Elapsed: 0.019 s
Algorithm: NLSHADE_RSP f(x): 0.0057944557 Elapsed: 0.023 s
Algorithm: ARRDE f(x): 9.8684862e-14 Elapsed: 0.031 s
Algorithm: GWO_DE f(x): 0.0066427977 Elapsed: 0.018 s
Algorithm: NelderMead f(x): 9.5208937e-30 Elapsed: 0.072 s
Algorithm: DA f(x): 3.5494939e-13 Elapsed: 0.175 s
Algorithm: L_BFGS_B f(x): 6.7711304e-15 Elapsed: 0.003 s
Algorithm: PSO f(x): 4.9073152e-09 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): 1.1826456e-08 Elapsed: 0.018 s
Algorithm: SPSO2011 f(x): 0.005796406 Elapsed: 0.020 s
Algorithm: CMAES f(x): 2.1307953e-13 Elapsed: 0.015 s
Algorithm: BIPOP_aCMAES f(x): 9.4183389e-11 Elapsed: 0.011 s
Algorithm: Scipy Nelder-Mead f(x): 7.6416259e-09 Elapsed: 0.086 s
Algorithm: Scipy L-BFGS-B f(x): 7.2717586e-14 Elapsed: 0.010 s
Algorithm: Scipy DA f(x): 1.465953e-14 Elapsed: 0.432 s
Function: bent_cigar
Algorithm: DE f(x): 26.191855 Elapsed: 0.015 s
Algorithm: ABC f(x): 0.046922887 Elapsed: 0.013 s
Algorithm: LSHADE f(x): 0.0019367317 Elapsed: 0.026 s
Algorithm: LSHADE_cnEpSin f(x): 1.2389598e-05 Elapsed: 0.018 s
Algorithm: JADE f(x): 9.7328981e-11 Elapsed: 0.020 s
Algorithm: jSO f(x): 5.8346178e-05 Elapsed: 0.026 s
Algorithm: j2020 f(x): 2.4960754e-10 Elapsed: 0.112 s
Algorithm: LSRTDE f(x): 4.5403445e-08 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 0.000367709 Elapsed: 0.017 s
Algorithm: ARRDE f(x): 5.5363714e-17 Elapsed: 0.023 s
Algorithm: GWO_DE f(x): 0.45505858 Elapsed: 0.015 s
Algorithm: NelderMead f(x): 7.6172326e-24 Elapsed: 0.042 s
Algorithm: DA f(x): 6.9255571e-09 Elapsed: 0.049 s
Algorithm: L_BFGS_B f(x): 9.8449067e-16 Elapsed: 0.001 s
Algorithm: PSO f(x): 7.7289154e-08 Elapsed: 0.012 s
Algorithm: DMSPSO f(x): 1.2876138e-10 Elapsed: 0.014 s
Algorithm: SPSO2011 f(x): 5.9650724 Elapsed: 0.017 s
Algorithm: CMAES f(x): 8.0029119e-07 Elapsed: 0.022 s
Algorithm: BIPOP_aCMAES f(x): 9.6219973e-11 Elapsed: 0.015 s
Algorithm: Scipy Nelder-Mead f(x): 98.947303 Elapsed: 0.030 s
Algorithm: Scipy L-BFGS-B f(x): 2.0992475e-10 Elapsed: 0.013 s
Algorithm: Scipy DA f(x): 2.2982927e-10 Elapsed: 0.293 s
Function: levy
Algorithm: DE f(x): 2.2725093 Elapsed: 0.020 s
Algorithm: ABC f(x): 4.5570952e-07 Elapsed: 0.020 s
Algorithm: LSHADE f(x): 1.0829658e-08 Elapsed: 0.030 s
Algorithm: LSHADE_cnEpSin f(x): 3.5374864e-12 Elapsed: 0.024 s
Algorithm: JADE f(x): 7.3493567e-16 Elapsed: 0.028 s
Algorithm: jSO f(x): 1.1177129e-09 Elapsed: 0.032 s
Algorithm: j2020 f(x): 0.089528264 Elapsed: 0.280 s
Algorithm: LSRTDE f(x): 3.2525454e-13 Elapsed: 0.021 s
Algorithm: NLSHADE_RSP f(x): 7.7868421e-09 Elapsed: 0.025 s
Algorithm: ARRDE f(x): 2.6161962e-22 Elapsed: 0.034 s
Algorithm: GWO_DE f(x): 5.2462578e-06 Elapsed: 0.021 s
Algorithm: NelderMead f(x): 2.3300009 Elapsed: 0.075 s
Algorithm: DA f(x): 4.5034896e-15 Elapsed: 0.216 s
Algorithm: L_BFGS_B f(x): 0.1790565 Elapsed: 0.002 s
Algorithm: PSO f(x): 5.9713608e-16 Elapsed: 0.018 s
Algorithm: DMSPSO f(x): 1.5690238e-14 Elapsed: 0.019 s
Algorithm: SPSO2011 f(x): 5.5242815e-07 Elapsed: 0.022 s
Algorithm: CMAES f(x): 3.0082245e-13 Elapsed: 0.013 s
Algorithm: BIPOP_aCMAES f(x): 7.6630845e-11 Elapsed: 0.010 s
Algorithm: Scipy Nelder-Mead f(x): 10.612364 Elapsed: 0.089 s
Algorithm: Scipy L-BFGS-B f(x): 5.6358232 Elapsed: 0.022 s
Algorithm: Scipy DA f(x): 1.5327518e-12 Elapsed: 0.501 s
Function: discus
Algorithm: DE f(x): 6.5433889e-17 Elapsed: 0.014 s
Algorithm: ABC f(x): 8.5312468e-05 Elapsed: 0.012 s
Algorithm: LSHADE f(x): 3.4177328e-07 Elapsed: 0.025 s
Algorithm: LSHADE_cnEpSin f(x): 5.5745866e-11 Elapsed: 0.018 s
Algorithm: JADE f(x): 3.5753523e-16 Elapsed: 0.020 s
Algorithm: jSO f(x): 5.8742102e-09 Elapsed: 0.027 s
Algorithm: j2020 f(x): 9.1398502e-13 Elapsed: 0.111 s
Algorithm: LSRTDE f(x): 4.2485466e-13 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 5.5939541e-11 Elapsed: 0.016 s
Algorithm: ARRDE f(x): 1.9951317e-21 Elapsed: 0.024 s
Algorithm: GWO_DE f(x): 4.7217992e-05 Elapsed: 0.015 s
Algorithm: NelderMead f(x): 2.5838254e-24 Elapsed: 0.112 s
Algorithm: DA f(x): 4.1855874e-13 Elapsed: 0.050 s
Algorithm: L_BFGS_B f(x): 3.6369399e-13 Elapsed: 0.002 s
Algorithm: PSO f(x): 2.0870329e-12 Elapsed: 0.012 s
Algorithm: DMSPSO f(x): 9.7306774e-14 Elapsed: 0.013 s
Algorithm: SPSO2011 f(x): 102.02634 Elapsed: 0.016 s
Algorithm: CMAES f(x): 1.904148e-13 Elapsed: 0.016 s
Algorithm: BIPOP_aCMAES f(x): 9.214248e-11 Elapsed: 0.012 s
Algorithm: Scipy Nelder-Mead f(x): 7.8818509e-09 Elapsed: 0.114 s
Algorithm: Scipy L-BFGS-B f(x): 7.8454908e-12 Elapsed: 0.010 s
Algorithm: Scipy DA f(x): 1.5357412e-07 Elapsed: 0.305 s
Function: drop_wave
Algorithm: DE f(x): -1 Elapsed: 0.012 s
Algorithm: ABC f(x): -0.99400969 Elapsed: 0.030 s
Algorithm: LSHADE f(x): -0.99997043 Elapsed: 0.043 s
Algorithm: LSHADE_cnEpSin f(x): -1 Elapsed: 0.036 s
Algorithm: JADE f(x): -0.99999995 Elapsed: 0.038 s
Algorithm: jSO f(x): -1 Elapsed: 0.044 s
Algorithm: j2020 f(x): -1 Elapsed: 0.086 s
Algorithm: LSRTDE f(x): -1 Elapsed: 0.025 s
Algorithm: NLSHADE_RSP f(x): -1 Elapsed: 0.033 s
Algorithm: ARRDE f(x): -1 Elapsed: 0.041 s
Algorithm: GWO_DE f(x): -1 Elapsed: 0.035 s
Algorithm: NelderMead f(x): -1 Elapsed: 0.009 s
Algorithm: DA f(x): -0.93624533 Elapsed: 0.045 s
Algorithm: L_BFGS_B f(x): -0.93624533 Elapsed: 0.001 s
Algorithm: PSO f(x): -1 Elapsed: 0.030 s
Algorithm: DMSPSO f(x): -1 Elapsed: 0.031 s
Algorithm: SPSO2011 f(x): -1 Elapsed: 0.034 s
Algorithm: CMAES f(x): -0.93709275 Elapsed: 0.036 s
Algorithm: BIPOP_aCMAES f(x): -0.32690614 Elapsed: 0.000 s
Algorithm: Scipy Nelder-Mead f(x): -0.053939199 Elapsed: 0.011 s
Algorithm: Scipy L-BFGS-B f(x): -0.060920875 Elapsed: 0.002 s
Algorithm: Scipy DA f(x): -0.93624533 Elapsed: 0.282 s
Function: goldstein_price
Algorithm: DE f(x): 3 Elapsed: 0.016 s
Algorithm: ABC f(x): 8.4987029 Elapsed: 0.027 s
Algorithm: LSHADE f(x): 3 Elapsed: 0.042 s
Algorithm: LSHADE_cnEpSin f(x): 3 Elapsed: 0.033 s
Algorithm: JADE f(x): 3 Elapsed: 0.035 s
Algorithm: jSO f(x): 3 Elapsed: 0.040 s
Algorithm: j2020 f(x): 3 Elapsed: 0.083 s
Algorithm: LSRTDE f(x): 3 Elapsed: 0.025 s
Algorithm: NLSHADE_RSP f(x): 3 Elapsed: 0.028 s
Algorithm: ARRDE f(x): 3 Elapsed: 0.038 s
Algorithm: GWO_DE f(x): 3 Elapsed: 0.031 s
Algorithm: NelderMead f(x): 3 Elapsed: 0.009 s
Algorithm: DA f(x): 3 Elapsed: 0.062 s
Algorithm: L_BFGS_B f(x): 3 Elapsed: 0.002 s
Algorithm: PSO f(x): 3 Elapsed: 0.031 s
Algorithm: DMSPSO f(x): 3 Elapsed: 0.028 s
Algorithm: SPSO2011 f(x): 3.0000028 Elapsed: 0.031 s
Algorithm: CMAES f(x): 3 Elapsed: 0.034 s
Algorithm: BIPOP_aCMAES f(x): 3 Elapsed: 0.044 s
Algorithm: Scipy Nelder-Mead f(x): 84 Elapsed: 0.015 s
Algorithm: Scipy L-BFGS-B f(x): 3 Elapsed: 0.006 s
Algorithm: Scipy DA f(x): 3 Elapsed: 0.283 s
Function: exponential
Algorithm: DE f(x): -1 Elapsed: 0.012 s
Algorithm: ABC f(x): -0.99999972 Elapsed: 0.013 s
Algorithm: LSHADE f(x): -0.99999999 Elapsed: 0.026 s
Algorithm: LSHADE_cnEpSin f(x): -1 Elapsed: 0.021 s
Algorithm: JADE f(x): -1 Elapsed: 0.020 s
Algorithm: jSO f(x): -1 Elapsed: 0.028 s
Algorithm: j2020 f(x): -1 Elapsed: 0.115 s
Algorithm: LSRTDE f(x): -1 Elapsed: 0.014 s
Algorithm: NLSHADE_RSP f(x): -1 Elapsed: 0.017 s
Algorithm: ARRDE f(x): -1 Elapsed: 0.024 s
Algorithm: GWO_DE f(x): -0.99999861 Elapsed: 0.015 s
Algorithm: NelderMead f(x): -1 Elapsed: 0.021 s
Algorithm: DA f(x): -6.4343732e-10 Elapsed: 0.107 s
Algorithm: L_BFGS_B f(x): -1.609051e-22 Elapsed: 0.000 s
Algorithm: PSO f(x): -1 Elapsed: 0.013 s
Algorithm: DMSPSO f(x): -1 Elapsed: 0.015 s
Algorithm: SPSO2011 f(x): -1 Elapsed: 0.017 s
Algorithm: CMAES f(x): -8.2953178e-25 Elapsed: 0.000 s
Algorithm: BIPOP_aCMAES f(x): -4.7836671e-18 Elapsed: 0.000 s
Algorithm: Scipy Nelder-Mead f(x): -1 Elapsed: 0.034 s
Algorithm: Scipy L-BFGS-B f(x): -5.2446221e-54 Elapsed: 0.001 s
Algorithm: Scipy DA f(x): -8.4503699e-12 Elapsed: 0.325 s
Function: quartic
Algorithm: DE f(x): 0.009943409 Elapsed: 0.021 s
Algorithm: ABC f(x): 0.054496823 Elapsed: 0.019 s
Algorithm: LSHADE f(x): 0.0017695069 Elapsed: 0.032 s
Algorithm: LSHADE_cnEpSin f(x): 0.0022572815 Elapsed: 0.026 s
Algorithm: JADE f(x): 0.0065914268 Elapsed: 0.026 s
Algorithm: jSO f(x): 0.0055610006 Elapsed: 0.041 s
Algorithm: j2020 f(x): 0.0031824399 Elapsed: 0.177 s
Algorithm: LSRTDE f(x): 0.021650487 Elapsed: 0.022 s
Algorithm: NLSHADE_RSP f(x): 0.0050619586 Elapsed: 0.025 s
Algorithm: ARRDE f(x): 0.0087228958 Elapsed: 0.032 s
Algorithm: GWO_DE f(x): 0.0031042237 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 3.2231466 Elapsed: 0.104 s
Algorithm: DA f(x): 0.0022227683 Elapsed: 0.061 s
Algorithm: L_BFGS_B f(x): 0.017609036 Elapsed: 0.008 s
Algorithm: PSO f(x): 0.0075577947 Elapsed: 0.017 s
Algorithm: DMSPSO f(x): 0.0054908702 Elapsed: 0.018 s
Algorithm: SPSO2011 f(x): 0.010998981 Elapsed: 0.023 s
Algorithm: CMAES f(x): 0.0048703297 Elapsed: 0.011 s
Algorithm: BIPOP_aCMAES f(x): 0.0061883551 Elapsed: 0.008 s
Algorithm: Scipy Nelder-Mead f(x): 2.7828721 Elapsed: 0.233 s
Algorithm: Scipy L-BFGS-B f(x): 50784.288 Elapsed: 0.009 s
Algorithm: Scipy DA f(x): 0.20264968 Elapsed: 0.309 s
Function: hybrid_composition1
Algorithm: DE f(x): 46.013054 Elapsed: 0.019 s
Algorithm: ABC f(x): 38.463758 Elapsed: 0.020 s
Algorithm: LSHADE f(x): 8.9683166 Elapsed: 0.029 s
Algorithm: LSHADE_cnEpSin f(x): 8.9683085 Elapsed: 0.024 s
Algorithm: JADE f(x): 8.9683084 Elapsed: 0.026 s
Algorithm: jSO f(x): 8.9683085 Elapsed: 0.032 s
Algorithm: j2020 f(x): 99.70699 Elapsed: 0.238 s
Algorithm: LSRTDE f(x): 8.9683084 Elapsed: 0.020 s
Algorithm: NLSHADE_RSP f(x): 8.9683102 Elapsed: 0.025 s
Algorithm: ARRDE f(x): 8.9683084 Elapsed: 0.034 s
Algorithm: GWO_DE f(x): 8.9729914 Elapsed: 0.020 s
Algorithm: NelderMead f(x): 8.9683084 Elapsed: 0.049 s
Algorithm: DA f(x): 47.137176 Elapsed: 0.173 s
Algorithm: L_BFGS_B f(x): 129.896 Elapsed: 0.002 s
Algorithm: PSO f(x): 8.9683084 Elapsed: 0.017 s
Algorithm: DMSPSO f(x): 8.9683084 Elapsed: 0.021 s
Algorithm: SPSO2011 f(x): 8.9683126 Elapsed: 0.021 s
Algorithm: CMAES f(x): 8.9683084 Elapsed: 0.028 s
Algorithm: BIPOP_aCMAES f(x): 8.9683084 Elapsed: 0.050 s
Algorithm: Scipy Nelder-Mead f(x): 81.481178 Elapsed: 0.057 s
Algorithm: Scipy L-BFGS-B f(x): 49.451818 Elapsed: 0.011 s
Algorithm: Scipy DA f(x): 8.9683084 Elapsed: 0.482 s
Function: hybrid_composition2
Algorithm: DE f(x): 1.938007e-05 Elapsed: 0.024 s
Algorithm: ABC f(x): 0.0039226331 Elapsed: 0.026 s
Algorithm: LSHADE f(x): 0.00032435022 Elapsed: 0.035 s
Algorithm: LSHADE_cnEpSin f(x): 1.5269293e-05 Elapsed: 0.029 s
Algorithm: JADE f(x): 3.0408034e-08 Elapsed: 0.033 s
Algorithm: jSO f(x): 8.890085e-05 Elapsed: 0.037 s
Algorithm: j2020 f(x): 1.0230618e-11 Elapsed: 0.419 s
Algorithm: LSRTDE f(x): 4.3133943e-06 Elapsed: 0.027 s
Algorithm: NLSHADE_RSP f(x): 2.5255503e-05 Elapsed: 0.033 s
Algorithm: ARRDE f(x): 1.6645973e-13 Elapsed: 0.044 s
Algorithm: GWO_DE f(x): 0.0060479569 Elapsed: 0.024 s
Algorithm: NelderMead f(x): 2.1270735 Elapsed: 0.145 s
Algorithm: DA f(x): 2.4179538e-07 Elapsed: 0.256 s
Algorithm: L_BFGS_B f(x): 2.1694175e-08 Elapsed: 0.012 s
Algorithm: PSO f(x): 2.8875353e-07 Elapsed: 0.023 s
Algorithm: DMSPSO f(x): 2.0066391e-07 Elapsed: 0.023 s
Algorithm: SPSO2011 f(x): 0.00062779798 Elapsed: 0.025 s
Algorithm: CMAES f(x): 5.7029468e-13 Elapsed: 0.031 s
Algorithm: BIPOP_aCMAES f(x): 9.3565631e-11 Elapsed: 0.027 s
Algorithm: Scipy Nelder-Mead f(x): 9.7571206 Elapsed: 0.169 s
Algorithm: Scipy L-BFGS-B f(x): 6.6176766e-08 Elapsed: 0.093 s
Algorithm: Scipy DA f(x): 6.0014141e-08 Elapsed: 0.626 s
Function: hybrid_composition3
Algorithm: DE f(x): 3.4767541 Elapsed: 0.033 s
Algorithm: ABC f(x): 53.301817 Elapsed: 0.041 s
Algorithm: LSHADE f(x): 1.2839623 Elapsed: 0.042 s
Algorithm: LSHADE_cnEpSin f(x): 1.2839526 Elapsed: 0.040 s
Algorithm: JADE f(x): 1.3071985 Elapsed: 0.045 s
Algorithm: jSO f(x): 1.2839527 Elapsed: 0.047 s
Algorithm: j2020 f(x): 1.3412612 Elapsed: 0.553 s
Algorithm: LSRTDE f(x): 1.2839526 Elapsed: 0.030 s
Algorithm: NLSHADE_RSP f(x): 1.2919624 Elapsed: 0.044 s
Algorithm: ARRDE f(x): 1.2839534 Elapsed: 0.054 s
Algorithm: GWO_DE f(x): 1.2913111 Elapsed: 0.031 s
Algorithm: NelderMead f(x): 34.881183 Elapsed: 0.154 s
Algorithm: DA f(x): 4.2578964 Elapsed: 0.313 s
Algorithm: L_BFGS_B f(x): 2.3887651 Elapsed: 0.009 s
Algorithm: PSO f(x): 1.2839526 Elapsed: 0.030 s
Algorithm: DMSPSO f(x): 1.2839526 Elapsed: 0.032 s
Algorithm: SPSO2011 f(x): 1.3137448 Elapsed: 0.039 s
Algorithm: CMAES f(x): 1.2839526 Elapsed: 0.052 s
Algorithm: BIPOP_aCMAES f(x): 1.2839526 Elapsed: 0.071 s
Algorithm: Scipy Nelder-Mead f(x): 95.146651 Elapsed: 0.367 s
Algorithm: Scipy L-BFGS-B f(x): 17.427019 Elapsed: 0.060 s
Algorithm: Scipy DA f(x): 90.688619 Elapsed: 0.777 s
Function: happy_cat
Algorithm: DE f(x): 0.23591693 Elapsed: 0.017 s
Algorithm: ABC f(x): 0.15177649 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 0.10854896 Elapsed: 0.027 s
Algorithm: LSHADE_cnEpSin f(x): 0.055524206 Elapsed: 0.085 s
Algorithm: JADE f(x): 0.092597895 Elapsed: 0.025 s
Algorithm: jSO f(x): 0.076913426 Elapsed: 0.030 s
Algorithm: j2020 f(x): 0.19970891 Elapsed: 0.212 s
Algorithm: LSRTDE f(x): 0.068197151 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 0.15832575 Elapsed: 0.021 s
Algorithm: ARRDE f(x): 0.074841347 Elapsed: 0.030 s
Algorithm: GWO_DE f(x): 0.038752403 Elapsed: 0.017 s
Algorithm: NelderMead f(x): 0.67618088 Elapsed: 0.040 s
Algorithm: DA f(x): 0.33583457 Elapsed: 0.141 s
Algorithm: L_BFGS_B f(x): 0.31691389 Elapsed: 0.010 s
Algorithm: PSO f(x): 0.090518555 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): 0.096716547 Elapsed: 0.017 s
Algorithm: SPSO2011 f(x): 0.067817495 Elapsed: 0.020 s
Algorithm: CMAES f(x): 0.076208409 Elapsed: 0.025 s
Algorithm: BIPOP_aCMAES f(x): 0.079961817 Elapsed: 0.043 s
Algorithm: Scipy Nelder-Mead f(x): 1.4407279 Elapsed: 0.039 s
Algorithm: Scipy L-BFGS-B f(x): 0.005875464 Elapsed: 0.034 s
Algorithm: Scipy DA f(x): 0.16471355 Elapsed: 0.400 s
Function: michalewics
Algorithm: DE f(x): -8.5815331 Elapsed: 0.024 s
Algorithm: ABC f(x): -8.4621134 Elapsed: 0.022 s
Algorithm: LSHADE f(x): -8.9894813 Elapsed: 0.034 s
Algorithm: LSHADE_cnEpSin f(x): -8.5499938 Elapsed: 0.027 s
Algorithm: JADE f(x): -9.2283196 Elapsed: 0.029 s
Algorithm: jSO f(x): -5.7529628 Elapsed: 0.037 s
Algorithm: j2020 f(x): -9.1168324 Elapsed: 0.169 s
Algorithm: LSRTDE f(x): -8.0371607 Elapsed: 0.024 s
Algorithm: NLSHADE_RSP f(x): -7.9501799 Elapsed: 0.026 s
Algorithm: ARRDE f(x): -9.6741515 Elapsed: 0.035 s
Algorithm: GWO_DE f(x): -4.6689961 Elapsed: 0.026 s
Algorithm: NelderMead f(x): -3.6164748 Elapsed: 0.135 s
Algorithm: DA f(x): -9.7854984 Elapsed: 0.083 s
Algorithm: L_BFGS_B f(x): -2.6919883 Elapsed: 0.006 s
Algorithm: PSO f(x): -8.1938975 Elapsed: 0.020 s
Algorithm: DMSPSO f(x): -4.5521755 Elapsed: 0.021 s
Algorithm: SPSO2011 f(x): -4.9307636 Elapsed: 0.025 s
Algorithm: CMAES f(x): -8.0447463 Elapsed: 0.030 s
Algorithm: BIPOP_aCMAES f(x): -1.7133756 Elapsed: 0.000 s
Algorithm: Scipy Nelder-Mead f(x): -4.2489914 Elapsed: 0.054 s
Algorithm: Scipy L-BFGS-B f(x): -3.2901102 Elapsed: 0.021 s
Algorithm: Scipy DA f(x): -9.7935582 Elapsed: 0.349 s
Function: scaffer6
Algorithm: DE f(x): 0.25249219 Elapsed: 0.192 s
Algorithm: ABC f(x): 0.18213552 Elapsed: 0.200 s
Algorithm: LSHADE f(x): 0.36538531 Elapsed: 0.207 s
Algorithm: LSHADE_cnEpSin f(x): 0.46483694 Elapsed: 0.199 s
Algorithm: JADE f(x): 0.15600834 Elapsed: 0.202 s
Algorithm: jSO f(x): 1.0107057 Elapsed: 0.206 s
Algorithm: j2020 f(x): 0.44059681 Elapsed: 0.256 s
Algorithm: LSRTDE f(x): 0.83658298 Elapsed: 0.189 s
Algorithm: NLSHADE_RSP f(x): 0.19632212 Elapsed: 0.203 s
Algorithm: ARRDE f(x): 0.14238011 Elapsed: 0.211 s
Algorithm: GWO_DE f(x): 0.17940201 Elapsed: 0.203 s
Algorithm: NelderMead f(x): 0.18775994 Elapsed: 0.121 s
Algorithm: DA f(x): 0.087443189 Elapsed: 0.241 s
Algorithm: L_BFGS_B f(x): 0.18775994 Elapsed: 0.023 s
Algorithm: PSO f(x): 0.11495147 Elapsed: 0.198 s
Algorithm: DMSPSO f(x): 0.32037117 Elapsed: 0.198 s
Algorithm: SPSO2011 f(x): 0.45037912 Elapsed: 0.198 s
Algorithm: CMAES f(x): 0.42270187 Elapsed: 0.203 s
Algorithm: BIPOP_aCMAES f(x): 0.71153887 Elapsed: 0.215 s
Algorithm: Scipy Nelder-Mead f(x): 0.38943872 Elapsed: 0.065 s
Algorithm: Scipy L-BFGS-B f(x): 0.38943873 Elapsed: 0.020 s
Algorithm: Scipy DA f(x): 0.087443196 Elapsed: 0.420 s
Function: hcf
Algorithm: DE f(x): 0.016643025 Elapsed: 0.015 s
Algorithm: ABC f(x): 0.003200968 Elapsed: 0.013 s
Algorithm: LSHADE f(x): 0.00054574173 Elapsed: 0.025 s
Algorithm: LSHADE_cnEpSin f(x): 2.6345598e-05 Elapsed: 0.021 s
Algorithm: JADE f(x): 1.3453768e-09 Elapsed: 0.023 s
Algorithm: jSO f(x): 1.5143254e-05 Elapsed: 0.029 s
Algorithm: j2020 f(x): 3.4540466e-08 Elapsed: 0.156 s
Algorithm: LSRTDE f(x): 1.5193954e-06 Elapsed: 0.015 s
Algorithm: NLSHADE_RSP f(x): 6.0449993e-06 Elapsed: 0.019 s
Algorithm: ARRDE f(x): 2.1678124e-13 Elapsed: 0.025 s
Algorithm: GWO_DE f(x): 0.0042892428 Elapsed: 0.015 s
Algorithm: NelderMead f(x): 2.358758 Elapsed: 0.137 s
Algorithm: DA f(x): 1.3036637e-07 Elapsed: 0.082 s
Algorithm: L_BFGS_B f(x): 5.4877386e-09 Elapsed: 0.006 s
Algorithm: PSO f(x): 3.6716305e-08 Elapsed: 0.013 s
Algorithm: DMSPSO f(x): 6.7345107e-08 Elapsed: 0.014 s
Algorithm: SPSO2011 f(x): 0.00076268558 Elapsed: 0.016 s
Algorithm: CMAES f(x): 6.6431452e-13 Elapsed: 0.016 s
Algorithm: BIPOP_aCMAES f(x): 6.2473238e-11 Elapsed: 0.014 s
Algorithm: Scipy Nelder-Mead f(x): 9.2898681 Elapsed: 0.104 s
Algorithm: Scipy L-BFGS-B f(x): 3.9901546e-08 Elapsed: 0.038 s
Algorithm: Scipy DA f(x): 6.6041994e-08 Elapsed: 0.316 s
Function: grie_rosen
Algorithm: DE f(x): 9.0927885 Elapsed: 0.016 s
Algorithm: ABC f(x): 4.9093932 Elapsed: 0.015 s
Algorithm: LSHADE f(x): 4.285257 Elapsed: 0.025 s
Algorithm: LSHADE_cnEpSin f(x): 1.9765677 Elapsed: 0.029 s
Algorithm: JADE f(x): 5.1477162 Elapsed: 0.024 s
Algorithm: jSO f(x): 5.6576765 Elapsed: 0.029 s
Algorithm: j2020 f(x): 1.0790723 Elapsed: 0.149 s
Algorithm: LSRTDE f(x): 5.9652161 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 3.8337539 Elapsed: 0.020 s
Algorithm: ARRDE f(x): 4.0831197 Elapsed: 0.026 s
Algorithm: GWO_DE f(x): 7.7043076 Elapsed: 0.017 s
Algorithm: NelderMead f(x): 1 Elapsed: 0.063 s
Algorithm: DA f(x): 1 Elapsed: 0.102 s
Algorithm: L_BFGS_B f(x): 1 Elapsed: 0.005 s
Algorithm: PSO f(x): 4.5445269 Elapsed: 0.014 s
Algorithm: DMSPSO f(x): 8.014341 Elapsed: 0.015 s
Algorithm: SPSO2011 f(x): 7.951165 Elapsed: 0.017 s
Algorithm: CMAES f(x): 1.0465555 Elapsed: 0.023 s
Algorithm: BIPOP_aCMAES f(x): 1 Elapsed: 0.024 s
Algorithm: Scipy Nelder-Mead f(x): 1 Elapsed: 0.067 s
Algorithm: Scipy L-BFGS-B f(x): 1 Elapsed: 0.017 s
Algorithm: Scipy DA f(x): 1 Elapsed: 0.348 s
Function: dixon_price
Algorithm: DE f(x): 0.66666667 Elapsed: 0.016 s
Algorithm: ABC f(x): 0.70458522 Elapsed: 0.018 s
Algorithm: LSHADE f(x): 0.66670683 Elapsed: 0.030 s
Algorithm: LSHADE_cnEpSin f(x): 0.66666667 Elapsed: 0.021 s
Algorithm: JADE f(x): 0.66666673 Elapsed: 0.023 s
Algorithm: jSO f(x): 0.66666667 Elapsed: 0.028 s
Algorithm: j2020 f(x): 0.063672199 Elapsed: 0.159 s
Algorithm: LSRTDE f(x): 0.66666681 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 0.66666667 Elapsed: 0.019 s
Algorithm: ARRDE f(x): 0.066966468 Elapsed: 0.027 s
Algorithm: GWO_DE f(x): 0.66738397 Elapsed: 0.017 s
Algorithm: NelderMead f(x): 0.66666667 Elapsed: 0.122 s
Algorithm: DA f(x): 0.66666667 Elapsed: 0.166 s
Algorithm: L_BFGS_B f(x): 0.66666667 Elapsed: 0.003 s
Algorithm: PSO f(x): 0.66666667 Elapsed: 0.019 s
Algorithm: DMSPSO f(x): 0.66666667 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): 0.66701749 Elapsed: 0.018 s
Algorithm: CMAES f(x): 0.66666667 Elapsed: 0.016 s
Algorithm: BIPOP_aCMAES f(x): 0.66666667 Elapsed: 0.015 s
Algorithm: Scipy Nelder-Mead f(x): 0.66666667 Elapsed: 0.083 s
Algorithm: Scipy L-BFGS-B f(x): 0.66666667 Elapsed: 0.015 s
Algorithm: Scipy DA f(x): 0.66666667 Elapsed: 0.391 s
Function: eosom
Algorithm: DE f(x): -0.0090056781 Elapsed: 0.027 s
Algorithm: ABC f(x): -0.0090054897 Elapsed: 0.038 s
Algorithm: LSHADE f(x): -0.0090056781 Elapsed: 0.053 s
Algorithm: LSHADE_cnEpSin f(x): -0.0090056781 Elapsed: 0.042 s
Algorithm: JADE f(x): -0.0090056781 Elapsed: 0.033 s
Algorithm: jSO f(x): -0.0090056781 Elapsed: 0.051 s
Algorithm: j2020 f(x): -0.0090056781 Elapsed: 0.091 s
Algorithm: LSRTDE f(x): -0.0090056781 Elapsed: 0.026 s
Algorithm: NLSHADE_RSP f(x): -0.0090056781 Elapsed: 0.035 s
Algorithm: ARRDE f(x): -0.0090056781 Elapsed: 0.045 s
Algorithm: GWO_DE f(x): -0.0090056781 Elapsed: 0.038 s
Algorithm: NelderMead f(x): -7.8737549e-14 Elapsed: 0.012 s
Algorithm: DA f(x): -0.0090056781 Elapsed: 0.087 s
Algorithm: L_BFGS_B f(x): 2.8026392e-10 Elapsed: 0.000 s
Algorithm: PSO f(x): -0.0090056781 Elapsed: 0.034 s
Algorithm: DMSPSO f(x): -0.0090056781 Elapsed: 0.034 s
Algorithm: SPSO2011 f(x): -0.0090056781 Elapsed: 0.038 s
Algorithm: CMAES f(x): -0.0090056781 Elapsed: 0.042 s
Algorithm: BIPOP_aCMAES f(x): -8.1207696e-09 Elapsed: 0.000 s
Algorithm: Scipy Nelder-Mead f(x): -0.0090056781 Elapsed: 0.011 s
Algorithm: Scipy L-BFGS-B f(x): -1.4567312e-07 Elapsed: 0.001 s
Algorithm: Scipy DA f(x): -0.009005677 Elapsed: 0.284 s
Function: hgbat
Algorithm: DE f(x): 0.50000754 Elapsed: 0.016 s
Algorithm: ABC f(x): 0.51557989 Elapsed: 0.015 s
Algorithm: LSHADE f(x): 0.50010291 Elapsed: 0.026 s
Algorithm: LSHADE_cnEpSin f(x): 0.50000301 Elapsed: 0.022 s
Algorithm: JADE f(x): 0.50000001 Elapsed: 0.024 s
Algorithm: jSO f(x): 0.50001693 Elapsed: 0.030 s
Algorithm: j2020 f(x): 0.50000009 Elapsed: 0.208 s
Algorithm: LSRTDE f(x): 0.50000148 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 0.5000157 Elapsed: 0.021 s
Algorithm: ARRDE f(x): 0.50000217 Elapsed: 0.028 s
Algorithm: GWO_DE f(x): 0.50186633 Elapsed: 0.020 s
Algorithm: NelderMead f(x): 0.5 Elapsed: 0.057 s
Algorithm: DA f(x): 0.50000007 Elapsed: 0.113 s
Algorithm: L_BFGS_B f(x): 0.5000013 Elapsed: 0.003 s
Algorithm: PSO f(x): 0.5000001 Elapsed: 0.014 s
Algorithm: DMSPSO f(x): 0.50000008 Elapsed: 0.015 s
Algorithm: SPSO2011 f(x): 0.50010615 Elapsed: 0.018 s
Algorithm: CMAES f(x): 0.5 Elapsed: 0.023 s
Algorithm: BIPOP_aCMAES f(x): 0.5 Elapsed: 0.043 s
Algorithm: Scipy Nelder-Mead f(x): 0.5000703 Elapsed: 0.046 s
Algorithm: Scipy L-BFGS-B f(x): 0.50000001 Elapsed: 0.030 s
Algorithm: Scipy DA f(x): 0.50000002 Elapsed: 0.387 s
Function: styblinski_tang
Algorithm: DE f(x): -349.2515 Elapsed: 0.022 s
Algorithm: ABC f(x): -391.66154 Elapsed: 0.021 s
Algorithm: LSHADE f(x): -391.65991 Elapsed: 0.033 s
Algorithm: LSHADE_cnEpSin f(x): -391.66165 Elapsed: 0.026 s
Algorithm: JADE f(x): -377.52494 Elapsed: 0.030 s
Algorithm: jSO f(x): -391.66166 Elapsed: 0.035 s
Algorithm: j2020 f(x): -391.66166 Elapsed: 0.156 s
Algorithm: LSRTDE f(x): -391.66166 Elapsed: 0.023 s
Algorithm: NLSHADE_RSP f(x): -391.66165 Elapsed: 0.026 s
Algorithm: ARRDE f(x): -391.66166 Elapsed: 0.033 s
Algorithm: GWO_DE f(x): -391.66157 Elapsed: 0.024 s
Algorithm: NelderMead f(x): -306.84134 Elapsed: 0.034 s
Algorithm: DA f(x): -391.66166 Elapsed: 0.096 s
Algorithm: L_BFGS_B f(x): -320.97806 Elapsed: 0.001 s
Algorithm: PSO f(x): -363.38822 Elapsed: 0.029 s
Algorithm: DMSPSO f(x): -391.66166 Elapsed: 0.023 s
Algorithm: SPSO2011 f(x): -375.97974 Elapsed: 0.024 s
Algorithm: CMAES f(x): -349.2515 Elapsed: 0.017 s
Algorithm: BIPOP_aCMAES f(x): -43.926384 Elapsed: 0.000 s
Algorithm: Scipy Nelder-Mead f(x): -250.29447 Elapsed: 0.050 s
Algorithm: Scipy L-BFGS-B f(x): -292.70462 Elapsed: 0.006 s
Algorithm: Scipy DA f(x): -391.66166 Elapsed: 0.337 s
Function: step
Algorithm: DE f(x): 0 Elapsed: 0.014 s
Algorithm: ABC f(x): 0 Elapsed: 0.012 s
Algorithm: LSHADE f(x): 0 Elapsed: 0.024 s
Algorithm: LSHADE_cnEpSin f(x): 0 Elapsed: 0.017 s
Algorithm: JADE f(x): 0 Elapsed: 0.021 s
Algorithm: jSO f(x): 0 Elapsed: 0.026 s
Algorithm: j2020 f(x): 0 Elapsed: 0.101 s
Algorithm: LSRTDE f(x): 0 Elapsed: 0.018 s
Algorithm: NLSHADE_RSP f(x): 0 Elapsed: 0.016 s
Algorithm: ARRDE f(x): 0 Elapsed: 0.023 s
Algorithm: GWO_DE f(x): 0 Elapsed: 0.015 s
Algorithm: NelderMead f(x): 98 Elapsed: 0.002 s
Algorithm: DA f(x): 0 Elapsed: 0.092 s
Algorithm: L_BFGS_B f(x): 103 Elapsed: 0.000 s
Algorithm: PSO f(x): 0 Elapsed: 0.011 s
Algorithm: DMSPSO f(x): 0 Elapsed: 0.012 s
Algorithm: SPSO2011 f(x): 0 Elapsed: 0.016 s
Algorithm: CMAES f(x): 0 Elapsed: 0.003 s
Algorithm: BIPOP_aCMAES f(x): 0 Elapsed: 0.001 s
Algorithm: Scipy Nelder-Mead f(x): 256 Elapsed: 0.011 s
Algorithm: Scipy L-BFGS-B f(x): 256 Elapsed: 0.001 s
Algorithm: Scipy DA f(x): 0 Elapsed: 0.297 s
Function: weierstrass
Algorithm: DE f(x): 3.9136649 Elapsed: 1.006 s
Algorithm: ABC f(x): 2.3385699 Elapsed: 1.012 s
Algorithm: LSHADE f(x): 1.697586 Elapsed: 0.980 s
Algorithm: LSHADE_cnEpSin f(x): 2.3747279 Elapsed: 1.051 s
Algorithm: JADE f(x): 0.62136377 Elapsed: 1.112 s
Algorithm: jSO f(x): 5.4126659 Elapsed: 1.567 s
Algorithm: j2020 f(x): 3.0273366 Elapsed: 1.165 s
Algorithm: LSRTDE f(x): 6.1535828 Elapsed: 0.958 s
Algorithm: NLSHADE_RSP f(x): 2.4954729 Elapsed: 1.008 s
Algorithm: ARRDE f(x): 0.79719085 Elapsed: 1.010 s
Algorithm: GWO_DE f(x): 8.0630304 Elapsed: 0.992 s
Algorithm: NelderMead f(x): 16.331325 Elapsed: 0.170 s
Algorithm: DA f(x): 7.5268862 Elapsed: 0.902 s
Algorithm: L_BFGS_B f(x): 17.260631 Elapsed: 0.571 s
Algorithm: PSO f(x): 0.024844903 Elapsed: 0.907 s
Algorithm: DMSPSO f(x): 2.7785439 Elapsed: 0.917 s
Algorithm: SPSO2011 f(x): 10.019956 Elapsed: 0.897 s
Algorithm: CMAES f(x): 0.0019573283 Elapsed: 0.914 s
Algorithm: BIPOP_aCMAES f(x): 10.027648 Elapsed: 0.931 s
Algorithm: Scipy Nelder-Mead f(x): 6.4472257 Elapsed: 0.148 s
Algorithm: Scipy L-BFGS-B f(x): 16.582908 Elapsed: 0.166 s
Algorithm: Scipy DA f(x): 3.9593389 Elapsed: 1.191 s
Function: sum_squares
Algorithm: DE f(x): 2.8608641e-05 Elapsed: 0.013 s
Algorithm: ABC f(x): 1.7911789e-06 Elapsed: 0.012 s
Algorithm: LSHADE f(x): 8.4431439e-08 Elapsed: 0.026 s
Algorithm: LSHADE_cnEpSin f(x): 9.2480663e-11 Elapsed: 0.018 s
Algorithm: JADE f(x): 3.3212172e-18 Elapsed: 0.019 s
Algorithm: jSO f(x): 6.4938347e-10 Elapsed: 0.024 s
Algorithm: j2020 f(x): 1.8269335e-12 Elapsed: 0.118 s
Algorithm: LSRTDE f(x): 1.8604918e-10 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 1.1120999e-10 Elapsed: 0.019 s
Algorithm: ARRDE f(x): 3.0589539e-24 Elapsed: 0.027 s
Algorithm: GWO_DE f(x): 1.9931301e-05 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 8.310147e-30 Elapsed: 0.044 s
Algorithm: DA f(x): 2.1728419e-14 Elapsed: 0.082 s
Algorithm: L_BFGS_B f(x): 5.0791404e-13 Elapsed: 0.001 s
Algorithm: PSO f(x): 2.1701935e-14 Elapsed: 0.013 s
Algorithm: DMSPSO f(x): 1.4260877e-14 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): 8.9292414e-06 Elapsed: 0.016 s
Algorithm: CMAES f(x): 2.6773219e-13 Elapsed: 0.009 s
Algorithm: BIPOP_aCMAES f(x): 9.9939703e-11 Elapsed: 0.007 s
Algorithm: Scipy Nelder-Mead f(x): 1.6899228e-08 Elapsed: 0.033 s
Algorithm: Scipy L-BFGS-B f(x): 1.8569864e-11 Elapsed: 0.004 s
Algorithm: Scipy DA f(x): 3.4901676e-10 Elapsed: 0.305 s
Minimizing Expensive Functions with Multithreading/Multiprocessing
When the objective function is expensive to evaluate, multithreading can be used to speed up the calculation of the vectorized objective function. However, this requires that the objective function is thread-safe.
If the objective function is not thread-safe, then multiprocessing can be used instead. This approach allows parallel execution across separate processes, which avoids the potential issues with thread safety.
Example to vectorize a thread-safe function using multithreading and multiprocessing
If the function is thread-safe to call cuncurrently, then we can safely use concurrent.futures.ThreadPoolExecutor (for multithreading) or concurrent.futures.ProcessPoolExecutor (for multiproceesing) directly.
[5]:
# Function to minimize (expensive to evaluate)
def func(x):
ret = rosenbrock(x)
time.sleep(0.01) # Simulate expensive computation
return ret
# Parallel execution setup
Nthreads = 8
use_threads = True # Toggle between ThreadPoolExecutor and ProcessPoolExecutor
if use_threads:
executor = concurrent.futures.ThreadPoolExecutor(max_workers=Nthreads)
else:
executor = concurrent.futures.ProcessPoolExecutor(max_workers=Nthreads)
def objective_function(X):
return list(executor.map(func, X)) # Batch evaluation in parallel
# Optimization problem settings
dimension = 10
maxevals = 1000
x0 = [[3.0] * dimension]
bounds = [(-10, 10)] * dimension
# List of algorithms to test
algorithms = {
"ARRDE": {"options": None},
"L_BFGS_B": {"options": {"func_noise_ratio": 0.0, "N_points_derivative": 1}},
"DA": {"options": None}
}
print("\nOptimization Results:")
print("=" * 100)
# Run optimizations using Minion
for algo, settings in algorithms.items():
start_time = time.time()
minimizer = mpy.Minimizer(
func=objective_function,
x0=x0,
bounds=bounds,
algo=algo,
relTol=0.0,
maxevals=maxevals,
callback=None,
seed=None,
options=settings["options"]
)
result = minimizer.optimize()
elapsed = time.time() - start_time
print(f"Algo : {algo:<30} | f(x) = {result.fun:<20.8g} | Elapsed: {elapsed:.2f} sec")
# Compare with SciPy optimizers (without multithreading)
for algo, opt_func in [
("Scipy Dual Annealing", dual_annealing),
("Scipy L-BFGS-B", minimize)
]:
start_time = time.time()
if algo == "Scipy Dual Annealing":
result = opt_func(func, bounds=bounds, maxfun=maxevals, no_local_search=False, x0=x0[0])
else:
result = opt_func(func, x0=x0[0], method="L-BFGS-B", options={"maxfun": maxevals}, bounds=bounds)
elapsed = time.time() - start_time
print(f"Algo : {algo:<30} | f(x) = {result.fun:<20.8g} | Elapsed: {elapsed:.2f} sec")
print("=" * 100)
# Shutdown executor gracefully
executor.shutdown()
Optimization Results:
====================================================================================================
Algo : ARRDE | f(x) = 112.52055 | Elapsed: 1.62 sec
Algo : L_BFGS_B | f(x) = 100 | Elapsed: 1.68 sec
Algo : DA | f(x) = 100 | Elapsed: 3.70 sec
Algo : Scipy Dual Annealing | f(x) = 100 | Elapsed: 10.34 sec
Algo : Scipy L-BFGS-B | f(x) = 100 | Elapsed: 4.42 sec
====================================================================================================
The algorithms implemented in Minion (ARRDE, L-BFGS-B, and Dual Annealing) significantly outperform their SciPy counterparts in speed. This performance improvement stems from Minion’s efficient numerical derivative computation, which batches function evaluations—an approach that greatly benefits minion’s L-BFGS-B and Dual Annealing. Note that dual annealing use L-BFGS-B for local search.
Using minionpy.Thread_Parallel to vectorize non-thread-safe member function
In the previous example, we demonstrated how to minimize a thread-safe function. However, in real-world scenarios, the objective function is often a method of a class, and class methods are typically not thread-safe. In this example, we demonstrate how to minimize a non-thread-safe function using the Thread_Parallel class. This approach ensures proper parallelization even when the objective function modifies internal state, which can lead to race conditions in a multi-threaded
environment.
1. Define the Class with objective_function
First, define a class that includes the objective_function. This function should accept a list of floats as input and return a single float as the output. In this example, the objective_function modifies an internal state, which makes it non-thread-safe. We will show how the minionpy Thread_Parallel class manages the parallel execution of such functions while ensuring thread isolation.
[6]:
class Objective :
"""
This illustrate a class with a non-thread-safe self.objective_function
"""
def __init__ (self, b) :
self.A=None # There is a now class member that will be modified when self.objective_function is called.
self.b = b
def update_A(self, x) :
self.A = self.b*np.sin(x) #modify self.A
time.sleep(0.05) #simulate an expensive function
def objective_function(self, x) :
self.update_A(x)
ret = np.sum(self.A*x)
#print(x, ret)
return ret
2. Define the Thread_Parallel object
[7]:
# Here, we vectorize `Objective.objective_function` using 8 threads, with the `b` parameter in the Objective class constructor set to `0.2`.
t_parallel = mpy.Thread_Parallel(8, Objective, 0.2)
#You can test the vectorization as follows :
X = np.random.rand(8, 8) #randomly creates 6 vectors of dimension 8
start = time.time()
res = t_parallel(X)
print("Vectorization using Thread_Parallel : \n\t", res)
print("Elapsed : ", time.time()-start, "\n")
obj=Objective(b=0.2)
start = time.time()
res2 = [obj.objective_function(x) for x in X]
print("Calling the function sequentially : \n\t", res2)
print("Elapsed : ", time.time()-start, "\n")
#test if res and res2 are exactly the same
print(np.array(res).all() == np.array(res2).all())
Vectorization using Thread_Parallel :
[0.5661370676468356, 0.7775659672127234, 0.4229914027614482, 0.5303959761143511, 0.3761453211372047, 0.5522159710759306, 0.38951343396507465, 0.556718173281366]
Elapsed : 0.05110669136047363
Calling the function sequentially :
[0.5661370676468356, 0.7775659672127234, 0.4229914027614482, 0.5303959761143511, 0.3761453211372047, 0.5522159710759306, 0.38951343396507465, 0.556718173281366]
Elapsed : 0.40199875831604004
True
3. Minimize using one of minionpy algorithms
[8]:
dimension = 8 #set dimension of the problem
maxevals = 1000 #number of function calls
x0 = [[3.0]*dimension] # initial guess
bounds = [(-10, 10)]*dimension
algo = "ARRDE"
now = time.time()
min = mpy.Minimizer(func=t_parallel, x0=x0, bounds=bounds, algo=algo, relTol=0.0,
maxevals=maxevals, callback=None, seed=None, options={"population_size": 0})
result = min.optimize()
elapsed= time.time()-now
print("Algo : ",algo, "\n\t x : ", result.x, "\n\t f(x) : ", result.fun, "\n\t Elapsed: ", elapsed, " seconds\n")
print("Test function value : ", Objective(b=0.2).objective_function(np.asarray(result.x)))
Algo : ARRDE
x : [-4.8745482242483, 4.2532696314673295, 4.636776364023326, -4.935053006852719, -4.893801687256062, 4.2541727836417795, -4.5347783796462, 5.555873294650024]
f(x) : -6.969264085741495
Elapsed: 7.983117580413818 seconds
Test function value : -6.969264085741495
We can observe that the minimum found by the ARRDE algorithm corresponds to the correct function value. But what happens if we use ThreadPoolExecutor without considering the thread-safety of the objective_function method?
[9]:
obj = Objective(b=0.2)
executor = concurrent.futures.ThreadPoolExecutor(max_workers=8)
def vectorize_obj(X) :
ret = list(executor.map(obj.objective_function, np.asarray(X)))
return ret
now = time.time()
min = mpy.Minimizer(func=vectorize_obj, x0=x0, bounds=bounds, algo=algo, relTol=0.0, maxevals=maxevals, callback=None, seed=None, options=None)
result = min.optimize()
elapsed= time.time()-now
print("Algo : ",algo, "\n\t x : ", result.x, "\n\t f(x) : ", result.fun, "\n\t Elapsed: ", elapsed, " seconds\n")
print("Test function value :", obj.objective_function(np.asarray(result.x)))
executor.shutdown(wait=True)
Algo : ARRDE
x : [-4.9085261023046725, 9.855798668604562, 5.326274488405682, -9.870938023916791, -6.328512976971076, -9.748500557841409, -9.603724177180414, 9.362136235173324]
f(x) : -7.418963223826018
Elapsed: 7.983393907546997 seconds
Test function value : -4.296564752042263
We can see that the function value of the minimum is not the same as the actual function value.
Using multiprocessing for non-thread-safe functions using minionpy.Process_Parallel
If multiprocessing is preferred over multithreading—whether to bypass the Global Interpreter Lock (GIL) or to ensure clean separation of data during objective function vectorization—minionpy provides the Process_Parallel feature. It follows the same usage rules as Thread_Parallel. When using Process_Parallel, a predefined number of reusable processes are created, each with its own instance of the class object.
[10]:
p_parallel = mpy.Process_Parallel(8, Objective, 0.2)
#You can test the vectorization as follows :
start = time.time()
X = np.random.rand(8, 6) #randomly creates 6 vectors of dimension 8
res = p_parallel(X)
print("Vectorization using Process_Parallel : \n\t", res)
print("Elapsed : ", time.time()-start, "\n")
obj=Objective(b=0.2)
start = time.time()
res2 = [obj.objective_function(x) for x in X]
print("Calling the function sequentially : \n\t", res2)
print("Elapsed : ", time.time()-start, "\n")
#test if res and res2 are exactly the same
print(np.array(res).all() == np.array(res2).all())
Vectorization using Process_Parallel :
[0.5304442646984987, 0.20451016023783655, 0.10655265370931162, 0.2714407459077475, 0.2980790126820181, 0.315356307197812, 0.19289203891937706, 0.440687150822349]
Elapsed : 0.12279987335205078
Calling the function sequentially :
[0.5304442646984987, 0.20451016023783655, 0.10655265370931162, 0.2714407459077475, 0.2980790126820181, 0.315356307197812, 0.19289203891937706, 0.440687150822349]
Elapsed : 0.4028041362762451
True
[11]:
dimension = 8 #set dimension of the problem
maxevals = 1000 #number of function calls
x0 = [[3.0]*dimension] # initial guess
bounds = [(-10, 10)]*dimension
algo = "ARRDE"
now = time.time()
min = mpy.Minimizer(func=p_parallel, x0=x0, bounds=bounds, algo=algo, relTol=0.0,
maxevals=maxevals, callback=None, seed=None, options={"population_size": 0})
result = min.optimize()
elapsed= time.time()-now
print("Algo : ",algo, "\n\t x : ", result.x, "\n\t f(x) : ", result.fun, "\n\t Elapsed: ", elapsed, " seconds\n")
print("Test function value : ", Objective(b=0.2).objective_function(np.asarray(result.x)))
Algo : ARRDE
x : [-5.292044833018368, 4.166986458579692, 4.488022614476481, 5.0228088678480765, 5.23266594020464, -4.826695879758527, -1.209896518319117, 4.336840773972577]
f(x) : -5.877285885951624
Elapsed: 8.18626880645752 seconds
Test function value : -5.877285885951624
Algorithm Comparisons Using CEC Benchmark Problems
We can compare the performance of different optimization algorithms by evaluating them on benchmark problems from the Congress on Evolutionary Computation (CEC) competition. The Minion library provides implementations of benchmark problems from the following CEC years: 2011, 2014, 2017, 2019, 2020, and 2022.
CEC2014 and CEC2017: These benchmarks contain 30 problems, implemented for dimensions 10, 20, 30, 50, and 100.
CEC2019: This set includes 10 problems with varying dimensions.
CEC2020: It contains 10 problems with dimensions 5, 10, 15, and 20.
CEC2022: This set consists of 12 problems with dimensions 10 and 20.
CEC problems typically include a variety of function types:
Basic functions (e.g., Rosenbrock, Rastrigin),
Hybrid functions (new functions constructed by combining basic functions, where each component is evaluated using a different basic function),
Composite functions (linear combinations of basic functions, where the coefficients are also functions of the input vector).
These functions are often shifted and rotated to introduce additional complexity.
CEC2011 consists of a set of real-world problems, idealized and simplified for the competition. It contains 22 problems of varying dimensions. Note that, for CEC2011, MATLAB must be installed on the system. An example of how to minimize CEC2011 problems can be found in examples/cec_11.py.
[12]:
import threading
import concurrent.futures
# This script minimizes CEC benchmark problems, repeated for NRuns times.
# Global results variable
results = []
results_lock = threading.Lock()
def test_optimization(func, bounds, dimension, func_name, Nmaxeval, seed):
"""Runs optimization algorithms on a given function and stores the results."""
global results
result = {
"Dimensions": dimension,
"Function": func_name
}
bounds_list = [bounds] * dimension
x0 = [[0.0 for _ in range(dimension)]]
print(f"\nRunning optimization for {func_name} (Dimension: {dimension})")
print("=" * 60)
for algo in algos:
res = mpy.Minimizer(
func, bounds_list, x0=x0, relTol=0.0, algo=algo,
maxevals=Nmaxeval, callback=None, seed=None,
options={
"population_size" : 0, #2*dimension,
"func_noise_ratio" : 0.0,
"N_points_derivative": 1,
"bound_strategy" : "none"
}
).optimize()
result[algo] = res.fun
print(f" {algo:<15} f(x): {res.fun:<20.8g}")
def func_scipy(par):
return func([par])[0]
# SciPy Optimizers
scipy_algorithms = [
("Scipy L-BFGS-B", minimize, {"x0": x0[0], "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}, "bounds": bounds_list}),
("Scipy Nelder-Mead", minimize, {"x0": x0[0], "method": "Nelder-Mead", "bounds": bounds_list, "options": {"maxfev": Nmaxeval, "adaptive": True}}),
("Scipy DA", dual_annealing, {"bounds": bounds_list, "maxfun": Nmaxeval, "no_local_search": False, "x0": x0[0]}),
]
for name, func_opt, kwargs in scipy_algorithms:
res = func_opt(func_scipy, **kwargs)
result[name] = res.fun
print(f" {name:<15} f(x): {res.fun:<20.8g}")
with results_lock:
results.append(result)
print("-" * 60)
def run_test_optimization(j, dim, year=2017, seed=None):
"""Runs the optimization for a specific function and CEC benchmark year."""
cec_func_classes = {
2014: mpy.CEC2014Functions,
2017: mpy.CEC2017Functions,
2019: mpy.CEC2019Functions,
2020: mpy.CEC2020Functions,
2022: mpy.CEC2022Functions
}
if year not in cec_func_classes:
raise Exception("Unknown CEC year.")
cec_func = cec_func_classes[year](function_number=j, dimension=dim)
test_optimization(cec_func, (-100, 100), dim, f"func_{j}", Nmaxeval, seed)
# List of algorithms to be tested
algos = [
"DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
"ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES"
]
Nmaxeval = 200000 # Maximum number of function evaluations
dimension = 20
NRuns = 1 # Number of repetitions
year = 2022 # CEC benchmark year
# Function numbers for each CEC year
func_numbers_dict = {
2022: list(range(1, 13)),
2020: list(range(1, 11)),
2019: list(range(1, 11)),
2017: list(range(1, 31)),
2014: list(range(1, 31)),
}
func_numbers = func_numbers_dict[year]
# Run optimizations using multi-threading
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
futures = [
executor.submit(run_test_optimization, j, dimension, year, k)
for k in range(NRuns)
for j in func_numbers
]
concurrent.futures.wait(futures)
for f in futures:
f.result()
Running optimization for func_1 (Dimension: 20)
============================================================
DE f(x): 300
ABC f(x): 42484.882
LSHADE f(x): 300
LSHADE_cnEpSin f(x): 300
JADE f(x): 300
jSO f(x): 300
j2020 f(x): 300.00003
LSRTDE f(x): 300
NLSHADE_RSP f(x): 300
ARRDE f(x): 300
GWO_DE f(x): 302.76135
NelderMead f(x): 300
DA f(x): 300
L_BFGS_B f(x): 300
PSO f(x): 300
DMSPSO f(x): 300
SPSO2011 f(x): 300
CMAES f(x): 300
BIPOP_aCMAES f(x): 300
Scipy L-BFGS-B f(x): 300
Scipy Nelder-Mead f(x): 300
Scipy DA f(x): 300
------------------------------------------------------------
Running optimization for func_2 (Dimension: 20)
============================================================
DE f(x): 447.55901
ABC f(x): 407.15048
LSHADE f(x): 400
LSHADE_cnEpSin f(x): 400
JADE f(x): 400
jSO f(x): 400
j2020 f(x): 417.14573
LSRTDE f(x): 444.89547
NLSHADE_RSP f(x): 406.39281
ARRDE f(x): 401.54981
GWO_DE f(x): 415.17322
NelderMead f(x): 403.98662
DA f(x): 419.41087
L_BFGS_B f(x): 449.08448
PSO f(x): 400.02232
DMSPSO f(x): 400.38118
SPSO2011 f(x): 449.08461
CMAES f(x): 449.08448
BIPOP_aCMAES f(x): 400
Scipy L-BFGS-B f(x): 449.08448
Scipy Nelder-Mead f(x): 449.08451
Scipy DA f(x): 449.08448
------------------------------------------------------------
Running optimization for func_3 (Dimension: 20)
============================================================
DE f(x): 614.63684
ABC f(x): 600
LSHADE f(x): 600
LSHADE_cnEpSin f(x): 600
JADE f(x): 600
jSO f(x): 600
j2020 f(x): 600
LSRTDE f(x): 600
NLSHADE_RSP f(x): 600
ARRDE f(x): 600
GWO_DE f(x): 600
NelderMead f(x): 668.52549
DA f(x): 600.00018
L_BFGS_B f(x): 668.52549
PSO f(x): 602.1189
DMSPSO f(x): 603.30578
SPSO2011 f(x): 600.74689
CMAES f(x): 600.0014
BIPOP_aCMAES f(x): 600
Scipy L-BFGS-B f(x): 668.5255
Scipy Nelder-Mead f(x): 668.01149
Scipy DA f(x): 600.00025
------------------------------------------------------------
Running optimization for func_4 (Dimension: 20)
============================================================
DE f(x): 855.74959
ABC f(x): 903.25862
LSHADE f(x): 815.61138
LSHADE_cnEpSin f(x): 806.08713
JADE f(x): 810.98604
jSO f(x): 805.9698
j2020 f(x): 816.60306
LSRTDE f(x): 803.97984
NLSHADE_RSP f(x): 860.76871
ARRDE f(x): 808.95884
GWO_DE f(x): 816.91429
NelderMead f(x): 890.54093
DA f(x): 882.58133
L_BFGS_B f(x): 890.54093
PSO f(x): 869.64682
DMSPSO f(x): 865.66707
SPSO2011 f(x): 816.28376
CMAES f(x): 811.9395
BIPOP_aCMAES f(x): 815.91933
Scipy L-BFGS-B f(x): 890.54093
Scipy Nelder-Mead f(x): 883.57629
Scipy DA f(x): 890.54093
------------------------------------------------------------
Running optimization for func_5 (Dimension: 20)
============================================================
DE f(x): 997.54474
ABC f(x): 3323.5121
LSHADE f(x): 900
LSHADE_cnEpSin f(x): 900
JADE f(x): 900
jSO f(x): 900
j2020 f(x): 900
LSRTDE f(x): 900
NLSHADE_RSP f(x): 900
ARRDE f(x): 900
GWO_DE f(x): 900
NelderMead f(x): 2456.1107
DA f(x): 3071.5902
L_BFGS_B f(x): 2458.8608
PSO f(x): 1440.6716
DMSPSO f(x): 905.12867
SPSO2011 f(x): 900.54385
CMAES f(x): 900
BIPOP_aCMAES f(x): 900.99818
Scipy L-BFGS-B f(x): 2458.8608
Scipy Nelder-Mead f(x): 2457.1933
Scipy DA f(x): 2561.3842
------------------------------------------------------------
Running optimization for func_6 (Dimension: 20)
============================================================
DE f(x): 1971.8282
ABC f(x): 5574.1072
LSHADE f(x): 1806.1336
LSHADE_cnEpSin f(x): 1800.3056
JADE f(x): 1898.8808
jSO f(x): 1800.4832
j2020 f(x): 1901.664
LSRTDE f(x): 1800.4834
NLSHADE_RSP f(x): 1887.2841
ARRDE f(x): 1841.3002
GWO_DE f(x): 11668.098
NelderMead f(x): 1844.2033
DA f(x): 1808.1163
L_BFGS_B f(x): 1909.0077
PSO f(x): 3848.7742
DMSPSO f(x): 10168.1
SPSO2011 f(x): 4657.2054
CMAES f(x): 1806.9352
BIPOP_aCMAES f(x): 1859.0192
Scipy L-BFGS-B f(x): 1872.5365
Scipy Nelder-Mead f(x): 2054.1894
Scipy DA f(x): 1814.9411
------------------------------------------------------------
Running optimization for func_7 (Dimension: 20)
============================================================
DE f(x): 2027.7862
ABC f(x): 2033.9782
LSHADE f(x): 2025.7557
LSHADE_cnEpSin f(x): 2021.0581
JADE f(x): 2024.9837
jSO f(x): 2022.072
j2020 f(x): 2023.9772
LSRTDE f(x): 2001.3071
NLSHADE_RSP f(x): 2021.717
ARRDE f(x): 2023.3001
GWO_DE f(x): 2036.9376
NelderMead f(x): 2526.423
DA f(x): 2112.0289
L_BFGS_B f(x): 2527.3806
PSO f(x): 2070.0527
DMSPSO f(x): 2060.1259
SPSO2011 f(x): 2047.5546
CMAES f(x): 2063.0947
BIPOP_aCMAES f(x): 2021.6167
Scipy L-BFGS-B f(x): 2545.9195
Scipy Nelder-Mead f(x): 2617.3528
Scipy DA f(x): 2092.0307
------------------------------------------------------------
Running optimization for func_8 (Dimension: 20)
============================================================
DE f(x): 2238.4151
ABC f(x): 2223.2242
LSHADE f(x): 2222.6411
LSHADE_cnEpSin f(x): 2216.5047
JADE f(x): 2221.7319
jSO f(x): 2224.0222
j2020 f(x): 2223.5503
LSRTDE f(x): 2224.9593
NLSHADE_RSP f(x): 2221.0833
ARRDE f(x): 2222.3926
GWO_DE f(x): 2230.2027
NelderMead f(x): 2636.8799
DA f(x): 2381.8641
L_BFGS_B f(x): 2991.1908
PSO f(x): 2222.561
DMSPSO f(x): 2222.4891
SPSO2011 f(x): 2227.6319
CMAES f(x): 2220.3577
BIPOP_aCMAES f(x): 2220.64
Scipy L-BFGS-B f(x): 2933.0533
Scipy Nelder-Mead f(x): 2890.3671
Scipy DA f(x): 2221.8949
------------------------------------------------------------
Running optimization for func_9 (Dimension: 20)
============================================================
DE f(x): 2465.3437
ABC f(x): 2480.7875
LSHADE f(x): 2465.3435
LSHADE_cnEpSin f(x): 2465.3435
JADE f(x): 2465.3435
jSO f(x): 2465.3435
j2020 f(x): 2465.3435
LSRTDE f(x): 2480.7813
NLSHADE_RSP f(x): 2465.3435
ARRDE f(x): 2465.3435
GWO_DE f(x): 2465.3435
NelderMead f(x): 2465.3435
DA f(x): 2467.4003
L_BFGS_B f(x): 2480.7813
PSO f(x): 2465.3435
DMSPSO f(x): 2465.3435
SPSO2011 f(x): 2480.804
CMAES f(x): 2480.7813
BIPOP_aCMAES f(x): 2465.3435
Scipy L-BFGS-B f(x): 2480.7813
Scipy Nelder-Mead f(x): 2480.8289
Scipy DA f(x): 2480.7813
------------------------------------------------------------
Running optimization for func_10 (Dimension: 20)
============================================================
DE f(x): 2500.5172
ABC f(x): 2400.1877
LSHADE f(x): 2400.4037
LSHADE_cnEpSin f(x): 2500.2849
JADE f(x): 2500.4683
jSO f(x): 2500.3194
j2020 f(x): 2400.1874
LSRTDE f(x): 2500.3617
NLSHADE_RSP f(x): 2500.4406
ARRDE f(x): 2400.0625
GWO_DE f(x): 2618.8727
NelderMead f(x): 6169.0617
DA f(x): 2425.1178
L_BFGS_B f(x): 6109.5459
PSO f(x): 3083.2547
DMSPSO f(x): 2632.1121
SPSO2011 f(x): 2500.3924
CMAES f(x): 3359.1873
BIPOP_aCMAES f(x): 2500.6549
Scipy L-BFGS-B f(x): 6287.3523
Scipy Nelder-Mead f(x): 5683.4727
Scipy DA f(x): 2400.0937
------------------------------------------------------------
Running optimization for func_11 (Dimension: 20)
============================================================
DE f(x): 3023.9238
ABC f(x): 2672.2987
LSHADE f(x): 2900
LSHADE_cnEpSin f(x): 3000
JADE f(x): 3000
jSO f(x): 2900
j2020 f(x): 2905.675
LSRTDE f(x): 3000
NLSHADE_RSP f(x): 2900
ARRDE f(x): 2900
GWO_DE f(x): 3000
NelderMead f(x): 3000
DA f(x): 2900
L_BFGS_B f(x): 2900
PSO f(x): 2900
DMSPSO f(x): 2900
SPSO2011 f(x): 2900
CMAES f(x): 2900
BIPOP_aCMAES f(x): 2900
Scipy L-BFGS-B f(x): 2900
Scipy Nelder-Mead f(x): 2900.0004
Scipy DA f(x): 2900
------------------------------------------------------------
Running optimization for func_12 (Dimension: 20)
============================================================
DE f(x): 2892.4733
ABC f(x): 2947.1646
LSHADE f(x): 2900.0039
LSHADE_cnEpSin f(x): 2900.004
JADE f(x): 2900.0041
jSO f(x): 2900.0038
j2020 f(x): 2900.0042
LSRTDE f(x): 2933.6674
NLSHADE_RSP f(x): 2900.004
ARRDE f(x): 2900.0043
GWO_DE f(x): 2900.004
NelderMead f(x): 5490.2128
DA f(x): 2900.0049
L_BFGS_B f(x): 5113.3733
PSO f(x): 2893.2191
DMSPSO f(x): 2900.0048
SPSO2011 f(x): 2940.0228
CMAES f(x): 2963.1768
BIPOP_aCMAES f(x): 2900.0048
Scipy L-BFGS-B f(x): 3382.9172
Scipy Nelder-Mead f(x): 5108.8009
Scipy DA f(x): 3059.5899
------------------------------------------------------------
Example of using minion/py in curve fitting problems
Here, an example of using minion to minimize an objective function related to a curve fitting problem is demonstrated. The idea is first to define the data generation model, generate the data, fit the model, and report the result.
Polynomial Fitting Problems
In this problem, we try fit a polynomial from a set of data. Specifically, a set of points (\(\{(x_i, y_i) \mid i = 1, 2, \dots, N\}\)) with \(x \in [0, 1]\) is generated according to:
Given the coefficients \(a_j\) that generate the data, the goal is to reproduce the data points by minimizing the objective function:
[13]:
# Step 1: Generate Data Points from a Polynomial
dimension = 10 # Number of free parameters (polynomial degree is dimension - 1)
np.random.seed(8) # For reproducibility
# True polynomial coefficients (random values)
true_coefficients = [np.random.uniform(-1.0, 1.0) * (1.0 ** i) for i in range(dimension)]
# Generate data points
x_data = np.linspace(0.0, 1, dimension + 10)
y_data = np.polyval(true_coefficients, x_data)
# Step 2: Define the Polynomial Model
def polynomial_model(x, coefficients):
"""Evaluate a polynomial at x given the coefficients."""
return np.polyval(coefficients, x)
# Step 3: Define the Objective Function
def objective_function(coefficients):
"""Compute the mean squared error between the polynomial model and data points."""
y_pred = polynomial_model(x_data, coefficients)
return np.mean((y_data - y_pred) ** 2)
def objective_function_vect(X):
"""Vectorized version of the objective function for batch optimization."""
return [objective_function(x) for x in X]
# Optimization Settings
bounds = [(-10, 10)] * dimension
Nmaxeval = 20000
algos = [
"DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
"ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES"
]
# Step 4: Minimize the Objective Function and Plot Results
plt.figure(figsize=(6, 4))
plt.scatter(x_data, y_data, label="Data Points", color="black", marker="o", zorder=3)
x0 = [[0.0 for _ in range(dimension)]]
print("\nOptimization Results:")
print("=" * 50)
# Run Optimization with Custom Algorithms
for algo in algos:
res = mpy.Minimizer(
objective_function_vect, bounds, x0=x0, relTol=0.0,
algo=algo, maxevals=Nmaxeval, callback=None, seed=0,
options={
"population_size": 0,
"func_noise_ratio" : 0.0,
"N_points_derivative": 1}
).optimize()
print(f"{algo:<30}: f(x) = {res.fun:<20.8g}")
plt.plot(x_data, polynomial_model(x_data, res.x), label=algo, linewidth=1.2, alpha=0.7)
# Run SciPy Optimizers
scipy_algorithms = [
("Scipy Dual Annealing (DA)", dual_annealing, {"bounds": bounds, "maxfun": Nmaxeval, "no_local_search": False, "x0": x0[0]}),
("Scipy L-BFGS-B", minimize, {"x0": x0[0], "bounds": bounds, "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}}),
("Scipy Nelder-Mead", minimize, {"x0": x0[0], "bounds": bounds, "method": "Nelder-Mead", "options": {"maxfev": Nmaxeval, "adaptive": True}}),
]
for name, func_opt, kwargs in scipy_algorithms:
res = func_opt(objective_function, **kwargs)
print(f"{name:<30}: f(x) = {res.fun:<20.8g}")
plt.plot(x_data, polynomial_model(x_data, res.x), label=name, linewidth=1.2, alpha=0.7)
print("=" * 50)
# Plot Formatting
plt.legend(loc="upper left", bbox_to_anchor=(1, 1), fontsize=9)
plt.title("Polynomial Fit")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True, linestyle="--", alpha=0.6)
plt.show()
Optimization Results:
==================================================
DE : f(x) = 3.4676234e-07
ABC : f(x) = 0.0056994221
LSHADE : f(x) = 4.0557789e-10
LSHADE_cnEpSin : f(x) = 3.3043359e-14
JADE : f(x) = 5.251496e-08
jSO : f(x) = 9.774338e-11
j2020 : f(x) = 8.4535903e-05
LSRTDE : f(x) = 1.4773705e-12
NLSHADE_RSP : f(x) = 7.1946723e-06
ARRDE : f(x) = 4.2782791e-09
GWO_DE : f(x) = 1.2315456e-05
NelderMead : f(x) = 4.0539659e-15
DA : f(x) = 2.521779e-05
L_BFGS_B : f(x) = 7.2866825e-07
PSO : f(x) = 3.5313431e-05
DMSPSO : f(x) = 2.6368825e-05
SPSO2011 : f(x) = 0.00054992829
CMAES : f(x) = 8.5261952e-12
BIPOP_aCMAES : f(x) = 9.9424922e-11
Scipy Dual Annealing (DA) : f(x) = 7.3242064e-07
Scipy L-BFGS-B : f(x) = 7.3242064e-07
Scipy Nelder-Mead : f(x) = 2.1676521e-11
==================================================
Gaussian Mixture Model Fitting Problems
Thsi time, the model is given by the sum of Gaussian functions:
Here, \(f(x, a, b, c)\) is normalized to represent a probability distribution. The data points are generated using predefined values of \(a_j\), \(b_j\), and \(c_j\) within the interval \(x \in [-20, 20]\). The objective function is the same as in the case of polynomial fitting.
[14]:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, dual_annealing
import concurrent.futures
# Step 1: Generate Data Points from a Gaussian Mixture Model (GMM)
np.random.seed(5) # For reproducibility
num_gauss = 5 # Number of Gaussians
true_centers = 10 * (-1 + 2 * np.random.random(num_gauss)) # Random center positions
true_widths = np.random.rand(num_gauss) + 1.0 # Widths (variances)
true_coeffs = 2.0 * np.random.rand(num_gauss) # Coefficients
dimension = num_gauss * 3 # Total number of free parameters
# Define a Gaussian function
def gauss(x, center, width):
"""Compute a Gaussian value at x given center and width."""
return (1.0 / (2.0 * np.pi * width ** 2)) * 0.5 * np.exp(-((x - center) ** 2) / (2 * width ** 2))
# Define the Gaussian Mixture Model (GMM)
def gmm(x, centers, widths, coeffs):
"""Evaluate the Gaussian Mixture Model (GMM) at x."""
result = np.zeros_like(x)
coeffs = np.array(coeffs)
norm_coeff = coeffs / np.sum(coeffs) # Normalize coefficients
for i in range(len(centers)):
result += norm_coeff[i] * gauss(x, centers[i], widths[i])
return result
# Generate synthetic data
x_data = np.linspace(-20, 20, dimension + 10)
y_data = gmm(x_data, true_centers, true_widths, true_coeffs)
# Step 2: Define the Model for Fitting
def gmm_model(x, params):
"""Compute GMM model values for given parameters."""
num_gauss = len(params) // 3
centers = params[:num_gauss]
widths = params[num_gauss:2*num_gauss]
coeffs = params[2*num_gauss:]
return gmm(x, centers, widths, coeffs)
# Step 3: Define the Objective Function
def objective_function(params):
"""Compute the mean squared error between model and data."""
y_pred = gmm_model(x_data, params)
return np.mean((y_data - y_pred) ** 2)
# Parallelized objective function
executor = concurrent.futures.ThreadPoolExecutor(max_workers=8)
def objective_function_vect(params):
"""Vectorized version of objective function using multithreading."""
return list(executor.map(objective_function, params))
# Optimization Settings
bounds = [(-10, 10)] * dimension
Nmaxeval = 10000
algos = [
"DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
"ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES"
]
x0 = [[1.0 for _ in range(dimension)]]
# Step 4: Minimize the Objective Function and Plot Results
plt.figure(figsize=(6, 4))
plt.scatter(x_data, y_data, label="Data", color="black", marker="o", zorder=3)
print("\nOptimization Results:")
print("=" * 60)
# Run Optimization with Custom Algorithms
for algo in algos:
res = mpy.Minimizer(
objective_function_vect, bounds, x0=x0, relTol=0.0,
algo=algo, maxevals=Nmaxeval, callback=None, seed=None,
options={"population_size": 0}
).optimize()
print(f"{algo:<30}: f(x) = {res.fun:<20.8g}")
plt.plot(x_data, gmm_model(x_data, res.x), label=algo, linewidth=1.2, alpha=0.7)
# Run SciPy Optimizers
scipy_algorithms = [
("Scipy L-BFGS-B", minimize, {"x0": x0[0], "bounds": bounds, "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}}),
("Scipy Dual Annealing", dual_annealing, {"x0": x0[0],"bounds": bounds, "maxfun": Nmaxeval, "no_local_search": False}),
("Scipy Nelder-Mead", minimize, {"x0": x0[0], "bounds": bounds,"method": "Nelder-Mead", "options": {"maxfev": Nmaxeval, "adaptive": True}}),
]
for name, func_opt, kwargs in scipy_algorithms:
res = func_opt(objective_function, **kwargs)
print(f"{name:<30}: f(x) = {res.fun:<20.8g}")
plt.plot(x_data, gmm_model(x_data, res.x), label=name, linewidth=1.2, alpha=0.7)
print("=" * 60)
# Plot Formatting
plt.legend(loc="upper left", bbox_to_anchor=(1, 1), fontsize=9)
plt.title("Gaussian Mixture Model Fit")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True, linestyle="--", alpha=0.6)
plt.show()
executor.shutdown()
Optimization Results:
============================================================
DE : f(x) = 5.7291499e-09
ABC : f(x) = 7.1340783e-07
LSHADE : f(x) = 1.0475381e-06
LSHADE_cnEpSin : f(x) = 4.3458431e-07
JADE : f(x) = 3.621201e-06
jSO : f(x) = 1.5717409e-06
j2020 : f(x) = 1.5987436e-06
LSRTDE : f(x) = 4.9046081e-06
NLSHADE_RSP : f(x) = 5.398718e-07
ARRDE : f(x) = 1.4614777e-06
GWO_DE : f(x) = 3.3096941e-08
NelderMead : f(x) = 7.3549528e-09
DA : f(x) = 3.0671579e-08
L_BFGS_B : f(x) = 1.4374531e-05
PSO : f(x) = 7.9250982e-09
DMSPSO : f(x) = 5.430383e-09
SPSO2011 : f(x) = 3.4595187e-06
CMAES : f(x) = 8.0375181e-09
BIPOP_aCMAES : f(x) = 9.427549e-11
Scipy L-BFGS-B : f(x) = 2.4100192e-05
Scipy Dual Annealing : f(x) = 6.1466906e-06
Scipy Nelder-Mead : f(x) = 4.1184114e-09
============================================================
More complex fitting problem: CT18 PDFs Fitting
Here, we provide a slightly more challenging curve fitting problem. The task is to reproduce the CT18 parton distribution functions (PDFs) \cite{Hou:2019efy}. The parameterization for valence up-quark (\(u_v\)), valence down-quark (\(d_v\)), gluon, anti-\(u\) (\(\bar{u}\)), anti-\(d\) (\(\bar{d}\)), and strange quark (\(s\)) PDFs at the initial scale is given by:
Here, \(P_i(y)\) is a Bernstein polynomial of degree 4, 3, or 5, depending on the specific PDF. The variable \(y\) is defined as \(y = \sqrt{x}\) for \(u_v\), \(d_v\), and \(g\), and as \(y = (1 - (1 - \sqrt{x}))^{a_3}\) for the sea quarks. The objective function is:
where \(i \in \{u_v, d_v, g, \bar{u}, \bar{d}, s\}\). The dimensionality of this problem is \(D = 47\).
[15]:
class CT18PDFs :
def __init__(self) :
self.parameters = {
"uv_0" : 3.385, "uv_1" : 0.763, "uv_2" : 3.036, "uv_3" : 1.502, "uv_4" : -0.147,"uv_5" : 1.671, "uv_6" : 0.,
"dv_0" : 0.490, "dv_1" : 0.763, "dv_2" : 3.036, "dv_3" : 2.615, "dv_4" : 1.828,"dv_5" : 2.721, "dv_6" : 0.,
"g_0" : 2.690, "g_1" : 0.531, "g_2" : 3.148, "g_3" : 3.032, "g_4" : -1.705, "g_5" : 1.354,
"ubar_0" : 0.414, "ubar_1" : -0.022, "ubar_2" : 7.737, "ubar_3" : 4.0, "ubar_4" : 0.618,"ubar_5" : 0.195, "ubar_6" : 0.871, "ubar_7" : 0.267,"ubar_8" : 0.733,
"dbar_0" : 0.414, "dbar_1" : -0.022, "dbar_2" : 7.737, "dbar_3" : 4.0, "dbar_4" : 0.292,"dbar_5" : 0.647, "dbar_6" : 0.474, "dbar_7" : 0.741,"dbar_8" :1.0,
"s_0" : 0.288, "s_1" : -0.022, "s_2" : 10.31, "s_3" : 4.0, "s_4" : 0.466,"s_5" : 0.466, "s_6" : 0.225, "s_7" : 0.225,"s_8" : 1.0,
}
self.xlist = np.linspace(1e-3, 0.8, 50)
self.paramNames = list(self.parameters.keys())
self.originalData = self.getData()
def uv(self, x) :
a0 = self.parameters["uv_0"]
a1 = self.parameters["uv_1"]
a2 = self.parameters["uv_2"]
a3 = self.parameters["uv_3"]
a4 = self.parameters["uv_4"]
a5 = self.parameters["uv_5"]
a6 = self.parameters["uv_6"]
y= np.sqrt(x)
P = np.sinh(a3)*(1-y)**4 + np.sinh(a4) *4*y*(1-y)**3 + np.sinh(a5) *6*y**2*(1-y)**2 + np.sinh(a6) *4*y**3*(1-y) + y**4
return a0 * x**(a1-1)*(1-x)**a2*P
def dv(self, x) :
a0 = self.parameters["dv_0"]
a1 = self.parameters["dv_1"]
a2 = self.parameters["dv_2"]
a3 = self.parameters["dv_3"]
a4 = self.parameters["dv_4"]
a5 = self.parameters["dv_5"]
a6 = self.parameters["dv_6"]
y= np.sqrt(x)
P = np.sinh(a3)*(1-y)**4 + np.sinh(a4) *4*y*(1-y)**3 + np.sinh(a5) *6*y**2*(1-y)**2 + np.sinh(a6) *4*y**3*(1-y) + y**4
return a0 * x**(a1-1)*(1-x)**a2*P
def g(self, x) :
a0 = self.parameters["g_0"]
a1 = self.parameters["g_1"]
a2 = self.parameters["g_2"]
a3 = self.parameters["g_3"]
a4 = self.parameters["g_4"]
a5 = self.parameters["g_5"]
y= np.sqrt(x)
P = np.sinh(a3)*(1-y)**3 + np.sinh(a4) *3*y*(1-y)**2 + np.sinh(a5) *3*y**2*(1-y) + y**3
return a0 * x**(a1-1)*(1-x)**a2*P
def ubar(self, x) :
a0 = self.parameters["ubar_0"]
a1 = self.parameters["ubar_1"]
a2 = self.parameters["ubar_2"]
a3 = self.parameters["ubar_3"]
a4 = self.parameters["ubar_4"]
a5 = self.parameters["ubar_5"]
a6 = self.parameters["ubar_6"]
a7 = self.parameters["ubar_7"]
a8 = self.parameters["ubar_8"]
y= 1-(1-np.sqrt(x))**a3
P = (1-y)**5 + a4 * 5*y*(1-y)**4 + a5 * 10*y**2*(1-y)**3 + a6 * 10*y**3*(1-y)**2 + a7 * 5*y**4*(1-y)+ a8 * 5*y**5
return a0 * x**(a1-1)*(1-x)**a2*P
def dbar(self, x) :
a0 = self.parameters["dbar_0"]
a1 = self.parameters["dbar_1"]
a2 = self.parameters["dbar_2"]
a3 = self.parameters["dbar_3"]
a4 = self.parameters["dbar_4"]
a5 = self.parameters["dbar_5"]
a6 = self.parameters["dbar_6"]
a7 = self.parameters["dbar_7"]
a8 = self.parameters["dbar_8"]
y= 1-(1-np.sqrt(x))**a3
P = (1-y)**5 + a4 * 5*y*(1-y)**4 + a5 * 10*y**2*(1-y)**3 + a6 * 10*y**3*(1-y)**2 + a7 * 5*y**4*(1-y)+ a8 * 5*y**5
return a0 * x**(a1-1)*(1-x)**a2*P
def s(self, x) :
a0 = self.parameters["s_0"]
a1 = self.parameters["s_1"]
a2 = self.parameters["s_2"]
a3 = self.parameters["s_3"]
a4 = self.parameters["s_4"]
a5 = self.parameters["s_5"]
a6 = self.parameters["s_6"]
a7 = self.parameters["s_7"]
a8 = self.parameters["s_8"]
y= 1-(1-np.sqrt(x))**a3
P = (1-y)**5 + a4 * 5*y*(1-y)**4 + a5 * 10*y**2*(1-y)**3 + a6 * 10*y**3*(1-y)**2 + a7 * 5*y**4*(1-y)+ a8 * 5*y**5
return a0 * x**(a1-1)*(1-x)**a2*P
def u(self, x) : return self.uv(x)+self.ubar(x)
def d(self, x) : return self.dv(x)+self.dbar(x)
def setParameter(self, pars) :
assert(len(pars)==len(self.parameters))
self.parameters= dict(zip(self.paramNames, pars))
def getData(self) :
x= self.xlist
return [ x*self.u(self.xlist), x*self.ubar(self.xlist), x*self.d(self.xlist), x*self.dbar(self.xlist), x*self.g(self.xlist), x*self.s(self.xlist)]
def objective_function(self, params):
self.setParameter(params)
data = self.getData()
ret =0
for do, d in zip(self.originalData, data) :
ret = ret + np.sum((do-d)**2)
return ret
[16]:
ct18 = CT18PDFs()
data = ct18.getData()
# Create a 3x2 grid of subplots
fig, axes = plt.subplots(2, 3, figsize=(10, 5))
# List of labels for each plot
labels = ["u", "ubar", "d", "dbar", "g", "s"]
# Plotting each function in its corresponding subplot
for i, ax in enumerate(axes.flatten()):
ax.plot(ct18.xlist, data[i], label=labels[i])
ax.set_xlim(0.1, 0.8)
ax.set_xlabel("x")
if (i%3 == 0):
ax.set_ylabel(r"$xf(x)$")
ax.legend()
plt.subplots_adjust(hspace=0.15, wspace=0.17)
plt.show()
[17]:
# Step 1: Define Problem Dimensions and Settings
dimension = 47
print("Dimension:", dimension)
bounds = [(-10, 10)] * dimension
Nmaxeval = 100000
x0 = [[1.0] * dimension] # Initial guess
# Step 2: Set Up Parallel Execution for CT18PDFs
t_parallel = mpy.Thread_Parallel(4, CT18PDFs) # Vectorize using 4 threads
# Step 3: Define Optimization Algorithms
algos = [
"DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
"ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES"
]
# Step 4: Run Optimization and Collect Results
results = {}
print("\nOptimization Results:")
print("=" * 60)
for algo in algos:
res = mpy.Minimizer(
t_parallel, bounds, x0=x0, algo=algo, relTol=0.0,
maxevals=Nmaxeval, callback=None, seed=None,
options={
"population_size": 0,
"func_noise_ratio" : 0.0,
"N_points_derivative": 1
}
).optimize()
print(f"{algo:<30}: f(x) = {res.fun:<20.8g}")
results[algo] = res
# Step 5: Run SciPy Optimizers
scipy_algorithms = [
("Scipy L-BFGS-B", minimize, {"x0": x0[0], "bounds": bounds, "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}}),
("Scipy Dual Annealing", dual_annealing, {"x0": x0[0],"bounds": bounds, "maxfun": Nmaxeval, "no_local_search": False}),
("Scipy Nelder-Mead", minimize, {"x0": x0[0], "bounds": bounds,"method": "Nelder-Mead", "options": {"maxfev": Nmaxeval, "adaptive": True}}),
]
for name, func_opt, kwargs in scipy_algorithms:
res = func_opt(ct18.objective_function, **kwargs)
print(f"{name:<30}: f(x) = {res.fun:<20.8g}")
results[name] = res
print("=" * 60)
# Step 6: Plot Results
fig, axes = plt.subplots(2, 3, figsize=(12, 6))
labels = ["u-data", "ubar-data", "d-data", "dbar-data", "g-data", "s-data"]
# Plot each dataset in its corresponding subplot
for i, ax in enumerate(axes.flatten()):
ax.plot(ct18.xlist, data[i], label=labels[i], color="black", linestyle="dotted", linewidth=1.2)
# Overlay model predictions for selected algorithms
for algo in ["ARRDE", "DA", "Scipy Dual Annealing", "L_BFGS_B"]:
ct18.setParameter(results[algo].x)
theo = ct18.getData()
ax.plot(ct18.xlist, theo[i], label=algo, linewidth=1.2, alpha=0.8)
ax.set_xlim(0.1, 0.8)
ax.set_xlabel("x")
if i % 3 == 0:
ax.set_ylabel(r"$xf(x)$")
ax.legend(fontsize=9)
plt.tight_layout()
plt.show()
Dimension: 47
Optimization Results:
============================================================
DE : f(x) = 0.19269741
ABC : f(x) = 9.2305563
LSHADE : f(x) = 5.0262623
LSHADE_cnEpSin : f(x) = 0.34919775
JADE : f(x) = 4.6637756
jSO : f(x) = 0.78116151
j2020 : f(x) = 9.9470365
LSRTDE : f(x) = 0.39744395
NLSHADE_RSP : f(x) = 1.0981858
ARRDE : f(x) = 1.2748372
GWO_DE : f(x) = 1.8577235
NelderMead : f(x) = 0.072777402
DA : f(x) = 0.13416323
L_BFGS_B : f(x) = 0.019077562
PSO : f(x) = 0.055286483
DMSPSO : f(x) = 0.327826
SPSO2011 : f(x) = 3.9963909
CMAES : f(x) = 1.0687989
BIPOP_aCMAES : f(x) = 0.47659189
Scipy L-BFGS-B : f(x) = 0.016397197
Scipy Dual Annealing : f(x) = 0.91439194
Scipy Nelder-Mead : f(x) = 0.072777402
============================================================