[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
[2]:
mpy
[2]:
<module 'minionpy' from 'd:\\Developments\\minion\\examples\\..\\minionpy\\__init__.py'>
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.
[3]:
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.9999999999999997, 1.0, 1.0, 0.9999999999999993]
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.
[4]:
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.
[5]:
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", "RCMAES"
]
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): 3.1013248e-13 Elapsed: 0.020 s
Algorithm: ABC f(x): 3.8409276e-07 Elapsed: 0.016 s
Algorithm: LSHADE f(x): 1.2420587e-09 Elapsed: 0.027 s
Algorithm: LSHADE_cnEpSin f(x): 8.0453835e-12 Elapsed: 0.033 s
Algorithm: JADE f(x): 4.9303807e-32 Elapsed: 0.020 s
Algorithm: jSO f(x): 4.3973511e-12 Elapsed: 0.028 s
Algorithm: j2020 f(x): 8.2324161e-13 Elapsed: 0.167 s
Algorithm: LSRTDE f(x): 2.1405603e-12 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 3.8072431e-08 Elapsed: 0.018 s
Algorithm: ARRDE f(x): 6.31914e-22 Elapsed: 0.016 s
Algorithm: GWO_DE f(x): 1.8723707e-06 Elapsed: 0.032 s
Algorithm: NelderMead f(x): 4.6709368e-30 Elapsed: 0.032 s
Algorithm: DA f(x): 1.7722074e-12 Elapsed: 0.106 s
Algorithm: L_BFGS_B f(x): 1.0668492e-13 Elapsed: 0.000 s
Algorithm: PSO f(x): 3.5618553e-14 Elapsed: 0.015 s
Algorithm: DMSPSO f(x): 2.1524914e-15 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): 1.7546543e-08 Elapsed: 0.024 s
Algorithm: CMAES f(x): 2.0057539e-13 Elapsed: 0.011 s
Algorithm: BIPOP_aCMAES f(x): 1.8524367e-27 Elapsed: 0.041 s
Algorithm: RCMAES f(x): 1.4665005e-13 Elapsed: 0.025 s
Algorithm: Scipy Nelder-Mead f(x): 5.8359322e-09 Elapsed: 0.030 s
Algorithm: Scipy L-BFGS-B f(x): 6.9420299e-12 Elapsed: 0.000 s
Algorithm: Scipy DA f(x): 4.2699916e-12 Elapsed: 0.328 s
Function: rosenbrock
Algorithm: DE f(x): 8.4731067 Elapsed: 0.017 s
Algorithm: ABC f(x): 1.2322678 Elapsed: 0.011 s
Algorithm: LSHADE f(x): 2.756665 Elapsed: 0.033 s
Algorithm: LSHADE_cnEpSin f(x): 3.5945221 Elapsed: 0.049 s
Algorithm: JADE f(x): 4.4548818 Elapsed: 0.034 s
Algorithm: jSO f(x): 1.6881663 Elapsed: 0.032 s
Algorithm: j2020 f(x): 6.470444 Elapsed: 0.218 s
Algorithm: LSRTDE f(x): 7.3764536 Elapsed: 0.031 s
Algorithm: NLSHADE_RSP f(x): 4.8143538 Elapsed: 0.019 s
Algorithm: ARRDE f(x): 0.33501158 Elapsed: 0.048 s
Algorithm: GWO_DE f(x): 6.5618449 Elapsed: 0.018 s
Algorithm: NelderMead f(x): 3.1653044e-27 Elapsed: 0.095 s
Algorithm: DA f(x): 1.346784e-13 Elapsed: 0.117 s
Algorithm: L_BFGS_B f(x): 4.307979e-13 Elapsed: 0.008 s
Algorithm: PSO f(x): 3.6620106 Elapsed: 0.015 s
Algorithm: DMSPSO f(x): 3.0666978 Elapsed: 0.019 s
Algorithm: SPSO2011 f(x): 8.3681959 Elapsed: 0.033 s
Algorithm: CMAES f(x): 0.070751751 Elapsed: 0.035 s
Algorithm: BIPOP_aCMAES f(x): 2.4385611e-20 Elapsed: 0.049 s
Algorithm: RCMAES f(x): 2.0289928e-07 Elapsed: 0.043 s
Algorithm: Scipy Nelder-Mead f(x): 8.9958364e-09 Elapsed: 0.071 s
Algorithm: Scipy L-BFGS-B f(x): 1.1088291e-10 Elapsed: 0.031 s
Algorithm: Scipy DA f(x): 1.5264733e-10 Elapsed: 0.329 s
Function: rastrigin
Algorithm: DE f(x): 27.858783 Elapsed: 0.016 s
Algorithm: ABC f(x): 1.020665 Elapsed: 0.031 s
Algorithm: LSHADE f(x): 0.75359441 Elapsed: 0.022 s
Algorithm: LSHADE_cnEpSin f(x): 6.8611038 Elapsed: 0.033 s
Algorithm: JADE f(x): 0 Elapsed: 0.082 s
Algorithm: jSO f(x): 11.979767 Elapsed: 0.017 s
Algorithm: j2020 f(x): 2.9848772 Elapsed: 0.230 s
Algorithm: LSRTDE f(x): 5.2631939 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 2.0455492 Elapsed: 0.018 s
Algorithm: ARRDE f(x): 5.9697544 Elapsed: 0.035 s
Algorithm: GWO_DE f(x): 25.399503 Elapsed: 0.016 s
Algorithm: NelderMead f(x): 102.47964 Elapsed: 0.032 s
Algorithm: DA f(x): 0 Elapsed: 0.105 s
Algorithm: L_BFGS_B f(x): 102.47964 Elapsed: 0.000 s
Algorithm: PSO f(x): 6.9647134 Elapsed: 0.017 s
Algorithm: DMSPSO f(x): 4.9747953 Elapsed: 0.015 s
Algorithm: SPSO2011 f(x): 22.502709 Elapsed: 0.031 s
Algorithm: CMAES f(x): 7.9596674 Elapsed: 0.017 s
Algorithm: BIPOP_aCMAES f(x): 15.292944 Elapsed: 0.050 s
Algorithm: RCMAES f(x): 0.99495906 Elapsed: 0.033 s
Algorithm: Scipy Nelder-Mead f(x): 254.70399 Elapsed: 0.032 s
Algorithm: Scipy L-BFGS-B f(x): 237.78983 Elapsed: 0.000 s
Algorithm: Scipy DA f(x): 0.99495906 Elapsed: 0.356 s
Function: schaffer2
Algorithm: DE f(x): 0.55808408 Elapsed: 0.228 s
Algorithm: ABC f(x): 0.15968907 Elapsed: 0.233 s
Algorithm: LSHADE f(x): 0.2075968 Elapsed: 0.250 s
Algorithm: LSHADE_cnEpSin f(x): 0.19970339 Elapsed: 0.253 s
Algorithm: JADE f(x): 0.091651581 Elapsed: 0.257 s
Algorithm: jSO f(x): 0.89364912 Elapsed: 0.246 s
Algorithm: j2020 f(x): 0.45049547 Elapsed: 0.410 s
Algorithm: LSRTDE f(x): 0.55253902 Elapsed: 0.247 s
Algorithm: NLSHADE_RSP f(x): 0.20241981 Elapsed: 0.290 s
Algorithm: ARRDE f(x): 0.19747585 Elapsed: 0.330 s
Algorithm: GWO_DE f(x): 0.25339952 Elapsed: 0.246 s
Algorithm: NelderMead f(x): 0.18775994 Elapsed: 0.190 s
Algorithm: DA f(x): 0.048579908 Elapsed: 0.284 s
Algorithm: L_BFGS_B f(x): 0.18775994 Elapsed: 0.029 s
Algorithm: PSO f(x): 0.13286684 Elapsed: 0.249 s
Algorithm: DMSPSO f(x): 0.36193056 Elapsed: 0.249 s
Algorithm: SPSO2011 f(x): 0.40766972 Elapsed: 0.250 s
Algorithm: CMAES f(x): 0.44386077 Elapsed: 0.249 s
Algorithm: BIPOP_aCMAES f(x): 0.31475046 Elapsed: 0.252 s
Algorithm: RCMAES f(x): 0.22498402 Elapsed: 0.266 s
Algorithm: Scipy Nelder-Mead f(x): 0.38943872 Elapsed: 0.063 s
Algorithm: Scipy L-BFGS-B f(x): 0.38943873 Elapsed: 0.047 s
Algorithm: Scipy DA f(x): 0.068011444 Elapsed: 0.546 s
Function: griewank
Algorithm: DE f(x): 0.061438138 Elapsed: 0.022 s
Algorithm: ABC f(x): 0.011294394 Elapsed: 0.025 s
Algorithm: LSHADE f(x): 0.020743875 Elapsed: 0.026 s
Algorithm: LSHADE_cnEpSin f(x): 0.015869195 Elapsed: 0.035 s
Algorithm: JADE f(x): 0.0074222286 Elapsed: 0.033 s
Algorithm: jSO f(x): 0.04904563 Elapsed: 0.031 s
Algorithm: j2020 f(x): 0.0073960403 Elapsed: 0.251 s
Algorithm: LSRTDE f(x): 0.0098688998 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 0.010269096 Elapsed: 0.016 s
Algorithm: ARRDE f(x): 0 Elapsed: 0.049 s
Algorithm: GWO_DE f(x): 0.039632747 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 0.02461003 Elapsed: 0.030 s
Algorithm: DA f(x): 0.056544974 Elapsed: 0.184 s
Algorithm: L_BFGS_B f(x): 0.02461003 Elapsed: 0.000 s
Algorithm: PSO f(x): 0.04187073 Elapsed: 0.022 s
Algorithm: DMSPSO f(x): 0.07381799 Elapsed: 0.011 s
Algorithm: SPSO2011 f(x): 0.10315104 Elapsed: 0.017 s
Algorithm: CMAES f(x): 1.7674751e-13 Elapsed: 0.015 s
Algorithm: BIPOP_aCMAES f(x): 0.012320989 Elapsed: 0.048 s
Algorithm: RCMAES f(x): 2.5124347e-13 Elapsed: 0.053 s
Algorithm: Scipy Nelder-Mead f(x): 0.046729411 Elapsed: 0.050 s
Algorithm: Scipy L-BFGS-B f(x): 0.024637061 Elapsed: 0.017 s
Algorithm: Scipy DA f(x): 0.039362843 Elapsed: 0.399 s
Function: ackley
Algorithm: DE f(x): 2.0133155 Elapsed: 0.035 s
Algorithm: ABC f(x): 0.0020388172 Elapsed: 0.020 s
Algorithm: LSHADE f(x): 7.5487711e-05 Elapsed: 0.034 s
Algorithm: LSHADE_cnEpSin f(x): 6.8326518e-06 Elapsed: 0.027 s
Algorithm: JADE f(x): 7.5495166e-15 Elapsed: 0.033 s
Algorithm: jSO f(x): 1.7451542e-05 Elapsed: 0.031 s
Algorithm: j2020 f(x): 1.0177455e-05 Elapsed: 0.285 s
Algorithm: LSRTDE f(x): 2.0897127e-05 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 0.00017424934 Elapsed: 0.016 s
Algorithm: ARRDE f(x): 4.5763393e-12 Elapsed: 0.051 s
Algorithm: GWO_DE f(x): 0.0017379938 Elapsed: 0.016 s
Algorithm: NelderMead f(x): 9.0738777 Elapsed: 0.035 s
Algorithm: DA f(x): 2.3137048e-13 Elapsed: 0.150 s
Algorithm: L_BFGS_B f(x): 9.4529928 Elapsed: 0.000 s
Algorithm: PSO f(x): 1.503355e-08 Elapsed: 0.024 s
Algorithm: DMSPSO f(x): 4.155741e-08 Elapsed: 0.019 s
Algorithm: SPSO2011 f(x): 0.00022512629 Elapsed: 0.029 s
Algorithm: CMAES f(x): 4.6584958e-13 Elapsed: 0.024 s
Algorithm: BIPOP_aCMAES f(x): 3.952394e-14 Elapsed: 0.054 s
Algorithm: RCMAES f(x): 5.0137672e-13 Elapsed: 0.034 s
Algorithm: Scipy Nelder-Mead f(x): 12.719749 Elapsed: 0.036 s
Algorithm: Scipy L-BFGS-B f(x): 12.719749 Elapsed: 0.000 s
Algorithm: Scipy DA f(x): 1.9576966e-08 Elapsed: 0.444 s
Function: zakharov
Algorithm: DE f(x): 3.0069894e-17 Elapsed: 0.023 s
Algorithm: ABC f(x): 41.659593 Elapsed: 0.018 s
Algorithm: LSHADE f(x): 3.2890263e-06 Elapsed: 0.028 s
Algorithm: LSHADE_cnEpSin f(x): 2.4950129e-10 Elapsed: 0.034 s
Algorithm: JADE f(x): 1.390713e-10 Elapsed: 0.032 s
Algorithm: jSO f(x): 3.8538016e-07 Elapsed: 0.035 s
Algorithm: j2020 f(x): 0.0014664174 Elapsed: 0.353 s
Algorithm: LSRTDE f(x): 9.1337203e-09 Elapsed: 0.009 s
Algorithm: NLSHADE_RSP f(x): 0.0015443574 Elapsed: 0.038 s
Algorithm: ARRDE f(x): 3.7159974e-15 Elapsed: 0.031 s
Algorithm: GWO_DE f(x): 0.0055891047 Elapsed: 0.032 s
Algorithm: NelderMead f(x): 9.5208937e-30 Elapsed: 0.092 s
Algorithm: DA f(x): 4.8003483e-15 Elapsed: 0.164 s
Algorithm: L_BFGS_B f(x): 1.1426143e-12 Elapsed: 0.008 s
Algorithm: PSO f(x): 1.2678103e-08 Elapsed: 0.018 s
Algorithm: DMSPSO f(x): 8.2620301e-09 Elapsed: 0.018 s
Algorithm: SPSO2011 f(x): 0.0035937021 Elapsed: 0.019 s
Algorithm: CMAES f(x): 2.0954112e-13 Elapsed: 0.021 s
Algorithm: BIPOP_aCMAES f(x): 2.6726884e-27 Elapsed: 0.060 s
Algorithm: RCMAES f(x): 2.1318679e-13 Elapsed: 0.038 s
Algorithm: Scipy Nelder-Mead f(x): 7.6416259e-09 Elapsed: 0.137 s
Algorithm: Scipy L-BFGS-B f(x): 7.1099823e-14 Elapsed: 0.019 s
Algorithm: Scipy DA f(x): 5.6595236e-11 Elapsed: 0.474 s
Function: bent_cigar
Algorithm: DE f(x): 0.4565648 Elapsed: 0.017 s
Algorithm: ABC f(x): 0.0070557844 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 0.0010852176 Elapsed: 0.017 s
Algorithm: LSHADE_cnEpSin f(x): 3.8386931e-06 Elapsed: 0.033 s
Algorithm: JADE f(x): 2.5637979e-24 Elapsed: 0.046 s
Algorithm: jSO f(x): 0.00016247901 Elapsed: 0.021 s
Algorithm: j2020 f(x): 1.2573978e-09 Elapsed: 0.220 s
Algorithm: LSRTDE f(x): 7.1736159e-05 Elapsed: 0.024 s
Algorithm: NLSHADE_RSP f(x): 0.049444144 Elapsed: 0.028 s
Algorithm: ARRDE f(x): 6.0498801e-18 Elapsed: 0.043 s
Algorithm: GWO_DE f(x): 0.43844519 Elapsed: 0.021 s
Algorithm: NelderMead f(x): 7.6172326e-24 Elapsed: 0.069 s
Algorithm: DA f(x): 3.9788316e-13 Elapsed: 0.155 s
Algorithm: L_BFGS_B f(x): 6.5127066e-14 Elapsed: 0.001 s
Algorithm: PSO f(x): 1.2779717e-08 Elapsed: 0.021 s
Algorithm: DMSPSO f(x): 1.1574732e-08 Elapsed: 0.021 s
Algorithm: SPSO2011 f(x): 60.436117 Elapsed: 0.095 s
Algorithm: CMAES f(x): 2.0527727e-05 Elapsed: 0.033 s
Algorithm: BIPOP_aCMAES f(x): 4.2892509e-21 Elapsed: 0.059 s
Algorithm: RCMAES f(x): 3.7040872e-13 Elapsed: 0.034 s
Algorithm: Scipy Nelder-Mead f(x): 98.947303 Elapsed: 0.041 s
Algorithm: Scipy L-BFGS-B f(x): 2.0992469e-10 Elapsed: 0.021 s
Algorithm: Scipy DA f(x): 2.2499054e-10 Elapsed: 0.378 s
Function: levy
Algorithm: DE f(x): 3.0346786e-05 Elapsed: 0.034 s
Algorithm: ABC f(x): 4.9142506e-06 Elapsed: 0.026 s
Algorithm: LSHADE f(x): 1.4546568e-08 Elapsed: 0.033 s
Algorithm: LSHADE_cnEpSin f(x): 1.2586431e-10 Elapsed: 0.046 s
Algorithm: JADE f(x): 5.592751e-30 Elapsed: 0.064 s
Algorithm: jSO f(x): 2.5195385e-10 Elapsed: 0.045 s
Algorithm: j2020 f(x): 3.3202314e-13 Elapsed: 0.505 s
Algorithm: LSRTDE f(x): 3.9050784e-12 Elapsed: 0.063 s
Algorithm: NLSHADE_RSP f(x): 5.6983619e-08 Elapsed: 0.034 s
Algorithm: ARRDE f(x): 7.4846351e-25 Elapsed: 0.050 s
Algorithm: GWO_DE f(x): 1.1449741e-06 Elapsed: 0.031 s
Algorithm: NelderMead f(x): 2.3300009 Elapsed: 0.051 s
Algorithm: DA f(x): 2.5016759e-13 Elapsed: 0.266 s
Algorithm: L_BFGS_B f(x): 0.089528251 Elapsed: 0.006 s
Algorithm: PSO f(x): 2.5763755e-14 Elapsed: 0.010 s
Algorithm: DMSPSO f(x): 7.1861345e-16 Elapsed: 0.033 s
Algorithm: SPSO2011 f(x): 1.311917e-05 Elapsed: 0.033 s
Algorithm: CMAES f(x): 2.6149947e-13 Elapsed: 0.022 s
Algorithm: BIPOP_aCMAES f(x): 2.243583e-05 Elapsed: 0.078 s
Algorithm: RCMAES f(x): 3.0376402e-13 Elapsed: 0.041 s
Algorithm: Scipy Nelder-Mead f(x): 10.612364 Elapsed: 0.116 s
Algorithm: Scipy L-BFGS-B f(x): 5.6358232 Elapsed: 0.045 s
Algorithm: Scipy DA f(x): 4.2764763e-11 Elapsed: 0.569 s
Function: discus
Algorithm: DE f(x): 5.7178715e-08 Elapsed: 0.019 s
Algorithm: ABC f(x): 0.0011298486 Elapsed: 0.016 s
Algorithm: LSHADE f(x): 2.7438801e-09 Elapsed: 0.028 s
Algorithm: LSHADE_cnEpSin f(x): 3.032465e-10 Elapsed: 0.034 s
Algorithm: JADE f(x): 1.9721523e-31 Elapsed: 0.030 s
Algorithm: jSO f(x): 5.2950688e-11 Elapsed: 0.025 s
Algorithm: j2020 f(x): 3.0727928e-13 Elapsed: 0.205 s
Algorithm: LSRTDE f(x): 1.2661138e-11 Elapsed: 0.018 s
Algorithm: NLSHADE_RSP f(x): 3.820779e-07 Elapsed: 0.016 s
Algorithm: ARRDE f(x): 1.7299206e-24 Elapsed: 0.035 s
Algorithm: GWO_DE f(x): 7.2145799e-05 Elapsed: 0.016 s
Algorithm: NelderMead f(x): 2.5838254e-24 Elapsed: 0.100 s
Algorithm: DA f(x): 3.6743993e-14 Elapsed: 0.133 s
Algorithm: L_BFGS_B f(x): 1.2333528e-13 Elapsed: 0.000 s
Algorithm: PSO f(x): 1.9777901e-11 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): 3.0682375e-13 Elapsed: 0.019 s
Algorithm: SPSO2011 f(x): 55.988271 Elapsed: 0.025 s
Algorithm: CMAES f(x): 3.0144923e-13 Elapsed: 0.022 s
Algorithm: BIPOP_aCMAES f(x): 5.3619245e-15 Elapsed: 0.054 s
Algorithm: RCMAES f(x): 2.1869038e-13 Elapsed: 0.031 s
Algorithm: Scipy Nelder-Mead f(x): 7.8818509e-09 Elapsed: 0.164 s
Algorithm: Scipy L-BFGS-B f(x): 7.8454388e-12 Elapsed: 0.021 s
Algorithm: Scipy DA f(x): 8.3484436e-10 Elapsed: 0.313 s
Function: drop_wave
Algorithm: DE f(x): -0.93624533 Elapsed: 0.016 s
Algorithm: ABC f(x): -0.93624524 Elapsed: 0.037 s
Algorithm: LSHADE f(x): -1 Elapsed: 0.049 s
Algorithm: LSHADE_cnEpSin f(x): -1 Elapsed: 0.052 s
Algorithm: JADE f(x): -1 Elapsed: 0.034 s
Algorithm: jSO f(x): -1 Elapsed: 0.050 s
Algorithm: j2020 f(x): -1 Elapsed: 0.164 s
Algorithm: LSRTDE f(x): -1 Elapsed: 0.033 s
Algorithm: NLSHADE_RSP f(x): -1 Elapsed: 0.056 s
Algorithm: ARRDE f(x): -1 Elapsed: 0.047 s
Algorithm: GWO_DE f(x): -1 Elapsed: 0.050 s
Algorithm: NelderMead f(x): -1 Elapsed: 0.016 s
Algorithm: DA f(x): -0.93624533 Elapsed: 0.100 s
Algorithm: L_BFGS_B f(x): -0.93624533 Elapsed: 0.000 s
Algorithm: PSO f(x): -1 Elapsed: 0.050 s
Algorithm: DMSPSO f(x): -1 Elapsed: 0.032 s
Algorithm: SPSO2011 f(x): -1 Elapsed: 0.050 s
Algorithm: CMAES f(x): -0.98989002 Elapsed: 0.058 s
Algorithm: BIPOP_aCMAES f(x): -0.98536311 Elapsed: 0.057 s
Algorithm: RCMAES f(x): -0.99953976 Elapsed: 0.054 s
Algorithm: Scipy Nelder-Mead f(x): -0.053939199 Elapsed: 0.016 s
Algorithm: Scipy L-BFGS-B f(x): -0.060920875 Elapsed: 0.015 s
Algorithm: Scipy DA f(x): -1 Elapsed: 0.350 s
Function: goldstein_price
Algorithm: DE f(x): 3 Elapsed: 0.017 s
Algorithm: ABC f(x): 31.223228 Elapsed: 0.033 s
Algorithm: LSHADE f(x): 3 Elapsed: 0.049 s
Algorithm: LSHADE_cnEpSin f(x): 3 Elapsed: 0.050 s
Algorithm: JADE f(x): 3 Elapsed: 0.040 s
Algorithm: jSO f(x): 3 Elapsed: 0.049 s
Algorithm: j2020 f(x): 3 Elapsed: 0.182 s
Algorithm: LSRTDE f(x): 3 Elapsed: 0.033 s
Algorithm: NLSHADE_RSP f(x): 3 Elapsed: 0.050 s
Algorithm: ARRDE f(x): 3 Elapsed: 0.064 s
Algorithm: GWO_DE f(x): 3 Elapsed: 0.034 s
Algorithm: NelderMead f(x): 3 Elapsed: 0.016 s
Algorithm: DA f(x): 3 Elapsed: 0.082 s
Algorithm: L_BFGS_B f(x): 3 Elapsed: 0.016 s
Algorithm: PSO f(x): 3 Elapsed: 0.032 s
Algorithm: DMSPSO f(x): 3 Elapsed: 0.032 s
Algorithm: SPSO2011 f(x): 3.000006 Elapsed: 0.032 s
Algorithm: CMAES f(x): 3 Elapsed: 0.048 s
Algorithm: BIPOP_aCMAES f(x): 3 Elapsed: 0.057 s
Algorithm: RCMAES f(x): 3 Elapsed: 0.048 s
Algorithm: Scipy Nelder-Mead f(x): 84 Elapsed: 0.019 s
Algorithm: Scipy L-BFGS-B f(x): 3 Elapsed: 0.016 s
Algorithm: Scipy DA f(x): 3 Elapsed: 0.302 s
Function: exponential
Algorithm: DE f(x): -0.9999973 Elapsed: 0.014 s
Algorithm: ABC f(x): -0.99999745 Elapsed: 0.019 s
Algorithm: LSHADE f(x): -1 Elapsed: 0.032 s
Algorithm: LSHADE_cnEpSin f(x): -1 Elapsed: 0.033 s
Algorithm: JADE f(x): -1 Elapsed: 0.016 s
Algorithm: jSO f(x): -1 Elapsed: 0.033 s
Algorithm: j2020 f(x): -1 Elapsed: 0.200 s
Algorithm: LSRTDE f(x): -1 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): -0.99999995 Elapsed: 0.024 s
Algorithm: ARRDE f(x): -1 Elapsed: 0.042 s
Algorithm: GWO_DE f(x): -0.99999797 Elapsed: 0.016 s
Algorithm: NelderMead f(x): -1 Elapsed: 0.033 s
Algorithm: DA f(x): -6.8852514e-10 Elapsed: 0.117 s
Algorithm: L_BFGS_B f(x): -1.609051e-22 Elapsed: 0.000 s
Algorithm: PSO f(x): -1 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): -1 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): -0.99999999 Elapsed: 0.016 s
Algorithm: CMAES f(x): -8.0949067e-19 Elapsed: 0.000 s
Algorithm: BIPOP_aCMAES f(x): -1 Elapsed: 0.048 s
Algorithm: RCMAES f(x): -1.4722505e-13 Elapsed: 0.103 s
Algorithm: Scipy Nelder-Mead f(x): -1 Elapsed: 0.053 s
Algorithm: Scipy L-BFGS-B f(x): -5.2446221e-54 Elapsed: 0.000 s
Algorithm: Scipy DA f(x): -8.0337727e-17 Elapsed: 0.359 s
Function: quartic
Algorithm: DE f(x): 0.00669347 Elapsed: 0.021 s
Algorithm: ABC f(x): 0.050228366 Elapsed: 0.019 s
Algorithm: LSHADE f(x): 0.013966561 Elapsed: 0.017 s
Algorithm: LSHADE_cnEpSin f(x): 0.010834201 Elapsed: 0.032 s
Algorithm: JADE f(x): 0.003113222 Elapsed: 0.050 s
Algorithm: jSO f(x): 0.0077145181 Elapsed: 0.017 s
Algorithm: j2020 f(x): 0.018412036 Elapsed: 0.249 s
Algorithm: LSRTDE f(x): 0.010920141 Elapsed: 0.033 s
Algorithm: NLSHADE_RSP f(x): 0.01400187 Elapsed: 0.017 s
Algorithm: ARRDE f(x): 0.0023344029 Elapsed: 0.034 s
Algorithm: GWO_DE f(x): 0.011634361 Elapsed: 0.033 s
Algorithm: NelderMead f(x): 2.439906 Elapsed: 0.099 s
Algorithm: DA f(x): 0.0019139852 Elapsed: 0.117 s
Algorithm: L_BFGS_B f(x): 0.13734697 Elapsed: 0.000 s
Algorithm: PSO f(x): 0.0051740768 Elapsed: 0.083 s
Algorithm: DMSPSO f(x): 0.003703311 Elapsed: 0.033 s
Algorithm: SPSO2011 f(x): 0.014348103 Elapsed: 0.033 s
Algorithm: CMAES f(x): 0.0071509288 Elapsed: 0.000 s
Algorithm: BIPOP_aCMAES f(x): 0.0015759651 Elapsed: 0.067 s
Algorithm: RCMAES f(x): 0.0035346978 Elapsed: 0.051 s
Algorithm: Scipy Nelder-Mead f(x): 6.1571452 Elapsed: 0.300 s
Algorithm: Scipy L-BFGS-B f(x): 50784.069 Elapsed: 0.000 s
Algorithm: Scipy DA f(x): 0.23549417 Elapsed: 0.383 s
Function: hybrid_composition1
Algorithm: DE f(x): 8.9988431 Elapsed: 0.033 s
Algorithm: ABC f(x): 20.357668 Elapsed: 0.035 s
Algorithm: LSHADE f(x): 8.9683112 Elapsed: 0.032 s
Algorithm: LSHADE_cnEpSin f(x): 8.9683085 Elapsed: 0.050 s
Algorithm: JADE f(x): 8.9683084 Elapsed: 0.049 s
Algorithm: jSO f(x): 8.9683085 Elapsed: 0.033 s
Algorithm: j2020 f(x): 50.161162 Elapsed: 0.366 s
Algorithm: LSRTDE f(x): 8.9683084 Elapsed: 0.018 s
Algorithm: NLSHADE_RSP f(x): 8.9683171 Elapsed: 0.033 s
Algorithm: ARRDE f(x): 8.9683084 Elapsed: 0.050 s
Algorithm: GWO_DE f(x): 8.9714542 Elapsed: 0.033 s
Algorithm: NelderMead f(x): 8.9683084 Elapsed: 0.067 s
Algorithm: DA f(x): 8.9683084 Elapsed: 0.183 s
Algorithm: L_BFGS_B f(x): 129.896 Elapsed: 0.007 s
Algorithm: PSO f(x): 43.165578 Elapsed: 0.010 s
Algorithm: DMSPSO f(x): 8.9683084 Elapsed: 0.033 s
Algorithm: SPSO2011 f(x): 8.9683112 Elapsed: 0.028 s
Algorithm: CMAES f(x): 8.9683084 Elapsed: 0.035 s
Algorithm: BIPOP_aCMAES f(x): 8.9683084 Elapsed: 0.064 s
Algorithm: RCMAES f(x): 8.9683085 Elapsed: 0.039 s
Algorithm: Scipy Nelder-Mead f(x): 81.481178 Elapsed: 0.060 s
Algorithm: Scipy L-BFGS-B f(x): 49.451818 Elapsed: 0.016 s
Algorithm: Scipy DA f(x): 127.3888 Elapsed: 0.539 s
Function: hybrid_composition2
Algorithm: DE f(x): 0.00065631029 Elapsed: 0.036 s
Algorithm: ABC f(x): 0.0014850221 Elapsed: 0.029 s
Algorithm: LSHADE f(x): 7.928088e-05 Elapsed: 0.040 s
Algorithm: LSHADE_cnEpSin f(x): 8.4663499e-05 Elapsed: 0.044 s
Algorithm: JADE f(x): 8.437695e-15 Elapsed: 0.048 s
Algorithm: jSO f(x): 3.9360297e-05 Elapsed: 0.037 s
Algorithm: j2020 f(x): 9.4931414e-09 Elapsed: 0.511 s
Algorithm: LSRTDE f(x): 1.8285006e-05 Elapsed: 0.032 s
Algorithm: NLSHADE_RSP f(x): 2.7129552e-05 Elapsed: 0.032 s
Algorithm: ARRDE f(x): 1.1080691e-12 Elapsed: 0.064 s
Algorithm: GWO_DE f(x): 0.0064449574 Elapsed: 0.028 s
Algorithm: NelderMead f(x): 2.1270735 Elapsed: 0.181 s
Algorithm: DA f(x): 7.1784852e-13 Elapsed: 0.257 s
Algorithm: L_BFGS_B f(x): 3.4506903e-11 Elapsed: 0.014 s
Algorithm: PSO f(x): 4.7867762e-07 Elapsed: 0.026 s
Algorithm: DMSPSO f(x): 1.1121672e-07 Elapsed: 0.028 s
Algorithm: SPSO2011 f(x): 0.00071767757 Elapsed: 0.038 s
Algorithm: CMAES f(x): 4.7674408e-13 Elapsed: 0.040 s
Algorithm: BIPOP_aCMAES f(x): 3.1845533e-13 Elapsed: 0.080 s
Algorithm: RCMAES f(x): 5.9952043e-13 Elapsed: 0.051 s
Algorithm: Scipy Nelder-Mead f(x): 9.7571206 Elapsed: 0.187 s
Algorithm: Scipy L-BFGS-B f(x): 5.4366301e-08 Elapsed: 0.114 s
Algorithm: Scipy DA f(x): 6.7994238e-08 Elapsed: 0.732 s
Function: hybrid_composition3
Algorithm: DE f(x): 1.2839526 Elapsed: 0.040 s
Algorithm: ABC f(x): 27.704459 Elapsed: 0.055 s
Algorithm: LSHADE f(x): 1.2839527 Elapsed: 0.053 s
Algorithm: LSHADE_cnEpSin f(x): 1.2839528 Elapsed: 0.061 s
Algorithm: JADE f(x): 1.2839526 Elapsed: 0.086 s
Algorithm: jSO f(x): 1.2839527 Elapsed: 0.048 s
Algorithm: j2020 f(x): 1.2843391 Elapsed: 0.860 s
Algorithm: LSRTDE f(x): 1.2839526 Elapsed: 0.038 s
Algorithm: NLSHADE_RSP f(x): 1.3209794 Elapsed: 0.038 s
Algorithm: ARRDE f(x): 1.2839526 Elapsed: 0.084 s
Algorithm: GWO_DE f(x): 1.2886312 Elapsed: 0.033 s
Algorithm: NelderMead f(x): 34.881183 Elapsed: 0.184 s
Algorithm: DA f(x): 1.7576298 Elapsed: 0.298 s
Algorithm: L_BFGS_B f(x): 2.6486818 Elapsed: 0.000 s
Algorithm: PSO f(x): 1.2839526 Elapsed: 0.034 s
Algorithm: DMSPSO f(x): 1.2839526 Elapsed: 0.032 s
Algorithm: SPSO2011 f(x): 1.2905009 Elapsed: 0.049 s
Algorithm: CMAES f(x): 1.2839526 Elapsed: 0.051 s
Algorithm: BIPOP_aCMAES f(x): 1.2839526 Elapsed: 0.103 s
Algorithm: RCMAES f(x): 1.2839526 Elapsed: 0.089 s
Algorithm: Scipy Nelder-Mead f(x): 95.146651 Elapsed: 0.444 s
Algorithm: Scipy L-BFGS-B f(x): 7.1707073 Elapsed: 0.132 s
Algorithm: Scipy DA f(x): 86.827716 Elapsed: 0.989 s
Function: happy_cat
Algorithm: DE f(x): 0.43438983 Elapsed: 0.036 s
Algorithm: ABC f(x): 0.11614202 Elapsed: 0.024 s
Algorithm: LSHADE f(x): 0.06876798 Elapsed: 0.032 s
Algorithm: LSHADE_cnEpSin f(x): 0.08811846 Elapsed: 0.048 s
Algorithm: JADE f(x): 0.057854724 Elapsed: 0.051 s
Algorithm: jSO f(x): 0.1398287 Elapsed: 0.018 s
Algorithm: j2020 f(x): 0.32344314 Elapsed: 0.303 s
Algorithm: LSRTDE f(x): 0.067310395 Elapsed: 0.031 s
Algorithm: NLSHADE_RSP f(x): 0.22108284 Elapsed: 0.033 s
Algorithm: ARRDE f(x): 0.03932664 Elapsed: 0.032 s
Algorithm: GWO_DE f(x): 0.092721777 Elapsed: 0.035 s
Algorithm: NelderMead f(x): 0.67618088 Elapsed: 0.048 s
Algorithm: DA f(x): 0.29259162 Elapsed: 0.088 s
Algorithm: L_BFGS_B f(x): 0.48739033 Elapsed: 0.008 s
Algorithm: PSO f(x): 0.10764502 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): 0.090894072 Elapsed: 0.018 s
Algorithm: SPSO2011 f(x): 0.11049381 Elapsed: 0.023 s
Algorithm: CMAES f(x): 0.079812377 Elapsed: 0.032 s
Algorithm: BIPOP_aCMAES f(x): 0.11685272 Elapsed: 0.067 s
Algorithm: RCMAES f(x): 0.031395191 Elapsed: 0.032 s
Algorithm: Scipy Nelder-Mead f(x): 1.4407279 Elapsed: 0.060 s
Algorithm: Scipy L-BFGS-B f(x): 0.0059492927 Elapsed: 0.038 s
Algorithm: Scipy DA f(x): 0.049035597 Elapsed: 0.445 s
Function: michalewics
Algorithm: DE f(x): -8.3009355 Elapsed: 0.027 s
Algorithm: ABC f(x): -9.1973303 Elapsed: 0.021 s
Algorithm: LSHADE f(x): -9.3568629 Elapsed: 0.030 s
Algorithm: LSHADE_cnEpSin f(x): -7.1404582 Elapsed: 0.028 s
Algorithm: JADE f(x): -9.8234088 Elapsed: 0.049 s
Algorithm: jSO f(x): -7.14665 Elapsed: 0.035 s
Algorithm: j2020 f(x): -9.3705526 Elapsed: 0.266 s
Algorithm: LSRTDE f(x): -5.9973706 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): -9.1494271 Elapsed: 0.035 s
Algorithm: ARRDE f(x): -9.1035186 Elapsed: 0.051 s
Algorithm: GWO_DE f(x): -5.8236661 Elapsed: 0.031 s
Algorithm: NelderMead f(x): -3.6164748 Elapsed: 0.181 s
Algorithm: DA f(x): -9.6983809 Elapsed: 0.101 s
Algorithm: L_BFGS_B f(x): -2.6919874 Elapsed: 0.000 s
Algorithm: PSO f(x): -8.4025835 Elapsed: 0.019 s
Algorithm: DMSPSO f(x): -9.2155994 Elapsed: 0.031 s
Algorithm: SPSO2011 f(x): -4.3098749 Elapsed: 0.033 s
Algorithm: CMAES f(x): -7.593261 Elapsed: 0.041 s
Algorithm: BIPOP_aCMAES f(x): -7.1249446 Elapsed: 0.076 s
Algorithm: RCMAES f(x): -9.12015 Elapsed: 0.033 s
Algorithm: Scipy Nelder-Mead f(x): -4.2489914 Elapsed: 0.050 s
Algorithm: Scipy L-BFGS-B f(x): -3.2901102 Elapsed: 0.036 s
Algorithm: Scipy DA f(x): -9.8596763 Elapsed: 0.451 s
Function: scaffer6
Algorithm: DE f(x): 0.39870787 Elapsed: 0.247 s
Algorithm: ABC f(x): 0.10500073 Elapsed: 0.238 s
Algorithm: LSHADE f(x): 0.16383664 Elapsed: 0.324 s
Algorithm: LSHADE_cnEpSin f(x): 0.31007305 Elapsed: 0.272 s
Algorithm: JADE f(x): 0.096623768 Elapsed: 0.264 s
Algorithm: jSO f(x): 0.49340471 Elapsed: 0.267 s
Algorithm: j2020 f(x): 0.54162424 Elapsed: 0.434 s
Algorithm: LSRTDE f(x): 0.84925214 Elapsed: 0.282 s
Algorithm: NLSHADE_RSP f(x): 0.2412924 Elapsed: 0.300 s
Algorithm: ARRDE f(x): 0.22498414 Elapsed: 0.267 s
Algorithm: GWO_DE f(x): 0.20916532 Elapsed: 0.334 s
Algorithm: NelderMead f(x): 0.18775994 Elapsed: 0.215 s
Algorithm: DA f(x): 0.08744319 Elapsed: 0.317 s
Algorithm: L_BFGS_B f(x): 0.18775994 Elapsed: 0.032 s
Algorithm: PSO f(x): 0.14246096 Elapsed: 0.320 s
Algorithm: DMSPSO f(x): 0.28000035 Elapsed: 0.347 s
Algorithm: SPSO2011 f(x): 0.44903672 Elapsed: 0.300 s
Algorithm: CMAES f(x): 0.18775997 Elapsed: 0.249 s
Algorithm: BIPOP_aCMAES f(x): 0.48261702 Elapsed: 0.302 s
Algorithm: RCMAES f(x): 0.36193056 Elapsed: 0.297 s
Algorithm: Scipy Nelder-Mead f(x): 0.38943872 Elapsed: 0.086 s
Algorithm: Scipy L-BFGS-B f(x): 0.38943873 Elapsed: 0.044 s
Algorithm: Scipy DA f(x): 0.08744319 Elapsed: 0.550 s
Function: hcf
Algorithm: DE f(x): 0.00012559037 Elapsed: 0.019 s
Algorithm: ABC f(x): 0.00064405979 Elapsed: 0.016 s
Algorithm: LSHADE f(x): 0.00026109603 Elapsed: 0.018 s
Algorithm: LSHADE_cnEpSin f(x): 5.940098e-06 Elapsed: 0.042 s
Algorithm: JADE f(x): 0 Elapsed: 0.025 s
Algorithm: jSO f(x): 1.5504817e-05 Elapsed: 0.032 s
Algorithm: j2020 f(x): 1.3515534e-09 Elapsed: 0.244 s
Algorithm: LSRTDE f(x): 6.2804581e-06 Elapsed: 0.010 s
Algorithm: NLSHADE_RSP f(x): 2.0882744e-05 Elapsed: 0.030 s
Algorithm: ARRDE f(x): 1.8728075e-13 Elapsed: 0.034 s
Algorithm: GWO_DE f(x): 0.0028549358 Elapsed: 0.030 s
Algorithm: NelderMead f(x): 2.358758 Elapsed: 0.170 s
Algorithm: DA f(x): 6.959574e-13 Elapsed: 0.083 s
Algorithm: L_BFGS_B f(x): 1.2448024e-11 Elapsed: 0.020 s
Algorithm: PSO f(x): 3.625667e-07 Elapsed: 0.014 s
Algorithm: DMSPSO f(x): 4.1352657e-08 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): 0.0008370529 Elapsed: 0.017 s
Algorithm: CMAES f(x): 5.6695078e-13 Elapsed: 0.017 s
Algorithm: BIPOP_aCMAES f(x): 3.4508637e-14 Elapsed: 0.055 s
Algorithm: RCMAES f(x): 6.2305716e-13 Elapsed: 0.028 s
Algorithm: Scipy Nelder-Mead f(x): 9.2898681 Elapsed: 0.117 s
Algorithm: Scipy L-BFGS-B f(x): 6.0597252e-08 Elapsed: 0.066 s
Algorithm: Scipy DA f(x): 3.908471e-08 Elapsed: 0.350 s
Function: grie_rosen
Algorithm: DE f(x): 8.8831392 Elapsed: 0.032 s
Algorithm: ABC f(x): 1.7608068 Elapsed: 0.018 s
Algorithm: LSHADE f(x): 5.6373159 Elapsed: 0.017 s
Algorithm: LSHADE_cnEpSin f(x): 2.4061948 Elapsed: 0.033 s
Algorithm: JADE f(x): 3.0199724 Elapsed: 0.050 s
Algorithm: jSO f(x): 4.0031942 Elapsed: 0.016 s
Algorithm: j2020 f(x): 6.1732822 Elapsed: 0.267 s
Algorithm: LSRTDE f(x): 6.731517 Elapsed: 0.016 s
Algorithm: NLSHADE_RSP f(x): 5.5444564 Elapsed: 0.033 s
Algorithm: ARRDE f(x): 1.0276919 Elapsed: 0.045 s
Algorithm: GWO_DE f(x): 8.3330569 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 1 Elapsed: 0.100 s
Algorithm: DA f(x): 1 Elapsed: 0.150 s
Algorithm: L_BFGS_B f(x): 1 Elapsed: 0.000 s
Algorithm: PSO f(x): 5.1698908 Elapsed: 0.033 s
Algorithm: DMSPSO f(x): 4.1950515 Elapsed: 0.017 s
Algorithm: SPSO2011 f(x): 7.3833122 Elapsed: 0.033 s
Algorithm: CMAES f(x): 1.0531737 Elapsed: 0.050 s
Algorithm: BIPOP_aCMAES f(x): 1 Elapsed: 0.067 s
Algorithm: RCMAES f(x): 1.0000001 Elapsed: 0.050 s
Algorithm: Scipy Nelder-Mead f(x): 1 Elapsed: 0.116 s
Algorithm: Scipy L-BFGS-B f(x): 1 Elapsed: 0.033 s
Algorithm: Scipy DA f(x): 1 Elapsed: 0.618 s
Function: dixon_price
Algorithm: DE f(x): 0.9369413 Elapsed: 0.032 s
Algorithm: ABC f(x): 0.084836119 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 0.66667706 Elapsed: 0.033 s
Algorithm: LSHADE_cnEpSin f(x): 0.66666667 Elapsed: 0.050 s
Algorithm: JADE f(x): 0.66666667 Elapsed: 0.033 s
Algorithm: jSO f(x): 0.66666667 Elapsed: 0.043 s
Algorithm: j2020 f(x): 1.0792427e-06 Elapsed: 0.239 s
Algorithm: LSRTDE f(x): 0.66666667 Elapsed: 0.033 s
Algorithm: NLSHADE_RSP f(x): 0.66666673 Elapsed: 0.023 s
Algorithm: ARRDE f(x): 0.011844537 Elapsed: 0.028 s
Algorithm: GWO_DE f(x): 0.6670176 Elapsed: 0.016 s
Algorithm: NelderMead f(x): 0.66666667 Elapsed: 0.053 s
Algorithm: DA f(x): 0.66666667 Elapsed: 0.164 s
Algorithm: L_BFGS_B f(x): 0.66666667 Elapsed: 0.000 s
Algorithm: PSO f(x): 0.66666667 Elapsed: 0.018 s
Algorithm: DMSPSO f(x): 0.66666667 Elapsed: 0.031 s
Algorithm: SPSO2011 f(x): 0.66871542 Elapsed: 0.017 s
Algorithm: CMAES f(x): 0.66666667 Elapsed: 0.017 s
Algorithm: BIPOP_aCMAES f(x): 1.1528975e-22 Elapsed: 0.065 s
Algorithm: RCMAES f(x): 0.66666667 Elapsed: 0.018 s
Algorithm: Scipy Nelder-Mead f(x): 0.66666667 Elapsed: 0.098 s
Algorithm: Scipy L-BFGS-B f(x): 0.66666667 Elapsed: 0.017 s
Algorithm: Scipy DA f(x): 0.66666667 Elapsed: 0.416 s
Function: eosom
Algorithm: DE f(x): -0.0090056781 Elapsed: 0.017 s
Algorithm: ABC f(x): -0.0090051278 Elapsed: 0.050 s
Algorithm: LSHADE f(x): -0.0090056781 Elapsed: 0.050 s
Algorithm: LSHADE_cnEpSin f(x): -0.0090056781 Elapsed: 0.067 s
Algorithm: JADE f(x): -0.0090056781 Elapsed: 0.033 s
Algorithm: jSO f(x): -0.0090056781 Elapsed: 0.050 s
Algorithm: j2020 f(x): -0.0090056781 Elapsed: 0.183 s
Algorithm: LSRTDE f(x): -0.0090056781 Elapsed: 0.050 s
Algorithm: NLSHADE_RSP f(x): -0.0090056781 Elapsed: 0.050 s
Algorithm: ARRDE f(x): -0.0090056781 Elapsed: 0.067 s
Algorithm: GWO_DE f(x): -0.0090056781 Elapsed: 0.051 s
Algorithm: NelderMead f(x): -7.8737549e-14 Elapsed: 0.033 s
Algorithm: DA f(x): -0.0090056781 Elapsed: 0.117 s
Algorithm: L_BFGS_B f(x): 2.8026392e-10 Elapsed: 0.000 s
Algorithm: PSO f(x): -0.0090056781 Elapsed: 0.050 s
Algorithm: DMSPSO f(x): -0.0090056781 Elapsed: 0.049 s
Algorithm: SPSO2011 f(x): -0.0090056781 Elapsed: 0.067 s
Algorithm: CMAES f(x): -0.0090056781 Elapsed: 0.075 s
Algorithm: BIPOP_aCMAES f(x): -0.0090056781 Elapsed: 0.074 s
Algorithm: RCMAES f(x): -0.0090056781 Elapsed: 0.084 s
Algorithm: Scipy Nelder-Mead f(x): -0.0090056781 Elapsed: 0.019 s
Algorithm: Scipy L-BFGS-B f(x): -1.4567312e-07 Elapsed: 0.000 s
Algorithm: Scipy DA f(x): -0.0090056781 Elapsed: 0.301 s
Function: hgbat
Algorithm: DE f(x): 0.50187639 Elapsed: 0.031 s
Algorithm: ABC f(x): 0.51336039 Elapsed: 0.015 s
Algorithm: LSHADE f(x): 0.50006438 Elapsed: 0.017 s
Algorithm: LSHADE_cnEpSin f(x): 0.50001148 Elapsed: 0.033 s
Algorithm: JADE f(x): 0.5 Elapsed: 0.050 s
Algorithm: jSO f(x): 0.50000443 Elapsed: 0.017 s
Algorithm: j2020 f(x): 0.50000019 Elapsed: 0.285 s
Algorithm: LSRTDE f(x): 0.50002916 Elapsed: 0.015 s
Algorithm: NLSHADE_RSP f(x): 0.50039586 Elapsed: 0.033 s
Algorithm: ARRDE f(x): 0.5 Elapsed: 0.036 s
Algorithm: GWO_DE f(x): 0.50185635 Elapsed: 0.030 s
Algorithm: NelderMead f(x): 0.5 Elapsed: 0.070 s
Algorithm: DA f(x): 0.50000001 Elapsed: 0.114 s
Algorithm: L_BFGS_B f(x): 0.50000001 Elapsed: 0.000 s
Algorithm: PSO f(x): 0.50000007 Elapsed: 0.018 s
Algorithm: DMSPSO f(x): 0.50000007 Elapsed: 0.020 s
Algorithm: SPSO2011 f(x): 0.50010564 Elapsed: 0.013 s
Algorithm: CMAES f(x): 0.5 Elapsed: 0.036 s
Algorithm: BIPOP_aCMAES f(x): 0.5 Elapsed: 0.064 s
Algorithm: RCMAES f(x): 0.5 Elapsed: 0.033 s
Algorithm: Scipy Nelder-Mead f(x): 0.5000703 Elapsed: 0.049 s
Algorithm: Scipy L-BFGS-B f(x): 0.50000002 Elapsed: 0.034 s
Algorithm: Scipy DA f(x): 0.50000001 Elapsed: 0.383 s
Function: styblinski_tang
Algorithm: DE f(x): -363.38784 Elapsed: 0.018 s
Algorithm: ABC f(x): -391.66152 Elapsed: 0.017 s
Algorithm: LSHADE f(x): -391.66076 Elapsed: 0.017 s
Algorithm: LSHADE_cnEpSin f(x): -391.66165 Elapsed: 0.033 s
Algorithm: JADE f(x): -377.52494 Elapsed: 0.034 s
Algorithm: jSO f(x): -391.66166 Elapsed: 0.017 s
Algorithm: j2020 f(x): -391.62532 Elapsed: 0.216 s
Algorithm: LSRTDE f(x): -391.66166 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): -391.66122 Elapsed: 0.033 s
Algorithm: ARRDE f(x): -391.66166 Elapsed: 0.033 s
Algorithm: GWO_DE f(x): -377.52492 Elapsed: 0.017 s
Algorithm: NelderMead f(x): -306.84134 Elapsed: 0.048 s
Algorithm: DA f(x): -391.66166 Elapsed: 0.125 s
Algorithm: L_BFGS_B f(x): -320.97806 Elapsed: 0.000 s
Algorithm: PSO f(x): -363.38822 Elapsed: 0.110 s
Algorithm: DMSPSO f(x): -377.52494 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): -377.52492 Elapsed: 0.033 s
Algorithm: CMAES f(x): -377.52494 Elapsed: 0.017 s
Algorithm: BIPOP_aCMAES f(x): -349.2515 Elapsed: 0.050 s
Algorithm: RCMAES f(x): -377.52494 Elapsed: 0.033 s
Algorithm: Scipy Nelder-Mead f(x): -250.29447 Elapsed: 0.050 s
Algorithm: Scipy L-BFGS-B f(x): -292.70462 Elapsed: 0.016 s
Algorithm: Scipy DA f(x): -391.66166 Elapsed: 0.350 s
Function: step
Algorithm: DE f(x): 1 Elapsed: 0.000 s
Algorithm: ABC f(x): 0 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 0 Elapsed: 0.017 s
Algorithm: LSHADE_cnEpSin f(x): 0 Elapsed: 0.033 s
Algorithm: JADE f(x): 0 Elapsed: 0.034 s
Algorithm: jSO f(x): 0 Elapsed: 0.025 s
Algorithm: j2020 f(x): 0 Elapsed: 0.223 s
Algorithm: LSRTDE f(x): 0 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 0 Elapsed: 0.023 s
Algorithm: ARRDE f(x): 0 Elapsed: 0.035 s
Algorithm: GWO_DE f(x): 0 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 98 Elapsed: 0.001 s
Algorithm: DA f(x): 0 Elapsed: 0.125 s
Algorithm: L_BFGS_B f(x): 103 Elapsed: 0.000 s
Algorithm: PSO f(x): 0 Elapsed: 0.017 s
Algorithm: DMSPSO f(x): 0 Elapsed: 0.029 s
Algorithm: SPSO2011 f(x): 0 Elapsed: 0.027 s
Algorithm: CMAES f(x): 0 Elapsed: 0.004 s
Algorithm: BIPOP_aCMAES f(x): 0 Elapsed: 0.057 s
Algorithm: RCMAES f(x): 0 Elapsed: 0.033 s
Algorithm: Scipy Nelder-Mead f(x): 256 Elapsed: 0.015 s
Algorithm: Scipy L-BFGS-B f(x): 256 Elapsed: 0.001 s
Algorithm: Scipy DA f(x): 0 Elapsed: 0.326 s
Function: weierstrass
Algorithm: DE f(x): 6.6762411 Elapsed: 1.106 s
Algorithm: ABC f(x): 1.7689882 Elapsed: 1.120 s
Algorithm: LSHADE f(x): 1.843618 Elapsed: 1.036 s
Algorithm: LSHADE_cnEpSin f(x): 3.7636512 Elapsed: 1.042 s
Algorithm: JADE f(x): 0.25402247 Elapsed: 1.157 s
Algorithm: jSO f(x): 7.1518865 Elapsed: 1.000 s
Algorithm: j2020 f(x): 2.6121347 Elapsed: 1.123 s
Algorithm: LSRTDE f(x): 10.424692 Elapsed: 1.011 s
Algorithm: NLSHADE_RSP f(x): 1.5618487 Elapsed: 1.070 s
Algorithm: ARRDE f(x): 2.8028555 Elapsed: 1.027 s
Algorithm: GWO_DE f(x): 8.296778 Elapsed: 1.037 s
Algorithm: NelderMead f(x): 16.331325 Elapsed: 0.199 s
Algorithm: DA f(x): 12.581938 Elapsed: 1.020 s
Algorithm: L_BFGS_B f(x): 17.505271 Elapsed: 0.145 s
Algorithm: PSO f(x): 0.69471505 Elapsed: 1.015 s
Algorithm: DMSPSO f(x): 6.3828497 Elapsed: 1.017 s
Algorithm: SPSO2011 f(x): 9.3314811 Elapsed: 1.000 s
Algorithm: CMAES f(x): 9.8367704 Elapsed: 1.009 s
Algorithm: BIPOP_aCMAES f(x): 0.80966954 Elapsed: 1.075 s
Algorithm: RCMAES f(x): 10.917941 Elapsed: 1.066 s
Algorithm: Scipy Nelder-Mead f(x): 6.4472257 Elapsed: 0.167 s
Algorithm: Scipy L-BFGS-B f(x): 15.152619 Elapsed: 0.150 s
Algorithm: Scipy DA f(x): 7.8145027 Elapsed: 1.233 s
Function: sum_squares
Algorithm: DE f(x): 7.8443974e-12 Elapsed: 0.017 s
Algorithm: ABC f(x): 1.1320746e-06 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 5.0250021e-08 Elapsed: 0.017 s
Algorithm: LSHADE_cnEpSin f(x): 5.8031739e-11 Elapsed: 0.033 s
Algorithm: JADE f(x): 1.5752115e-27 Elapsed: 0.033 s
Algorithm: jSO f(x): 8.2499053e-11 Elapsed: 0.033 s
Algorithm: j2020 f(x): 8.5076449e-13 Elapsed: 0.183 s
Algorithm: LSRTDE f(x): 1.0575001e-10 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 6.9326457e-08 Elapsed: 0.017 s
Algorithm: ARRDE f(x): 2.4040217e-24 Elapsed: 0.033 s
Algorithm: GWO_DE f(x): 9.2745848e-06 Elapsed: 0.017 s
Algorithm: NelderMead f(x): 8.310147e-30 Elapsed: 0.050 s
Algorithm: DA f(x): 8.1379826e-15 Elapsed: 0.117 s
Algorithm: L_BFGS_B f(x): 4.0453218e-14 Elapsed: 0.000 s
Algorithm: PSO f(x): 6.0895571e-15 Elapsed: 0.017 s
Algorithm: DMSPSO f(x): 2.7514762e-15 Elapsed: 0.016 s
Algorithm: SPSO2011 f(x): 7.3714663e-06 Elapsed: 0.026 s
Algorithm: CMAES f(x): 3.4587095e-13 Elapsed: 0.008 s
Algorithm: BIPOP_aCMAES f(x): 2.1153437e-25 Elapsed: 0.050 s
Algorithm: RCMAES f(x): 3.274528e-13 Elapsed: 0.017 s
Algorithm: Scipy Nelder-Mead f(x): 1.6899228e-08 Elapsed: 0.050 s
Algorithm: Scipy L-BFGS-B f(x): 1.8569868e-11 Elapsed: 0.000 s
Algorithm: Scipy DA f(x): 1.8569868e-11 Elapsed: 0.349 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.
[6]:
# 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) = 117.95172 | Elapsed: 1.96 sec
Algo : L_BFGS_B | f(x) = 100 | Elapsed: 1.86 sec
Algo : DA | f(x) = 100 | Elapsed: 5.06 sec
Algo : Scipy Dual Annealing | f(x) = 100 | Elapsed: 10.85 sec
Algo : Scipy L-BFGS-B | f(x) = 100 | Elapsed: 4.64 sec
====================================================================================================
The algorithms implemented in Minion (ARRDE, L-BFGS-B, and Dual Annealing) significantly outperform their SciPy counterparts in speed. For example, Minion’s Dual Annealing is roughly 4 times as fast as the SciPy’s, while its L-BFGS-B is almost three times as fast. 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.
[7]:
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
[8]:
# 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 :
[np.float64(0.5590277202277464), np.float64(0.8314047491898819), np.float64(0.42835223063884925), np.float64(0.3263644456888844), np.float64(0.710442560133207), np.float64(0.406870840521136), np.float64(0.5407012538640411), np.float64(0.48233441148883416)]
Elapsed : 0.05704069137573242
Calling the function sequentially :
[np.float64(0.5590277202277464), np.float64(0.8314047491898819), np.float64(0.42835223063884925), np.float64(0.3263644456888844), np.float64(0.710442560133207), np.float64(0.406870840521136), np.float64(0.5407012538640411), np.float64(0.48233441148883416)]
Elapsed : 0.40640807151794434
True
3. Minimize using one of minionpy algorithms
[9]:
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 : [5.018454243404394, -4.810866184531413, 9.992310013708282, 4.967835596117807, -4.803662393455747, 4.858113945288457, 4.438874376295008, 5.042549004109493]
f(x) : -7.67703489988693
Elapsed: 9.916847229003906 seconds
Test function value : -7.67703489988693
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?
[10]:
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 : [-9.997223468122773, -7.551520998748705, -7.93736170073008, -9.950709131816918, -9.91122046515175, 9.804161242381989, 0.8936974111335916, 7.752642571805346]
f(x) : -7.188477780475587
Elapsed: 9.90553092956543 seconds
Test function value : 0.9705624435760034
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. This approach works correctly, but it is best demonstrated from a
separate Python script rather than directly from a notebook cell. On many platforms, multiprocessing workers must be able to import the objective class from a real module, so the example should be placed in a standalone file and executed under if __name__ == "__main__":.
[ ]:
# Note : the following snippet should be used in a separate script under if __name__ == "__main__", as Process_Parallel does not work in Jupyter notebooks.
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())
[ ]:
# Note : the following snippet should be used in a separate script under if __name__ == "__main__", as Process_Parallel does not work in Jupyter notebooks.
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)))
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.
[11]:
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
}
x0 = [[0.0 for _ in range(len(bounds))]]
print(f"\nRunning optimization for {func_name} (Dimension: {dimension})")
print("=" * 60)
for algo in algos:
res = mpy.Minimizer(
func, bounds, 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" : "reflect-random"
}
).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}),
("Scipy Nelder-Mead", minimize, {"x0": x0[0], "method": "Nelder-Mead", "bounds": bounds, "options": {"maxfev": Nmaxeval, "adaptive": True}}),
("Scipy DA", dual_annealing, {"bounds": bounds, "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 = {
2011 : mpy.CEC2011Functions,
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)
bounds = [(-100, 100)] * dimension
if year == 2011 :
bounds = cec_func.get_bounds()
test_optimization(cec_func,bounds, dim, f"func_{j}", Nmaxeval, seed)
# List of algorithms to be tested
algos = [
"DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP", "IMODE", "AGSK",
"ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES", "RCMAES"
]
Nmaxeval = 20000 # 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)),
2011 : list(range(1, 23))
}
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): 1035.1009
ABC f(x): 49967.702
LSHADE f(x): 300.74801
LSHADE_cnEpSin f(x): 300.03523
JADE f(x): 457.20224
jSO f(x): 300.36146
j2020 f(x): 27562.584
LSRTDE f(x): 300.58607
NLSHADE_RSP f(x): 6019.1092
IMODE f(x): 300
AGSK f(x): 14275.397
ARRDE f(x): 300.00032
GWO_DE f(x): 4560.7819
NelderMead f(x): 358.27996
DA f(x): 300
L_BFGS_B f(x): 300
PSO f(x): 3761.7453
DMSPSO f(x): 756.64802
SPSO2011 f(x): 10320.75
CMAES f(x): 300
BIPOP_aCMAES f(x): 300
RCMAES f(x): 4654.8386
Scipy L-BFGS-B f(x): 300
Scipy Nelder-Mead f(x): 9928.5338
Scipy DA f(x): 300
------------------------------------------------------------
Running optimization for func_2 (Dimension: 20)
============================================================
DE f(x): 475.10938
ABC f(x): 487.65906
LSHADE f(x): 449.08457
LSHADE_cnEpSin f(x): 449.08448
JADE f(x): 449.08465
jSO f(x): 449.08451
j2020 f(x): 449.0931
LSRTDE f(x): 449.08673
NLSHADE_RSP f(x): 453.61644
IMODE f(x): 412.42697
AGSK f(x): 449.09543
ARRDE f(x): 444.89547
GWO_DE f(x): 449.5273
NelderMead f(x): 449.38295
DA f(x): 449.08448
L_BFGS_B f(x): 449.08448
PSO f(x): 474.39471
DMSPSO f(x): 449.08448
SPSO2011 f(x): 449.61382
CMAES f(x): 449.08448
BIPOP_aCMAES f(x): 449.70785
RCMAES f(x): 427.40889
Scipy L-BFGS-B f(x): 449.08448
Scipy Nelder-Mead f(x): 560.25712
Scipy DA f(x): 400
------------------------------------------------------------
Running optimization for func_3 (Dimension: 20)
============================================================
DE f(x): 605.05102
ABC f(x): 610.74446
LSHADE f(x): 600.13947
LSHADE_cnEpSin f(x): 600.1087
JADE f(x): 600.00002
jSO f(x): 600.0122
j2020 f(x): 600.00238
LSRTDE f(x): 600.09935
NLSHADE_RSP f(x): 602.5856
IMODE f(x): 625.4722
AGSK f(x): 614.54725
ARRDE f(x): 600.00587
GWO_DE f(x): 600.71827
NelderMead f(x): 668.52549
DA f(x): 605.55265
L_BFGS_B f(x): 668.5255
PSO f(x): 602.59005
DMSPSO f(x): 600.37642
SPSO2011 f(x): 601.78052
CMAES f(x): 600.3345
BIPOP_aCMAES f(x): 600.53816
RCMAES f(x): 600.00004
Scipy L-BFGS-B f(x): 668.52551
Scipy Nelder-Mead f(x): 669.03505
Scipy DA f(x): 603.72526
------------------------------------------------------------
Running optimization for func_4 (Dimension: 20)
============================================================
DE f(x): 921.55629
ABC f(x): 910.93957
LSHADE f(x): 854.27876
LSHADE_cnEpSin f(x): 833.08867
JADE f(x): 819.79005
jSO f(x): 854.87208
j2020 f(x): 919.296
LSRTDE f(x): 908.13509
NLSHADE_RSP f(x): 882.59239
IMODE f(x): 924.68848
AGSK f(x): 898.23827
ARRDE f(x): 807.95989
GWO_DE f(x): 892.09169
NelderMead f(x): 890.54093
DA f(x): 932.32807
L_BFGS_B f(x): 890.54093
PSO f(x): 835.81846
DMSPSO f(x): 835.81849
SPSO2011 f(x): 868.11726
CMAES f(x): 811.9395
BIPOP_aCMAES f(x): 838.80334
RCMAES f(x): 807.95968
Scipy L-BFGS-B f(x): 890.54093
Scipy Nelder-Mead f(x): 892.11966
Scipy DA f(x): 899.49524
------------------------------------------------------------
Running optimization for func_5 (Dimension: 20)
============================================================
DE f(x): 1127.6864
ABC f(x): 3441.794
LSHADE f(x): 900.72922
LSHADE_cnEpSin f(x): 900.00023
JADE f(x): 900
jSO f(x): 900.08967
j2020 f(x): 900.25644
LSRTDE f(x): 900.0038
NLSHADE_RSP f(x): 1035.6895
IMODE f(x): 1975.8172
AGSK f(x): 1160.9526
ARRDE f(x): 900
GWO_DE f(x): 958.7145
NelderMead f(x): 2456.1107
DA f(x): 3133.3091
L_BFGS_B f(x): 2458.8607
PSO f(x): 1570.7013
DMSPSO f(x): 911.43741
SPSO2011 f(x): 900.05354
CMAES f(x): 900
BIPOP_aCMAES f(x): 900
RCMAES f(x): 900
Scipy L-BFGS-B f(x): 2458.8607
Scipy Nelder-Mead f(x): 2457.195
Scipy DA f(x): 2875.4063
------------------------------------------------------------
Running optimization for func_6 (Dimension: 20)
============================================================
DE f(x): 2718.2183
ABC f(x): 28669.942
LSHADE f(x): 1910.8788
LSHADE_cnEpSin f(x): 1855.173
JADE f(x): 1925.221
jSO f(x): 1884.693
j2020 f(x): 183901.13
LSRTDE f(x): 1844.8332
NLSHADE_RSP f(x): 1909.2953
IMODE f(x): 34398225
AGSK f(x): 102295.05
ARRDE f(x): 1860.0103
GWO_DE f(x): 66915.161
NelderMead f(x): 1899.6356
DA f(x): 1850.2409
L_BFGS_B f(x): 1875.3024
PSO f(x): 5513.8029
DMSPSO f(x): 1981.4143
SPSO2011 f(x): 2950.0372
CMAES f(x): 1952.0223
BIPOP_aCMAES f(x): 1830.306
RCMAES f(x): 1850.3832
Scipy L-BFGS-B f(x): 1871.7843
Scipy Nelder-Mead f(x): 2054.1894
Scipy DA f(x): 1812.5904
------------------------------------------------------------
Running optimization for func_7 (Dimension: 20)
============================================================
DE f(x): 2033.3604
ABC f(x): 2093.5065
LSHADE f(x): 2063.4361
LSHADE_cnEpSin f(x): 2052.696
JADE f(x): 2034.8118
jSO f(x): 2052.9419
j2020 f(x): 2057.4182
LSRTDE f(x): 2025.5151
NLSHADE_RSP f(x): 2033.4797
IMODE f(x): 2085.0425
AGSK f(x): 2103.7497
ARRDE f(x): 2025.044
GWO_DE f(x): 2043.1313
NelderMead f(x): 2529.0241
DA f(x): 2068.3336
L_BFGS_B f(x): 2528.1893
PSO f(x): 2101.0439
DMSPSO f(x): 2023.523
SPSO2011 f(x): 2084.381
CMAES f(x): 2049.4525
BIPOP_aCMAES f(x): 2094.9708
RCMAES f(x): 2021.3803
Scipy L-BFGS-B f(x): 2597.5477
Scipy Nelder-Mead f(x): 2617.3528
Scipy DA f(x): 2055.0225
------------------------------------------------------------
Running optimization for func_8 (Dimension: 20)
============================================================
DE f(x): 2226.1043
ABC f(x): 2226.2005
LSHADE f(x): 2229.3323
LSHADE_cnEpSin f(x): 2232.1618
JADE f(x): 2224.2439
jSO f(x): 2232.4331
j2020 f(x): 2231.5721
LSRTDE f(x): 2228.759
NLSHADE_RSP f(x): 2225.7131
IMODE f(x): 2248.8373
AGSK f(x): 2233.2377
ARRDE f(x): 2228.115
GWO_DE f(x): 2233.6226
NelderMead f(x): 2636.88
DA f(x): 2222.3222
L_BFGS_B f(x): 2961.2446
PSO f(x): 2339.927
DMSPSO f(x): 2340.5193
SPSO2011 f(x): 2231.8724
CMAES f(x): 2224.9362
BIPOP_aCMAES f(x): 2221.0861
RCMAES f(x): 2227.8191
Scipy L-BFGS-B f(x): 2902.8126
Scipy Nelder-Mead f(x): 2890.3671
Scipy DA f(x): 2343.1096
------------------------------------------------------------
Running optimization for func_9 (Dimension: 20)
============================================================
DE f(x): 2506.9626
ABC f(x): 2486.7919
LSHADE f(x): 2480.7814
LSHADE_cnEpSin f(x): 2480.7813
JADE f(x): 2480.7813
jSO f(x): 2480.7813
j2020 f(x): 2480.7819
LSRTDE f(x): 2480.8057
NLSHADE_RSP f(x): 2482.3874
IMODE f(x): 2552.7522
AGSK f(x): 2480.7847
ARRDE f(x): 2480.7813
GWO_DE f(x): 2481.0204
NelderMead f(x): 2482.171
DA f(x): 2480.7813
L_BFGS_B f(x): 2480.7813
PSO f(x): 2480.7813
DMSPSO f(x): 2480.7813
SPSO2011 f(x): 2489.369
CMAES f(x): 2480.7813
BIPOP_aCMAES f(x): 2482.3772
RCMAES f(x): 2484.5006
Scipy L-BFGS-B f(x): 2480.7813
Scipy Nelder-Mead f(x): 2567.0897
Scipy DA f(x): 2480.7813
------------------------------------------------------------
Running optimization for func_10 (Dimension: 20)
============================================================
DE f(x): 3653.3005
ABC f(x): 2501.1775
LSHADE f(x): 2500.4803
LSHADE_cnEpSin f(x): 2500.6496
JADE f(x): 2500.5933
jSO f(x): 2500.5421
j2020 f(x): 2512.5501
LSRTDE f(x): 2500.5561
NLSHADE_RSP f(x): 2500.7545
IMODE f(x): 2501.2848
AGSK f(x): 2500.7967
ARRDE f(x): 2500.5408
GWO_DE f(x): 2500.5993
NelderMead f(x): 6169.0617
DA f(x): 2726.4177
L_BFGS_B f(x): 6109.5459
PSO f(x): 3512.719
DMSPSO f(x): 3088.8943
SPSO2011 f(x): 2500.8714
CMAES f(x): 3380.158
BIPOP_aCMAES f(x): 2625.1251
RCMAES f(x): 2500.5443
Scipy L-BFGS-B f(x): 6287.0682
Scipy Nelder-Mead f(x): 5716.4003
Scipy DA f(x): 2400.2811
------------------------------------------------------------
Running optimization for func_11 (Dimension: 20)
============================================================
DE f(x): 2933.2513
ABC f(x): 3287.1576
LSHADE f(x): 2900.0364
LSHADE_cnEpSin f(x): 2900.0333
JADE f(x): 2900
jSO f(x): 2900.0085
j2020 f(x): 2900.0082
LSRTDE f(x): 2900.4144
NLSHADE_RSP f(x): 2902.5872
IMODE f(x): 3287.6097
AGSK f(x): 2904.9657
ARRDE f(x): 3000
GWO_DE f(x): 2931.5272
NelderMead f(x): 3000
DA f(x): 3000
L_BFGS_B f(x): 2900
PSO f(x): 2900
DMSPSO f(x): 2900
SPSO2011 f(x): 2900.0047
CMAES f(x): 2900
BIPOP_aCMAES f(x): 2900
RCMAES f(x): 2900
Scipy L-BFGS-B f(x): 2900
Scipy Nelder-Mead f(x): 3510.1295
Scipy DA f(x): 2900
------------------------------------------------------------
Running optimization for func_12 (Dimension: 20)
============================================================
DE f(x): 2987.3575
ABC f(x): 2965.7603
LSHADE f(x): 2935.9888
LSHADE_cnEpSin f(x): 2933.2037
JADE f(x): 2938.0283
jSO f(x): 2932.2629
j2020 f(x): 2950.5141
LSRTDE f(x): 2940.1399
NLSHADE_RSP f(x): 2977.4347
IMODE f(x): 3069.1483
AGSK f(x): 2941.6012
ARRDE f(x): 2942.1424
GWO_DE f(x): 2946.1216
NelderMead f(x): 5490.2128
DA f(x): 2976.6605
L_BFGS_B f(x): 5490.2128
PSO f(x): 2949.3587
DMSPSO f(x): 2979.1232
SPSO2011 f(x): 2975.7828
CMAES f(x): 2950.6458
BIPOP_aCMAES f(x): 3000.716
RCMAES f(x): 2963.7624
Scipy L-BFGS-B f(x): 3434.9771
Scipy Nelder-Mead f(x): 5188.5097
Scipy DA f(x): 2989.4664
------------------------------------------------------------
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:
[12]:
# 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", "RCMAES"
]
# 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) = 1.4440892e-08
ABC : f(x) = 0.0056994221
LSHADE : f(x) = 1.747296e-12
LSHADE_cnEpSin : f(x) = 1.2546628e-13
JADE : f(x) = 3.9365631e-08
jSO : f(x) = 1.7792886e-11
j2020 : f(x) = 8.4535903e-05
LSRTDE : f(x) = 2.545778e-18
NLSHADE_RSP : f(x) = 1.0265447e-05
ARRDE : f(x) = 7.7391481e-10
GWO_DE : f(x) = 7.7970011e-05
NelderMead : f(x) = 4.0539659e-15
DA : f(x) = 7.3320295e-07
L_BFGS_B : f(x) = 7.3320324e-07
PSO : f(x) = 7.9373746e-06
DMSPSO : f(x) = 0.00024702002
SPSO2011 : f(x) = 0.00013752664
CMAES : f(x) = 9.8216578e-13
BIPOP_aCMAES : f(x) = 5.4117211e-22
RCMAES : f(x) = 1.1677759e-13
Scipy Dual Annealing (DA) : f(x) = 7.3247761e-07
Scipy L-BFGS-B : f(x) = 7.3247761e-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.
[13]:
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.2016821e-08
ABC : f(x) = 1.3409008e-06
LSHADE : f(x) = 5.5908417e-07
LSHADE_cnEpSin : f(x) = 1.2469598e-06
JADE : f(x) = 7.0607139e-08
jSO : f(x) = 8.4092472e-07
j2020 : f(x) = 1.5717859e-07
LSRTDE : f(x) = 4.7937334e-06
NLSHADE_RSP : f(x) = 7.8347728e-07
ARRDE : f(x) = 5.8702427e-09
GWO_DE : f(x) = 9.5340273e-09
NelderMead : f(x) = 7.3549528e-09
DA : f(x) = 7.8090419e-06
L_BFGS_B : f(x) = 2.5552938e-05
PSO : f(x) = 8.7937321e-09
DMSPSO : f(x) = 8.8752675e-10
SPSO2011 : f(x) = 2.4620218e-06
CMAES : f(x) = 3.093182e-08
BIPOP_aCMAES : f(x) = 1.5690981e-10
Scipy L-BFGS-B : f(x) = 2.4099371e-05
Scipy Dual Annealing : f(x) = 6.1466904e-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\).
[14]:
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
[15]:
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()
[16]:
# 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) = 1.1915898
ABC : f(x) = 18.48863
LSHADE : f(x) = 2.4194843
LSHADE_cnEpSin : f(x) = 0.53502555
JADE : f(x) = 2.9865776
jSO : f(x) = 1.6595643
j2020 : f(x) = 7.7543685
LSRTDE : f(x) = 0.28161899
NLSHADE_RSP : f(x) = 1.5008192
ARRDE : f(x) = 0.014022732
GWO_DE : f(x) = 1.4231015
NelderMead : f(x) = 0.072777402
DA : f(x) = 2.125748
L_BFGS_B : f(x) = 0.016089457
PSO : f(x) = 0.079717617
DMSPSO : f(x) = 0.0073668314
SPSO2011 : f(x) = 5.2242459
CMAES : f(x) = 1.9005412
BIPOP_aCMAES : f(x) = 0.66072312
Scipy L-BFGS-B : f(x) = 0.016125148
Scipy Dual Annealing : f(x) = 0.87696814
Scipy Nelder-Mead : f(x) = 0.072777402
============================================================
[ ]: