[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 '/home/muzakka/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",
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 : [1.0, 0.9999999999999998, 0.9999999999999997, 0.9999999999999998, 0.9999999999999836]
f(x) : 160200.00000000006
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,
maxevals=maxevals, callback=None, seed=None,
options={"population_size": 0, "convergence_tol":0.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.8796947e-06 Elapsed: 0.020 s
Algorithm: ABC f(x): 4.9772917e-06 Elapsed: 0.014 s
Algorithm: LSHADE f(x): 1.4353805e-09 Elapsed: 0.019 s
Algorithm: LSHADE_cnEpSin f(x): 5.4674191e-14 Elapsed: 0.034 s
Algorithm: JADE f(x): 7.8886091e-31 Elapsed: 0.027 s
Algorithm: jSO f(x): 1.3277479e-10 Elapsed: 0.022 s
Algorithm: j2020 f(x): 1.542933e-12 Elapsed: 0.114 s
Algorithm: LSRTDE f(x): 2.2833503e-11 Elapsed: 0.018 s
Algorithm: NLSHADE_RSP f(x): 2.2553804e-08 Elapsed: 0.018 s
Algorithm: ARRDE f(x): 4.288481e-27 Elapsed: 0.028 s
Algorithm: GWO_DE f(x): 2.9030876e-06 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 4.6709368e-30 Elapsed: 0.041 s
Algorithm: DA f(x): 1.2691251e-12 Elapsed: 0.003 s
Algorithm: L_BFGS_B f(x): 1.0668492e-13 Elapsed: 0.000 s
Algorithm: PSO f(x): 1.1904985e-14 Elapsed: 0.015 s
Algorithm: DMSPSO f(x): 4.3319447e-16 Elapsed: 0.019 s
Algorithm: SPSO2011 f(x): 2.9549519e-08 Elapsed: 0.022 s
Algorithm: CMAES f(x): 7.7764599e-30 Elapsed: 0.024 s
Algorithm: BIPOP_aCMAES f(x): 1.2150014e-27 Elapsed: 0.039 s
Algorithm: RCMAES f(x): 1.8351504e-13 Elapsed: 0.028 s
Algorithm: Scipy Nelder-Mead f(x): 5.8359322e-09 Elapsed: 0.038 s
Algorithm: Scipy L-BFGS-B f(x): 6.9420299e-12 Elapsed: 0.002 s
Algorithm: Scipy DA f(x): 2.153777e-16 Elapsed: 0.342 s
Function: rosenbrock
Algorithm: DE f(x): 55.388125 Elapsed: 0.017 s
Algorithm: ABC f(x): 1.4722782 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 4.6352793 Elapsed: 0.021 s
Algorithm: LSHADE_cnEpSin f(x): 2.8390061 Elapsed: 0.031 s
Algorithm: JADE f(x): 3.7829995 Elapsed: 0.033 s
Algorithm: jSO f(x): 2.175247 Elapsed: 0.021 s
Algorithm: j2020 f(x): 4.9777057 Elapsed: 0.175 s
Algorithm: LSRTDE f(x): 3.5782003 Elapsed: 0.019 s
Algorithm: NLSHADE_RSP f(x): 7.4663937 Elapsed: 0.022 s
Algorithm: ARRDE f(x): 0.65001897 Elapsed: 0.032 s
Algorithm: GWO_DE f(x): 7.345552 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 3.1653044e-27 Elapsed: 0.084 s
Algorithm: DA f(x): 1.4773537e-13 Elapsed: 0.023 s
Algorithm: L_BFGS_B f(x): 4.307979e-13 Elapsed: 0.005 s
Algorithm: PSO f(x): 2.9404998 Elapsed: 0.020 s
Algorithm: DMSPSO f(x): 1.3684967 Elapsed: 0.027 s
Algorithm: SPSO2011 f(x): 7.4379368 Elapsed: 0.021 s
Algorithm: CMAES f(x): 0.020598558 Elapsed: 0.027 s
Algorithm: BIPOP_aCMAES f(x): 1.299369e-20 Elapsed: 0.052 s
Algorithm: RCMAES f(x): 5.234485e-13 Elapsed: 0.029 s
Algorithm: Scipy Nelder-Mead f(x): 8.9958364e-09 Elapsed: 0.077 s
Algorithm: Scipy L-BFGS-B f(x): 1.1087483e-10 Elapsed: 0.070 s
Algorithm: Scipy DA f(x): 2.2407375e-10 Elapsed: 0.478 s
Function: rastrigin
Algorithm: DE f(x): 16.914289 Elapsed: 0.018 s
Algorithm: ABC f(x): 0.99590106 Elapsed: 0.017 s
Algorithm: LSHADE f(x): 0.41492165 Elapsed: 0.023 s
Algorithm: LSHADE_cnEpSin f(x): 4.6453245 Elapsed: 0.032 s
Algorithm: JADE f(x): 1.7763568e-15 Elapsed: 0.029 s
Algorithm: jSO f(x): 11.567473 Elapsed: 0.023 s
Algorithm: j2020 f(x): 7.8875801e-07 Elapsed: 0.163 s
Algorithm: LSRTDE f(x): 5.9835982 Elapsed: 0.023 s
Algorithm: NLSHADE_RSP f(x): 0.25889458 Elapsed: 0.022 s
Algorithm: ARRDE f(x): 2.9848895 Elapsed: 0.033 s
Algorithm: GWO_DE f(x): 20.664176 Elapsed: 0.022 s
Algorithm: NelderMead f(x): 102.47964 Elapsed: 0.025 s
Algorithm: DA f(x): 39.798216 Elapsed: 0.003 s
Algorithm: L_BFGS_B f(x): 102.47964 Elapsed: 0.001 s
Algorithm: PSO f(x): 8.9546271 Elapsed: 0.018 s
Algorithm: DMSPSO f(x): 2.9848772 Elapsed: 0.020 s
Algorithm: SPSO2011 f(x): 17.358313 Elapsed: 0.021 s
Algorithm: CMAES f(x): 7.9596674 Elapsed: 0.029 s
Algorithm: BIPOP_aCMAES f(x): 19.899141 Elapsed: 0.045 s
Algorithm: RCMAES f(x): 3.9798362 Elapsed: 0.034 s
Algorithm: Scipy Nelder-Mead f(x): 254.70399 Elapsed: 0.033 s
Algorithm: Scipy L-BFGS-B f(x): 237.78983 Elapsed: 0.006 s
Algorithm: Scipy DA f(x): 3.375078e-14 Elapsed: 0.524 s
Function: schaffer2
Algorithm: DE f(x): 0.65081687 Elapsed: 0.160 s
Algorithm: ABC f(x): 0.15434129 Elapsed: 0.171 s
Algorithm: LSHADE f(x): 0.20266581 Elapsed: 0.225 s
Algorithm: LSHADE_cnEpSin f(x): 0.27548185 Elapsed: 0.254 s
Algorithm: JADE f(x): 0.089429299 Elapsed: 0.181 s
Algorithm: jSO f(x): 0.42909799 Elapsed: 0.161 s
Algorithm: j2020 f(x): 0.47213831 Elapsed: 0.269 s
Algorithm: LSRTDE f(x): 0.72162619 Elapsed: 0.194 s
Algorithm: NLSHADE_RSP f(x): 0.20402425 Elapsed: 0.197 s
Algorithm: ARRDE f(x): 0.33442623 Elapsed: 0.184 s
Algorithm: GWO_DE f(x): 0.49450848 Elapsed: 0.189 s
Algorithm: NelderMead f(x): 0.18775994 Elapsed: 0.145 s
Algorithm: DA f(x): 0.54146345 Elapsed: 0.016 s
Algorithm: L_BFGS_B f(x): 0.18775994 Elapsed: 0.023 s
Algorithm: PSO f(x): 0.44707258 Elapsed: 0.181 s
Algorithm: DMSPSO f(x): 0.56897164 Elapsed: 0.153 s
Algorithm: SPSO2011 f(x): 0.60304324 Elapsed: 0.162 s
Algorithm: CMAES f(x): 0.42418884 Elapsed: 0.161 s
Algorithm: BIPOP_aCMAES f(x): 0.89193328 Elapsed: 0.210 s
Algorithm: RCMAES f(x): 0.11495135 Elapsed: 0.235 s
Algorithm: Scipy Nelder-Mead f(x): 0.38943872 Elapsed: 0.082 s
Algorithm: Scipy L-BFGS-B f(x): 0.38943873 Elapsed: 0.179 s
Algorithm: Scipy DA f(x): 0.048580255 Elapsed: 0.932 s
Function: griewank
Algorithm: DE f(x): 0.058070859 Elapsed: 0.029 s
Algorithm: ABC f(x): 0.0033985548 Elapsed: 0.045 s
Algorithm: LSHADE f(x): 0.0018340505 Elapsed: 0.023 s
Algorithm: LSHADE_cnEpSin f(x): 0.010286034 Elapsed: 0.033 s
Algorithm: JADE f(x): 3.3306691e-16 Elapsed: 0.032 s
Algorithm: jSO f(x): 0.15101667 Elapsed: 0.022 s
Algorithm: j2020 f(x): 0.041824189 Elapsed: 0.220 s
Algorithm: LSRTDE f(x): 0.0046657659 Elapsed: 0.021 s
Algorithm: NLSHADE_RSP f(x): 0.0076825755 Elapsed: 0.024 s
Algorithm: ARRDE f(x): 0 Elapsed: 0.034 s
Algorithm: GWO_DE f(x): 0.022150776 Elapsed: 0.023 s
Algorithm: NelderMead f(x): 0.02461003 Elapsed: 0.036 s
Algorithm: DA f(x): 0.11319805 Elapsed: 0.050 s
Algorithm: L_BFGS_B f(x): 0.02461003 Elapsed: 0.002 s
Algorithm: PSO f(x): 0.093409802 Elapsed: 0.019 s
Algorithm: DMSPSO f(x): 0.012316073 Elapsed: 0.021 s
Algorithm: SPSO2011 f(x): 0.0033482646 Elapsed: 0.024 s
Algorithm: CMAES f(x): 0 Elapsed: 0.018 s
Algorithm: BIPOP_aCMAES f(x): 0.014772408 Elapsed: 0.053 s
Algorithm: RCMAES f(x): 2.43916e-13 Elapsed: 0.032 s
Algorithm: Scipy Nelder-Mead f(x): 0.046729411 Elapsed: 0.051 s
Algorithm: Scipy L-BFGS-B f(x): 0.024637062 Elapsed: 0.035 s
Algorithm: Scipy DA f(x): 0.090965727 Elapsed: 0.585 s
Function: ackley
Algorithm: DE f(x): 1.1551485 Elapsed: 0.018 s
Algorithm: ABC f(x): 0.0026262615 Elapsed: 0.022 s
Algorithm: LSHADE f(x): 4.2703653e-05 Elapsed: 0.029 s
Algorithm: LSHADE_cnEpSin f(x): 1.3078989e-05 Elapsed: 0.037 s
Algorithm: JADE f(x): 1.4654944e-14 Elapsed: 0.030 s
Algorithm: jSO f(x): 8.4967761e-06 Elapsed: 0.026 s
Algorithm: j2020 f(x): 4.3406527e-09 Elapsed: 0.260 s
Algorithm: LSRTDE f(x): 3.7132093e-05 Elapsed: 0.022 s
Algorithm: NLSHADE_RSP f(x): 0.00025993931 Elapsed: 0.026 s
Algorithm: ARRDE f(x): 4.1255888e-13 Elapsed: 0.038 s
Algorithm: GWO_DE f(x): 0.00086205221 Elapsed: 0.028 s
Algorithm: NelderMead f(x): 9.0738777 Elapsed: 0.037 s
Algorithm: DA f(x): 8.4515582 Elapsed: 0.009 s
Algorithm: L_BFGS_B f(x): 9.4529928 Elapsed: 0.001 s
Algorithm: PSO f(x): 3.0926249e-08 Elapsed: 0.020 s
Algorithm: DMSPSO f(x): 8.7186845e-08 Elapsed: 0.024 s
Algorithm: SPSO2011 f(x): 0.00014708193 Elapsed: 0.029 s
Algorithm: CMAES f(x): 7.5495166e-15 Elapsed: 0.032 s
Algorithm: BIPOP_aCMAES f(x): 5.0182081e-14 Elapsed: 0.056 s
Algorithm: RCMAES f(x): 5.2624571e-13 Elapsed: 0.034 s
Algorithm: Scipy Nelder-Mead f(x): 12.719749 Elapsed: 0.035 s
Algorithm: Scipy L-BFGS-B f(x): 12.719749 Elapsed: 0.012 s
Algorithm: Scipy DA f(x): 1.9016682e-08 Elapsed: 0.782 s
Function: zakharov
Algorithm: DE f(x): 6.7319085e-10 Elapsed: 0.021 s
Algorithm: ABC f(x): 68.686964 Elapsed: 0.022 s
Algorithm: LSHADE f(x): 1.7793574e-06 Elapsed: 0.025 s
Algorithm: LSHADE_cnEpSin f(x): 8.3336135e-09 Elapsed: 0.036 s
Algorithm: JADE f(x): 1.2927008e-10 Elapsed: 0.042 s
Algorithm: jSO f(x): 1.7774563e-08 Elapsed: 0.025 s
Algorithm: j2020 f(x): 0.052630981 Elapsed: 0.282 s
Algorithm: LSRTDE f(x): 3.9927412e-09 Elapsed: 0.022 s
Algorithm: NLSHADE_RSP f(x): 0.0033036086 Elapsed: 0.028 s
Algorithm: ARRDE f(x): 6.9119074e-15 Elapsed: 0.044 s
Algorithm: GWO_DE f(x): 0.005279014 Elapsed: 0.026 s
Algorithm: NelderMead f(x): 9.5208937e-30 Elapsed: 0.094 s
Algorithm: DA f(x): 2.4048964e-11 Elapsed: 0.003 s
Algorithm: L_BFGS_B f(x): 2.1392905e-13 Elapsed: 0.003 s
Algorithm: PSO f(x): 3.6381897e-07 Elapsed: 0.023 s
Algorithm: DMSPSO f(x): 2.5707731e-09 Elapsed: 0.025 s
Algorithm: SPSO2011 f(x): 0.0077367976 Elapsed: 0.039 s
Algorithm: CMAES f(x): 4.3479854e-28 Elapsed: 0.033 s
Algorithm: BIPOP_aCMAES f(x): 2.8547234e-27 Elapsed: 0.061 s
Algorithm: RCMAES f(x): 3.1856509e-13 Elapsed: 0.036 s
Algorithm: Scipy Nelder-Mead f(x): 7.6416259e-09 Elapsed: 0.105 s
Algorithm: Scipy L-BFGS-B f(x): 7.2026284e-14 Elapsed: 0.033 s
Algorithm: Scipy DA f(x): 1.4354997e-13 Elapsed: 0.585 s
Function: bent_cigar
Algorithm: DE f(x): 29.006599 Elapsed: 0.015 s
Algorithm: ABC f(x): 0.11506033 Elapsed: 0.016 s
Algorithm: LSHADE f(x): 0.0025002294 Elapsed: 0.020 s
Algorithm: LSHADE_cnEpSin f(x): 5.9717649e-06 Elapsed: 0.030 s
Algorithm: JADE f(x): 4.9796845e-24 Elapsed: 0.027 s
Algorithm: jSO f(x): 0.00024070497 Elapsed: 0.020 s
Algorithm: j2020 f(x): 1.1231602e-08 Elapsed: 0.153 s
Algorithm: LSRTDE f(x): 3.9890005e-06 Elapsed: 0.024 s
Algorithm: NLSHADE_RSP f(x): 0.00016536792 Elapsed: 0.023 s
Algorithm: ARRDE f(x): 2.2682853e-20 Elapsed: 0.033 s
Algorithm: GWO_DE f(x): 1.2819706 Elapsed: 0.026 s
Algorithm: NelderMead f(x): 7.6172326e-24 Elapsed: 0.064 s
Algorithm: DA f(x): 5.7827062e-17 Elapsed: 0.002 s
Algorithm: L_BFGS_B f(x): 6.5127066e-14 Elapsed: 0.001 s
Algorithm: PSO f(x): 8.8400241e-10 Elapsed: 0.019 s
Algorithm: DMSPSO f(x): 3.1808956e-10 Elapsed: 0.025 s
Algorithm: SPSO2011 f(x): 97.414782 Elapsed: 0.024 s
Algorithm: CMAES f(x): 3.8441176e-07 Elapsed: 0.030 s
Algorithm: BIPOP_aCMAES f(x): 1.9155292e-21 Elapsed: 0.059 s
Algorithm: RCMAES f(x): 3.420942e-13 Elapsed: 0.034 s
Algorithm: Scipy Nelder-Mead f(x): 98.947303 Elapsed: 0.043 s
Algorithm: Scipy L-BFGS-B f(x): 2.0992461e-10 Elapsed: 0.080 s
Algorithm: Scipy DA f(x): 2.7037432e-10 Elapsed: 0.538 s
Function: levy
Algorithm: DE f(x): 6.4922554e-21 Elapsed: 0.026 s
Algorithm: ABC f(x): 3.6224872e-07 Elapsed: 0.031 s
Algorithm: LSHADE f(x): 9.1556036e-09 Elapsed: 0.035 s
Algorithm: LSHADE_cnEpSin f(x): 1.1069458e-10 Elapsed: 0.040 s
Algorithm: JADE f(x): 1.3831394e-30 Elapsed: 0.044 s
Algorithm: jSO f(x): 6.9503421e-10 Elapsed: 0.029 s
Algorithm: j2020 f(x): 7.1913004e-12 Elapsed: 0.360 s
Algorithm: LSRTDE f(x): 7.7276062e-11 Elapsed: 0.026 s
Algorithm: NLSHADE_RSP f(x): 5.394141e-08 Elapsed: 0.032 s
Algorithm: ARRDE f(x): 1.4485636e-22 Elapsed: 0.049 s
Algorithm: GWO_DE f(x): 2.9158882e-06 Elapsed: 0.028 s
Algorithm: NelderMead f(x): 2.3300009 Elapsed: 0.065 s
Algorithm: DA f(x): 1.883362 Elapsed: 0.016 s
Algorithm: L_BFGS_B f(x): 0.089528251 Elapsed: 0.002 s
Algorithm: PSO f(x): 0.45432402 Elapsed: 0.025 s
Algorithm: DMSPSO f(x): 1.3167123e-15 Elapsed: 0.025 s
Algorithm: SPSO2011 f(x): 1.9169279e-06 Elapsed: 0.029 s
Algorithm: CMAES f(x): 5.8939727e-30 Elapsed: 0.036 s
Algorithm: BIPOP_aCMAES f(x): 2.5393056e-25 Elapsed: 0.064 s
Algorithm: RCMAES f(x): 2.1584126e-13 Elapsed: 0.038 s
Algorithm: Scipy Nelder-Mead f(x): 10.612364 Elapsed: 0.111 s
Algorithm: Scipy L-BFGS-B f(x): 5.6358232 Elapsed: 0.074 s
Algorithm: Scipy DA f(x): 1.3245842e-10 Elapsed: 0.920 s
Function: discus
Algorithm: DE f(x): 1.2349284e-06 Elapsed: 0.015 s
Algorithm: ABC f(x): 4.2136472e-06 Elapsed: 0.015 s
Algorithm: LSHADE f(x): 2.645397e-07 Elapsed: 0.019 s
Algorithm: LSHADE_cnEpSin f(x): 2.7922858e-09 Elapsed: 0.029 s
Algorithm: JADE f(x): 3.4512665e-30 Elapsed: 0.025 s
Algorithm: jSO f(x): 1.3796864e-09 Elapsed: 0.019 s
Algorithm: j2020 f(x): 9.1269245e-13 Elapsed: 0.146 s
Algorithm: LSRTDE f(x): 1.4300898e-10 Elapsed: 0.017 s
Algorithm: NLSHADE_RSP f(x): 1.058335e-07 Elapsed: 0.022 s
Algorithm: ARRDE f(x): 2.1379832e-22 Elapsed: 0.027 s
Algorithm: GWO_DE f(x): 3.5937759e-05 Elapsed: 0.020 s
Algorithm: NelderMead f(x): 2.5838254e-24 Elapsed: 0.078 s
Algorithm: DA f(x): 4.0181518e-14 Elapsed: 0.002 s
Algorithm: L_BFGS_B f(x): 1.2333528e-13 Elapsed: 0.001 s
Algorithm: PSO f(x): 6.5854435e-12 Elapsed: 0.015 s
Algorithm: DMSPSO f(x): 1.8629488e-14 Elapsed: 0.017 s
Algorithm: SPSO2011 f(x): 76.396509 Elapsed: 0.025 s
Algorithm: CMAES f(x): 2.9307015e-18 Elapsed: 0.027 s
Algorithm: BIPOP_aCMAES f(x): 6.6426122e-15 Elapsed: 0.040 s
Algorithm: RCMAES f(x): 2.6317567e-13 Elapsed: 0.030 s
Algorithm: Scipy Nelder-Mead f(x): 7.8818509e-09 Elapsed: 0.155 s
Algorithm: Scipy L-BFGS-B f(x): 7.8454543e-12 Elapsed: 0.045 s
Algorithm: Scipy DA f(x): 6.0097778e-05 Elapsed: 0.414 s
Function: drop_wave
Algorithm: DE f(x): -1 Elapsed: 0.011 s
Algorithm: ABC f(x): -0.99185923 Elapsed: 0.031 s
Algorithm: LSHADE f(x): -1 Elapsed: 0.039 s
Algorithm: LSHADE_cnEpSin f(x): -1 Elapsed: 0.049 s
Algorithm: JADE f(x): -1 Elapsed: 0.024 s
Algorithm: jSO f(x): -1 Elapsed: 0.037 s
Algorithm: j2020 f(x): -1 Elapsed: 0.128 s
Algorithm: LSRTDE f(x): -1 Elapsed: 0.037 s
Algorithm: NLSHADE_RSP f(x): -1 Elapsed: 0.038 s
Algorithm: ARRDE f(x): -1 Elapsed: 0.045 s
Algorithm: GWO_DE f(x): -1 Elapsed: 0.039 s
Algorithm: NelderMead f(x): -1 Elapsed: 0.018 s
Algorithm: DA f(x): -1 Elapsed: 0.001 s
Algorithm: L_BFGS_B f(x): -0.93624533 Elapsed: 0.001 s
Algorithm: PSO f(x): -1 Elapsed: 0.034 s
Algorithm: DMSPSO f(x): -1 Elapsed: 0.034 s
Algorithm: SPSO2011 f(x): -0.99999843 Elapsed: 0.042 s
Algorithm: CMAES f(x): -0.99581752 Elapsed: 0.041 s
Algorithm: BIPOP_aCMAES f(x): -0.99374443 Elapsed: 0.062 s
Algorithm: RCMAES f(x): -0.99496582 Elapsed: 0.047 s
Algorithm: Scipy Nelder-Mead f(x): -0.053939199 Elapsed: 0.016 s
Algorithm: Scipy L-BFGS-B f(x): -0.060920875 Elapsed: 0.003 s
Algorithm: Scipy DA f(x): -0.93624533 Elapsed: 0.386 s
Function: goldstein_price
Algorithm: DE f(x): 3 Elapsed: 0.022 s
Algorithm: ABC f(x): 42.812827 Elapsed: 0.042 s
Algorithm: LSHADE f(x): 3 Elapsed: 0.048 s
Algorithm: LSHADE_cnEpSin f(x): 3 Elapsed: 0.065 s
Algorithm: JADE f(x): 3 Elapsed: 0.035 s
Algorithm: jSO f(x): 3 Elapsed: 0.048 s
Algorithm: j2020 f(x): 3 Elapsed: 0.110 s
Algorithm: LSRTDE f(x): 3 Elapsed: 0.039 s
Algorithm: NLSHADE_RSP f(x): 3 Elapsed: 0.043 s
Algorithm: ARRDE f(x): 3 Elapsed: 0.046 s
Algorithm: GWO_DE f(x): 3 Elapsed: 0.041 s
Algorithm: NelderMead f(x): 3 Elapsed: 0.013 s
Algorithm: DA f(x): 410.47045 Elapsed: 0.001 s
Algorithm: L_BFGS_B f(x): 3 Elapsed: 0.002 s
Algorithm: PSO f(x): 3 Elapsed: 0.036 s
Algorithm: DMSPSO f(x): 3 Elapsed: 0.038 s
Algorithm: SPSO2011 f(x): 3.0001546 Elapsed: 0.045 s
Algorithm: CMAES f(x): 3 Elapsed: 0.051 s
Algorithm: BIPOP_aCMAES f(x): 3 Elapsed: 0.067 s
Algorithm: RCMAES f(x): 3 Elapsed: 0.061 s
Algorithm: Scipy Nelder-Mead f(x): 84 Elapsed: 0.027 s
Algorithm: Scipy L-BFGS-B f(x): 3 Elapsed: 0.128 s
Algorithm: Scipy DA f(x): 3 Elapsed: 0.537 s
Function: exponential
Algorithm: DE f(x): -0.99985638 Elapsed: 0.022 s
Algorithm: ABC f(x): -0.99999983 Elapsed: 0.017 s
Algorithm: LSHADE f(x): -1 Elapsed: 0.027 s
Algorithm: LSHADE_cnEpSin f(x): -1 Elapsed: 0.035 s
Algorithm: JADE f(x): -1 Elapsed: 0.017 s
Algorithm: jSO f(x): -1 Elapsed: 0.024 s
Algorithm: j2020 f(x): -1 Elapsed: 0.174 s
Algorithm: LSRTDE f(x): -1 Elapsed: 0.023 s
Algorithm: NLSHADE_RSP f(x): -1 Elapsed: 0.024 s
Algorithm: ARRDE f(x): -1 Elapsed: 0.033 s
Algorithm: GWO_DE f(x): -0.9999971 Elapsed: 0.025 s
Algorithm: NelderMead f(x): -1 Elapsed: 0.030 s
Algorithm: DA f(x): -1.7984945e-13 Elapsed: 0.162 s
Algorithm: L_BFGS_B f(x): -1.609051e-22 Elapsed: 0.001 s
Algorithm: PSO f(x): -1 Elapsed: 0.017 s
Algorithm: DMSPSO f(x): -1 Elapsed: 0.021 s
Algorithm: SPSO2011 f(x): -1 Elapsed: 0.024 s
Algorithm: CMAES f(x): -1 Elapsed: 0.017 s
Algorithm: BIPOP_aCMAES f(x): -1 Elapsed: 0.054 s
Algorithm: RCMAES f(x): -4.4682748e-15 Elapsed: 0.160 s
Algorithm: Scipy Nelder-Mead f(x): -1 Elapsed: 0.044 s
Algorithm: Scipy L-BFGS-B f(x): -5.2446221e-54 Elapsed: 0.001 s
Algorithm: Scipy DA f(x): -1.2603173e-10 Elapsed: 0.415 s
Function: quartic
Algorithm: DE f(x): 0.070869952 Elapsed: 0.026 s
Algorithm: ABC f(x): 0.058337628 Elapsed: 0.027 s
Algorithm: LSHADE f(x): 0.034153371 Elapsed: 0.031 s
Algorithm: LSHADE_cnEpSin f(x): 0.0051602264 Elapsed: 0.040 s
Algorithm: JADE f(x): 0.0040307964 Elapsed: 0.044 s
Algorithm: jSO f(x): 0.020823493 Elapsed: 0.031 s
Algorithm: j2020 f(x): 0.013745377 Elapsed: 0.246 s
Algorithm: LSRTDE f(x): 0.0060928615 Elapsed: 0.028 s
Algorithm: NLSHADE_RSP f(x): 0.0092803471 Elapsed: 0.030 s
Algorithm: ARRDE f(x): 0.0021502969 Elapsed: 0.041 s
Algorithm: GWO_DE f(x): 0.007787476 Elapsed: 0.028 s
Algorithm: NelderMead f(x): 1.1578399 Elapsed: 0.119 s
Algorithm: DA f(x): 0.043719912 Elapsed: 0.026 s
Algorithm: L_BFGS_B f(x): 0.11726177 Elapsed: 0.001 s
Algorithm: PSO f(x): 0.016140929 Elapsed: 0.025 s
Algorithm: DMSPSO f(x): 0.011472653 Elapsed: 0.026 s
Algorithm: SPSO2011 f(x): 0.016133436 Elapsed: 0.031 s
Algorithm: CMAES f(x): 0.0033771471 Elapsed: 0.012 s
Algorithm: BIPOP_aCMAES f(x): 0.00022872766 Elapsed: 0.059 s
Algorithm: RCMAES f(x): 0.0043934279 Elapsed: 0.039 s
Algorithm: Scipy Nelder-Mead f(x): 11.235701 Elapsed: 0.293 s
Algorithm: Scipy L-BFGS-B f(x): 50784.738 Elapsed: 0.009 s
Algorithm: Scipy DA f(x): 0.26768236 Elapsed: 0.485 s
Function: hybrid_composition1
Algorithm: DE f(x): 8.9683086 Elapsed: 0.020 s
Algorithm: ABC f(x): 27.482065 Elapsed: 0.025 s
Algorithm: LSHADE f(x): 8.9683095 Elapsed: 0.029 s
Algorithm: LSHADE_cnEpSin f(x): 8.9683084 Elapsed: 0.036 s
Algorithm: JADE f(x): 8.9683084 Elapsed: 0.045 s
Algorithm: jSO f(x): 8.9683085 Elapsed: 0.030 s
Algorithm: j2020 f(x): 46.125917 Elapsed: 0.300 s
Algorithm: LSRTDE f(x): 8.9683085 Elapsed: 0.025 s
Algorithm: NLSHADE_RSP f(x): 8.9683114 Elapsed: 0.034 s
Algorithm: ARRDE f(x): 8.9683084 Elapsed: 0.051 s
Algorithm: GWO_DE f(x): 8.9707298 Elapsed: 0.034 s
Algorithm: NelderMead f(x): 8.9683084 Elapsed: 0.077 s
Algorithm: DA f(x): 127.26569 Elapsed: 0.042 s
Algorithm: L_BFGS_B f(x): 129.896 Elapsed: 0.004 s
Algorithm: PSO f(x): 8.9683084 Elapsed: 0.029 s
Algorithm: DMSPSO f(x): 8.9683084 Elapsed: 0.032 s
Algorithm: SPSO2011 f(x): 8.9683403 Elapsed: 0.028 s
Algorithm: CMAES f(x): 8.9683084 Elapsed: 0.040 s
Algorithm: BIPOP_aCMAES f(x): 8.9683084 Elapsed: 0.067 s
Algorithm: RCMAES f(x): 8.9683085 Elapsed: 0.047 s
Algorithm: Scipy Nelder-Mead f(x): 81.481178 Elapsed: 0.070 s
Algorithm: Scipy L-BFGS-B f(x): 49.451818 Elapsed: 0.045 s
Algorithm: Scipy DA f(x): 8.9683084 Elapsed: 0.720 s
Function: hybrid_composition2
Algorithm: DE f(x): 0.004561202 Elapsed: 0.027 s
Algorithm: ABC f(x): 0.0059918142 Elapsed: 0.032 s
Algorithm: LSHADE f(x): 1.7486585e-05 Elapsed: 0.034 s
Algorithm: LSHADE_cnEpSin f(x): 7.2635021e-06 Elapsed: 0.043 s
Algorithm: JADE f(x): 1.5099033e-14 Elapsed: 0.042 s
Algorithm: jSO f(x): 1.1174438e-05 Elapsed: 0.035 s
Algorithm: j2020 f(x): 3.6833568e-10 Elapsed: 0.489 s
Algorithm: LSRTDE f(x): 9.4920236e-06 Elapsed: 0.030 s
Algorithm: NLSHADE_RSP f(x): 0.00031830377 Elapsed: 0.044 s
Algorithm: ARRDE f(x): 1.0980753e-10 Elapsed: 0.060 s
Algorithm: GWO_DE f(x): 0.0041439795 Elapsed: 0.035 s
Algorithm: NelderMead f(x): 2.1270735 Elapsed: 0.170 s
Algorithm: DA f(x): 1.5411461e-12 Elapsed: 0.064 s
Algorithm: L_BFGS_B f(x): 1.5647319e-11 Elapsed: 0.010 s
Algorithm: PSO f(x): 1.1284677e-07 Elapsed: 0.027 s
Algorithm: DMSPSO f(x): 1.2772599e-07 Elapsed: 0.032 s
Algorithm: SPSO2011 f(x): 0.00063301396 Elapsed: 0.033 s
Algorithm: CMAES f(x): 1.2023368e-14 Elapsed: 0.047 s
Algorithm: BIPOP_aCMAES f(x): 5.492785e-14 Elapsed: 0.193 s
Algorithm: RCMAES f(x): 6.7368333e-13 Elapsed: 0.046 s
Algorithm: Scipy Nelder-Mead f(x): 9.7571206 Elapsed: 0.206 s
Algorithm: Scipy L-BFGS-B f(x): 6.6785884e-08 Elapsed: 0.323 s
Algorithm: Scipy DA f(x): 4.6583145e-08 Elapsed: 0.937 s
Function: hybrid_composition3
Algorithm: DE f(x): 1.9432442 Elapsed: 0.034 s
Algorithm: ABC f(x): 44.02707 Elapsed: 0.049 s
Algorithm: LSHADE f(x): 1.2839537 Elapsed: 0.045 s
Algorithm: LSHADE_cnEpSin f(x): 1.2839526 Elapsed: 0.057 s
Algorithm: JADE f(x): 2.0659812 Elapsed: 0.123 s
Algorithm: jSO f(x): 1.2839529 Elapsed: 0.048 s
Algorithm: j2020 f(x): 1.2297994 Elapsed: 0.697 s
Algorithm: LSRTDE f(x): 1.2839526 Elapsed: 0.043 s
Algorithm: NLSHADE_RSP f(x): 1.2895342 Elapsed: 0.061 s
Algorithm: ARRDE f(x): 1.2839526 Elapsed: 0.090 s
Algorithm: GWO_DE f(x): 1.2937963 Elapsed: 0.046 s
Algorithm: NelderMead f(x): 34.881183 Elapsed: 0.191 s
Algorithm: DA f(x): 409.67197 Elapsed: 0.021 s
Algorithm: L_BFGS_B f(x): 1.7576298 Elapsed: 0.009 s
Algorithm: PSO f(x): 1.3048264 Elapsed: 0.048 s
Algorithm: DMSPSO f(x): 1.2839526 Elapsed: 0.060 s
Algorithm: SPSO2011 f(x): 1.3928593 Elapsed: 0.050 s
Algorithm: CMAES f(x): 1.2839526 Elapsed: 0.062 s
Algorithm: BIPOP_aCMAES f(x): 1.2839526 Elapsed: 0.110 s
Algorithm: RCMAES f(x): 1.2839526 Elapsed: 0.057 s
Algorithm: Scipy Nelder-Mead f(x): 95.146651 Elapsed: 0.436 s
Algorithm: Scipy L-BFGS-B f(x): 3.2449736 Elapsed: 0.189 s
Algorithm: Scipy DA f(x): 84.671525 Elapsed: 1.593 s
Function: happy_cat
Algorithm: DE f(x): 0.24842443 Elapsed: 0.020 s
Algorithm: ABC f(x): 0.14198151 Elapsed: 0.020 s
Algorithm: LSHADE f(x): 0.087076102 Elapsed: 0.024 s
Algorithm: LSHADE_cnEpSin f(x): 0.062076569 Elapsed: 0.033 s
Algorithm: JADE f(x): 0.092519283 Elapsed: 0.041 s
Algorithm: jSO f(x): 0.16814755 Elapsed: 0.023 s
Algorithm: j2020 f(x): 0.21229457 Elapsed: 0.256 s
Algorithm: LSRTDE f(x): 0.037592313 Elapsed: 0.023 s
Algorithm: NLSHADE_RSP f(x): 0.17675636 Elapsed: 0.025 s
Algorithm: ARRDE f(x): 0.069108926 Elapsed: 0.041 s
Algorithm: GWO_DE f(x): 0.063681861 Elapsed: 0.024 s
Algorithm: NelderMead f(x): 0.67618088 Elapsed: 0.047 s
Algorithm: DA f(x): 0.48024234 Elapsed: 0.042 s
Algorithm: L_BFGS_B f(x): 0.48737281 Elapsed: 0.005 s
Algorithm: PSO f(x): 0.068418114 Elapsed: 0.019 s
Algorithm: DMSPSO f(x): 0.11946681 Elapsed: 0.021 s
Algorithm: SPSO2011 f(x): 0.1403372 Elapsed: 0.025 s
Algorithm: CMAES f(x): 0.053993164 Elapsed: 0.032 s
Algorithm: BIPOP_aCMAES f(x): 0.12681222 Elapsed: 0.055 s
Algorithm: RCMAES f(x): 0.023070824 Elapsed: 0.035 s
Algorithm: Scipy Nelder-Mead f(x): 1.4407279 Elapsed: 0.053 s
Algorithm: Scipy L-BFGS-B f(x): 0.0058185876 Elapsed: 0.034 s
Algorithm: Scipy DA f(x): 0.030118229 Elapsed: 0.490 s
Function: michalewics
Algorithm: DE f(x): -7.9662317 Elapsed: 0.029 s
Algorithm: ABC f(x): -9.1054083 Elapsed: 0.030 s
Algorithm: LSHADE f(x): -8.831381 Elapsed: 0.032 s
Algorithm: LSHADE_cnEpSin f(x): -6.9124412 Elapsed: 0.042 s
Algorithm: JADE f(x): -9.9532791 Elapsed: 0.041 s
Algorithm: jSO f(x): -7.2776346 Elapsed: 0.034 s
Algorithm: j2020 f(x): -8.8476617 Elapsed: 0.232 s
Algorithm: LSRTDE f(x): -7.3367531 Elapsed: 0.031 s
Algorithm: NLSHADE_RSP f(x): -9.1364566 Elapsed: 0.051 s
Algorithm: ARRDE f(x): -6.218818 Elapsed: 0.077 s
Algorithm: GWO_DE f(x): -4.6309655 Elapsed: 0.037 s
Algorithm: NelderMead f(x): -3.6164748 Elapsed: 0.164 s
Algorithm: DA f(x): -8.8685657 Elapsed: 0.029 s
Algorithm: L_BFGS_B f(x): -2.691988 Elapsed: 0.007 s
Algorithm: PSO f(x): -8.8899702 Elapsed: 0.026 s
Algorithm: DMSPSO f(x): -4.649747 Elapsed: 0.030 s
Algorithm: SPSO2011 f(x): -4.6285815 Elapsed: 0.033 s
Algorithm: CMAES f(x): -8.4216953 Elapsed: 0.036 s
Algorithm: BIPOP_aCMAES f(x): -5.4731534 Elapsed: 0.059 s
Algorithm: RCMAES f(x): -8.8458964 Elapsed: 0.044 s
Algorithm: Scipy Nelder-Mead f(x): -4.2489914 Elapsed: 0.060 s
Algorithm: Scipy L-BFGS-B f(x): -3.2901105 Elapsed: 0.171 s
Algorithm: Scipy DA f(x): -9.7304209 Elapsed: 1.038 s
Function: scaffer6
Algorithm: DE f(x): 0.44893978 Elapsed: 0.190 s
Algorithm: ABC f(x): 0.12666977 Elapsed: 0.188 s
Algorithm: LSHADE f(x): 0.13879553 Elapsed: 0.200 s
Algorithm: LSHADE_cnEpSin f(x): 0.21941075 Elapsed: 0.211 s
Algorithm: JADE f(x): 0.095418172 Elapsed: 0.192 s
Algorithm: jSO f(x): 0.58634406 Elapsed: 0.190 s
Algorithm: j2020 f(x): 0.29763368 Elapsed: 0.255 s
Algorithm: LSRTDE f(x): 0.41882412 Elapsed: 0.151 s
Algorithm: NLSHADE_RSP f(x): 0.16498872 Elapsed: 0.161 s
Algorithm: ARRDE f(x): 0.19949136 Elapsed: 0.164 s
Algorithm: GWO_DE f(x): 0.33439201 Elapsed: 0.163 s
Algorithm: NelderMead f(x): 0.18775994 Elapsed: 0.102 s
Algorithm: DA f(x): 0.41635277 Elapsed: 0.028 s
Algorithm: L_BFGS_B f(x): 0.18775994 Elapsed: 0.021 s
Algorithm: PSO f(x): 0.19747744 Elapsed: 0.156 s
Algorithm: DMSPSO f(x): 0.45169701 Elapsed: 0.152 s
Algorithm: SPSO2011 f(x): 0.40176798 Elapsed: 0.164 s
Algorithm: CMAES f(x): 0.4988771 Elapsed: 0.162 s
Algorithm: BIPOP_aCMAES f(x): 0.86123532 Elapsed: 0.173 s
Algorithm: RCMAES f(x): 0.14245952 Elapsed: 0.160 s
Algorithm: Scipy Nelder-Mead f(x): 0.38943872 Elapsed: 0.073 s
Algorithm: Scipy L-BFGS-B f(x): 0.38943873 Elapsed: 0.057 s
Algorithm: Scipy DA f(x): 0.087443189 Elapsed: 0.785 s
Function: hcf
Algorithm: DE f(x): 0.0040127119 Elapsed: 0.020 s
Algorithm: ABC f(x): 0.0039428539 Elapsed: 0.020 s
Algorithm: LSHADE f(x): 0.00010537824 Elapsed: 0.025 s
Algorithm: LSHADE_cnEpSin f(x): 1.4195001e-05 Elapsed: 0.036 s
Algorithm: JADE f(x): 0 Elapsed: 0.031 s
Algorithm: jSO f(x): 4.1700744e-05 Elapsed: 0.025 s
Algorithm: j2020 f(x): 4.3023236e-11 Elapsed: 0.207 s
Algorithm: LSRTDE f(x): 2.7320902e-05 Elapsed: 0.022 s
Algorithm: NLSHADE_RSP f(x): 4.8588408e-06 Elapsed: 0.026 s
Algorithm: ARRDE f(x): 3.8417507e-12 Elapsed: 0.038 s
Algorithm: GWO_DE f(x): 0.0023568929 Elapsed: 0.025 s
Algorithm: NelderMead f(x): 2.358758 Elapsed: 0.213 s
Algorithm: DA f(x): 1.8598669e-12 Elapsed: 0.040 s
Algorithm: L_BFGS_B f(x): 5.0026665e-12 Elapsed: 0.007 s
Algorithm: PSO f(x): 5.6795821e-08 Elapsed: 0.020 s
Algorithm: DMSPSO f(x): 4.2086301e-08 Elapsed: 0.022 s
Algorithm: SPSO2011 f(x): 0.00079478984 Elapsed: 0.033 s
Algorithm: CMAES f(x): 9.5075857e-15 Elapsed: 0.032 s
Algorithm: BIPOP_aCMAES f(x): 7.8962444e-14 Elapsed: 0.066 s
Algorithm: RCMAES f(x): 5.9729999e-13 Elapsed: 0.031 s
Algorithm: Scipy Nelder-Mead f(x): 9.2898681 Elapsed: 0.149 s
Algorithm: Scipy L-BFGS-B f(x): 3.4309798e-08 Elapsed: 0.247 s
Algorithm: Scipy DA f(x): 4.7082426e-08 Elapsed: 0.642 s
Function: grie_rosen
Algorithm: DE f(x): 6.6380551 Elapsed: 0.019 s
Algorithm: ABC f(x): 1.3856696 Elapsed: 0.022 s
Algorithm: LSHADE f(x): 4.5895619 Elapsed: 0.036 s
Algorithm: LSHADE_cnEpSin f(x): 2.0254878 Elapsed: 0.037 s
Algorithm: JADE f(x): 5.4562989 Elapsed: 0.039 s
Algorithm: jSO f(x): 3.2760023 Elapsed: 0.024 s
Algorithm: j2020 f(x): 4.1823264 Elapsed: 0.208 s
Algorithm: LSRTDE f(x): 5.4609907 Elapsed: 0.022 s
Algorithm: NLSHADE_RSP f(x): 7.6993979 Elapsed: 0.027 s
Algorithm: ARRDE f(x): 1.0000266 Elapsed: 0.039 s
Algorithm: GWO_DE f(x): 8.1840974 Elapsed: 0.025 s
Algorithm: NelderMead f(x): 1 Elapsed: 0.085 s
Algorithm: DA f(x): 1 Elapsed: 0.032 s
Algorithm: L_BFGS_B f(x): 1 Elapsed: 0.006 s
Algorithm: PSO f(x): 5.5693049 Elapsed: 0.016 s
Algorithm: DMSPSO f(x): 8.9923264 Elapsed: 0.019 s
Algorithm: SPSO2011 f(x): 7.761184 Elapsed: 0.022 s
Algorithm: CMAES f(x): 1.0466296 Elapsed: 0.030 s
Algorithm: BIPOP_aCMAES f(x): 4.9865791 Elapsed: 0.050 s
Algorithm: RCMAES f(x): 1 Elapsed: 0.029 s
Algorithm: Scipy Nelder-Mead f(x): 1 Elapsed: 0.081 s
Algorithm: Scipy L-BFGS-B f(x): 1 Elapsed: 0.096 s
Algorithm: Scipy DA f(x): 1 Elapsed: 0.758 s
Function: dixon_price
Algorithm: DE f(x): 0.66666667 Elapsed: 0.013 s
Algorithm: ABC f(x): 0.021504914 Elapsed: 0.021 s
Algorithm: LSHADE f(x): 0.6666667 Elapsed: 0.025 s
Algorithm: LSHADE_cnEpSin f(x): 0.66666667 Elapsed: 0.035 s
Algorithm: JADE f(x): 0.66666667 Elapsed: 0.033 s
Algorithm: jSO f(x): 0.66666667 Elapsed: 0.025 s
Algorithm: j2020 f(x): 0.69717231 Elapsed: 0.239 s
Algorithm: LSRTDE f(x): 0.66666667 Elapsed: 0.023 s
Algorithm: NLSHADE_RSP f(x): 0.022934338 Elapsed: 0.027 s
Algorithm: ARRDE f(x): 0.66666667 Elapsed: 0.039 s
Algorithm: GWO_DE f(x): 0.66729414 Elapsed: 0.026 s
Algorithm: NelderMead f(x): 0.66666667 Elapsed: 0.049 s
Algorithm: DA f(x): 0.66666667 Elapsed: 0.003 s
Algorithm: L_BFGS_B f(x): 0.66666667 Elapsed: 0.004 s
Algorithm: PSO f(x): 0.66666667 Elapsed: 0.019 s
Algorithm: DMSPSO f(x): 0.66666667 Elapsed: 0.024 s
Algorithm: SPSO2011 f(x): 0.6668304 Elapsed: 0.029 s
Algorithm: CMAES f(x): 0.66666667 Elapsed: 0.032 s
Algorithm: BIPOP_aCMAES f(x): 0.66666667 Elapsed: 0.061 s
Algorithm: RCMAES f(x): 0.66666667 Elapsed: 0.036 s
Algorithm: Scipy Nelder-Mead f(x): 0.66666667 Elapsed: 0.114 s
Algorithm: Scipy L-BFGS-B f(x): 0.66666667 Elapsed: 0.101 s
Algorithm: Scipy DA f(x): 5.3988228e-11 Elapsed: 0.705 s
Function: eosom
Algorithm: DE f(x): -0.0090056781 Elapsed: 0.028 s
Algorithm: ABC f(x): -0.0090033933 Elapsed: 0.035 s
Algorithm: LSHADE f(x): -0.0090056781 Elapsed: 0.053 s
Algorithm: LSHADE_cnEpSin f(x): -0.0090056781 Elapsed: 0.045 s
Algorithm: JADE f(x): -0.0090056781 Elapsed: 0.025 s
Algorithm: jSO f(x): -0.0090056781 Elapsed: 0.036 s
Algorithm: j2020 f(x): -0.0090056781 Elapsed: 0.106 s
Algorithm: LSRTDE f(x): -0.0090056781 Elapsed: 0.033 s
Algorithm: NLSHADE_RSP f(x): -0.0090056781 Elapsed: 0.035 s
Algorithm: ARRDE f(x): -0.0090056781 Elapsed: 0.041 s
Algorithm: GWO_DE f(x): -0.0090056781 Elapsed: 0.039 s
Algorithm: NelderMead f(x): -7.8737549e-14 Elapsed: 0.013 s
Algorithm: DA f(x): -0.0075252849 Elapsed: 0.001 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.009005678 Elapsed: 0.039 s
Algorithm: CMAES f(x): -0.0090056781 Elapsed: 0.041 s
Algorithm: BIPOP_aCMAES f(x): -0.0090056781 Elapsed: 0.062 s
Algorithm: RCMAES f(x): -0.0090056781 Elapsed: 0.043 s
Algorithm: Scipy Nelder-Mead f(x): -0.0090056781 Elapsed: 0.013 s
Algorithm: Scipy L-BFGS-B f(x): -1.4567312e-07 Elapsed: 0.001 s
Algorithm: Scipy DA f(x): -0.0090056781 Elapsed: 0.452 s
Function: hgbat
Algorithm: DE f(x): 0.50042909 Elapsed: 0.024 s
Algorithm: ABC f(x): 0.51335789 Elapsed: 0.025 s
Algorithm: LSHADE f(x): 0.50000605 Elapsed: 0.027 s
Algorithm: LSHADE_cnEpSin f(x): 0.50000521 Elapsed: 0.039 s
Algorithm: JADE f(x): 0.5 Elapsed: 0.036 s
Algorithm: jSO f(x): 0.5000067 Elapsed: 0.027 s
Algorithm: j2020 f(x): 0.50000057 Elapsed: 0.288 s
Algorithm: LSRTDE f(x): 0.50000743 Elapsed: 0.027 s
Algorithm: NLSHADE_RSP f(x): 0.50283126 Elapsed: 0.030 s
Algorithm: ARRDE f(x): 0.50000001 Elapsed: 0.047 s
Algorithm: GWO_DE f(x): 0.50137955 Elapsed: 0.032 s
Algorithm: NelderMead f(x): 0.5 Elapsed: 0.088 s
Algorithm: DA f(x): 0.50000001 Elapsed: 0.047 s
Algorithm: L_BFGS_B f(x): 0.50000001 Elapsed: 0.005 s
Algorithm: PSO f(x): 0.50000021 Elapsed: 0.024 s
Algorithm: DMSPSO f(x): 0.50000006 Elapsed: 0.025 s
Algorithm: SPSO2011 f(x): 0.50012731 Elapsed: 0.028 s
Algorithm: CMAES f(x): 0.5 Elapsed: 0.040 s
Algorithm: BIPOP_aCMAES f(x): 0.5 Elapsed: 0.076 s
Algorithm: RCMAES f(x): 0.5 Elapsed: 0.039 s
Algorithm: Scipy Nelder-Mead f(x): 0.5000703 Elapsed: 0.062 s
Algorithm: Scipy L-BFGS-B f(x): 0.50000001 Elapsed: 0.072 s
Algorithm: Scipy DA f(x): 0.50000001 Elapsed: 0.626 s
Function: styblinski_tang
Algorithm: DE f(x): -349.2515 Elapsed: 0.019 s
Algorithm: ABC f(x): -391.66152 Elapsed: 0.028 s
Algorithm: LSHADE f(x): -391.66159 Elapsed: 0.033 s
Algorithm: LSHADE_cnEpSin f(x): -391.66166 Elapsed: 0.043 s
Algorithm: JADE f(x): -349.2515 Elapsed: 0.020 s
Algorithm: jSO f(x): -391.66166 Elapsed: 0.032 s
Algorithm: j2020 f(x): -391.66166 Elapsed: 0.196 s
Algorithm: LSRTDE f(x): -391.66166 Elapsed: 0.033 s
Algorithm: NLSHADE_RSP f(x): -391.66165 Elapsed: 0.032 s
Algorithm: ARRDE f(x): -391.66166 Elapsed: 0.042 s
Algorithm: GWO_DE f(x): -391.66158 Elapsed: 0.037 s
Algorithm: NelderMead f(x): -306.84134 Elapsed: 0.033 s
Algorithm: DA f(x): -335.11478 Elapsed: 0.002 s
Algorithm: L_BFGS_B f(x): -320.97806 Elapsed: 0.001 s
Algorithm: PSO f(x): -335.11478 Elapsed: 0.026 s
Algorithm: DMSPSO f(x): -363.38822 Elapsed: 0.029 s
Algorithm: SPSO2011 f(x): -349.24089 Elapsed: 0.031 s
Algorithm: CMAES f(x): -363.38822 Elapsed: 0.023 s
Algorithm: BIPOP_aCMAES f(x): -349.2515 Elapsed: 0.056 s
Algorithm: RCMAES f(x): -391.66166 Elapsed: 0.041 s
Algorithm: Scipy Nelder-Mead f(x): -250.29447 Elapsed: 0.057 s
Algorithm: Scipy L-BFGS-B f(x): -292.70462 Elapsed: 0.033 s
Algorithm: Scipy DA f(x): -391.66166 Elapsed: 0.510 s
Function: step
Algorithm: DE f(x): 0 Elapsed: 0.003 s
Algorithm: ABC f(x): 0 Elapsed: 0.015 s
Algorithm: LSHADE f(x): 0 Elapsed: 0.013 s
Algorithm: LSHADE_cnEpSin f(x): 0 Elapsed: 0.016 s
Algorithm: JADE f(x): 0 Elapsed: 0.004 s
Algorithm: jSO f(x): 0 Elapsed: 0.010 s
Algorithm: j2020 f(x): 0 Elapsed: 0.145 s
Algorithm: LSRTDE f(x): 0 Elapsed: 0.022 s
Algorithm: NLSHADE_RSP f(x): 0 Elapsed: 0.029 s
Algorithm: ARRDE f(x): 0 Elapsed: 0.051 s
Algorithm: GWO_DE f(x): 0 Elapsed: 0.031 s
Algorithm: NelderMead f(x): 98 Elapsed: 0.003 s
Algorithm: DA f(x): 20 Elapsed: 0.009 s
Algorithm: L_BFGS_B f(x): 103 Elapsed: 0.000 s
Algorithm: PSO f(x): 0 Elapsed: 0.023 s
Algorithm: DMSPSO f(x): 0 Elapsed: 0.020 s
Algorithm: SPSO2011 f(x): 0 Elapsed: 0.019 s
Algorithm: CMAES f(x): 0 Elapsed: 0.004 s
Algorithm: BIPOP_aCMAES f(x): 0 Elapsed: 0.066 s
Algorithm: RCMAES f(x): 0 Elapsed: 0.041 s
Algorithm: Scipy Nelder-Mead f(x): 256 Elapsed: 0.019 s
Algorithm: Scipy L-BFGS-B f(x): 256 Elapsed: 0.001 s
Algorithm: Scipy DA f(x): 0 Elapsed: 0.449 s
Function: weierstrass
Algorithm: DE f(x): 5.8761522 Elapsed: 1.202 s
Algorithm: ABC f(x): 2.3723588 Elapsed: 1.044 s
Algorithm: LSHADE f(x): 1.5049742 Elapsed: 1.068 s
Algorithm: LSHADE_cnEpSin f(x): 2.7693089 Elapsed: 1.223 s
Algorithm: JADE f(x): 0.1685608 Elapsed: 1.219 s
Algorithm: jSO f(x): 8.8892226 Elapsed: 1.081 s
Algorithm: j2020 f(x): 2.8053528 Elapsed: 1.292 s
Algorithm: LSRTDE f(x): 7.9584357 Elapsed: 1.146 s
Algorithm: NLSHADE_RSP f(x): 2.1754807 Elapsed: 1.023 s
Algorithm: ARRDE f(x): 3.326122 Elapsed: 0.994 s
Algorithm: GWO_DE f(x): 7.4846498 Elapsed: 1.086 s
Algorithm: NelderMead f(x): 16.331325 Elapsed: 0.246 s
Algorithm: DA f(x): 8.014514 Elapsed: 1.155 s
Algorithm: L_BFGS_B f(x): 17.40283 Elapsed: 0.273 s
Algorithm: PSO f(x): 0.027949274 Elapsed: 1.188 s
Algorithm: DMSPSO f(x): 4.0940825 Elapsed: 1.040 s
Algorithm: SPSO2011 f(x): 7.9086895 Elapsed: 1.015 s
Algorithm: CMAES f(x): 10.448703 Elapsed: 1.003 s
Algorithm: BIPOP_aCMAES f(x): 10.006577 Elapsed: 1.019 s
Algorithm: RCMAES f(x): 2.1740897 Elapsed: 1.046 s
Algorithm: Scipy Nelder-Mead f(x): 6.4472257 Elapsed: 0.174 s
Algorithm: Scipy L-BFGS-B f(x): 15.858066 Elapsed: 0.301 s
Algorithm: Scipy DA f(x): 5.1439642 Elapsed: 2.370 s
Function: sum_squares
Algorithm: DE f(x): 1.0058945e-20 Elapsed: 0.025 s
Algorithm: ABC f(x): 4.0018809e-06 Elapsed: 0.025 s
Algorithm: LSHADE f(x): 1.8222616e-09 Elapsed: 0.032 s
Algorithm: LSHADE_cnEpSin f(x): 8.9597182e-12 Elapsed: 0.032 s
Algorithm: JADE f(x): 8.2337357e-30 Elapsed: 0.020 s
Algorithm: jSO f(x): 8.1234558e-10 Elapsed: 0.021 s
Algorithm: j2020 f(x): 8.6117047e-13 Elapsed: 0.150 s
Algorithm: LSRTDE f(x): 6.5865205e-09 Elapsed: 0.018 s
Algorithm: NLSHADE_RSP f(x): 4.0121718e-08 Elapsed: 0.019 s
Algorithm: ARRDE f(x): 1.1467257e-24 Elapsed: 0.028 s
Algorithm: GWO_DE f(x): 1.4033047e-05 Elapsed: 0.020 s
Algorithm: NelderMead f(x): 8.310147e-30 Elapsed: 0.042 s
Algorithm: DA f(x): 1.3587359e-13 Elapsed: 0.002 s
Algorithm: L_BFGS_B f(x): 4.0453218e-14 Elapsed: 0.001 s
Algorithm: PSO f(x): 8.3874388e-15 Elapsed: 0.015 s
Algorithm: DMSPSO f(x): 5.7806741e-15 Elapsed: 0.019 s
Algorithm: SPSO2011 f(x): 9.4998011e-07 Elapsed: 0.020 s
Algorithm: CMAES f(x): 2.5958601e-29 Elapsed: 0.027 s
Algorithm: BIPOP_aCMAES f(x): 1.4833479e-26 Elapsed: 0.046 s
Algorithm: RCMAES f(x): 1.6814137e-13 Elapsed: 0.027 s
Algorithm: Scipy Nelder-Mead f(x): 1.6899228e-08 Elapsed: 0.041 s
Algorithm: Scipy L-BFGS-B f(x): 1.8569833e-11 Elapsed: 0.044 s
Algorithm: Scipy DA f(x): 4.1442849e-11 Elapsed: 0.456 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,
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) = 174.31405 | Elapsed: 1.81 sec
Algo : L_BFGS_B | f(x) = 100 | Elapsed: 1.74 sec
Algo : DA | f(x) = 100.00002 | Elapsed: 1.71 sec
Algo : Scipy Dual Annealing | f(x) = 100 | Elapsed: 10.59 sec
Algo : Scipy L-BFGS-B | f(x) = 100 | Elapsed: 4.55 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.49893952609903164), np.float64(0.7409753800678246), np.float64(0.24359533253570678), np.float64(0.5357962121266069), np.float64(0.46151024712130534), np.float64(0.39240877478906944), np.float64(0.6346171946138794), np.float64(0.44213163313063997)]
Elapsed : 0.0527501106262207
Calling the function sequentially :
[np.float64(0.49893952609903164), np.float64(0.7409753800678246), np.float64(0.24359533253570678), np.float64(0.5357962121266069), np.float64(0.46151024712130534), np.float64(0.39240877478906944), np.float64(0.6346171946138794), np.float64(0.44213163313063997)]
Elapsed : 0.4025554656982422
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,
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.9793382374756305, 9.982636076912668, -4.874947560843359, -4.855394656922106, 4.890119980137681, -4.904571604837544, 4.896492221865951, -4.9504384303105935]
f(x) : -7.7911872282137455
Elapsed: 9.690591812133789 seconds
Test function value : -7.7911872282137455
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,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 : [8.569440953483959, 7.020317330209963, 9.184611352677384, 2.3169961890615167, 7.969545092991909, 7.909275619087072, 7.717387640207804, 9.991115008678161]
f(x) : -9.356496428000847
Elapsed: 9.68142294883728 seconds
Test function value : 6.63427532464428
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__":.
[11]:
# 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())
Vectorization using Process_Parallel :
[np.float64(0.14347422107693497), np.float64(0.595757752378875), np.float64(0.24379180202046255), np.float64(0.5777028302138887), np.float64(0.27153814522743025), np.float64(0.32516728314335863), np.float64(0.6222880906835925), np.float64(0.44156938555407277)]
Elapsed : 0.16840600967407227
Calling the function sequentially :
[np.float64(0.14347422107693497), np.float64(0.595757752378875), np.float64(0.24379180202046255), np.float64(0.5777028302138887), np.float64(0.27153814522743025), np.float64(0.32516728314335863), np.float64(0.6222880906835925), np.float64(0.44156938555407277)]
Elapsed : 0.4021761417388916
True
[12]:
# 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,
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.967707305289708, -5.2841586321752425, -4.819575479547448, 5.001164040521943, 4.751497421558071, -5.056955854461807, 4.853100691209513, -4.817559553728316]
f(x) : -7.588002076496824
Elapsed: 9.84260106086731 seconds
Test function value : -7.588002076496824
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.
[14]:
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, 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",
"convergence_tol" : 0.0
}
).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 = 10000 # 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): 5085.5257
ABC f(x): 44222.213
LSHADE f(x): 1088.4817
LSHADE_cnEpSin f(x): 393.81561
JADE f(x): 1639.1365
jSO f(x): 663.08019
j2020 f(x): 18723.773
LSRTDE f(x): 807.35554
NLSHADE_RSP f(x): 10900.921
IMODE f(x): 35558.207
AGSK f(x): 21380.317
ARRDE f(x): 347.58412
GWO_DE f(x): 10862.459
NelderMead f(x): 2325.3118
DA f(x): 300
L_BFGS_B f(x): 300
PSO f(x): 2983.2594
DMSPSO f(x): 5558.866
SPSO2011 f(x): 27812.642
CMAES f(x): 300.00821
BIPOP_aCMAES f(x): 300
RCMAES f(x): 300.01891
Scipy L-BFGS-B f(x): 300.00003
Scipy Nelder-Mead f(x): 14246.918
Scipy DA f(x): 300.00008
------------------------------------------------------------
Running optimization for func_2 (Dimension: 20)
============================================================
DE f(x): 480.94136
ABC f(x): 547.98553
LSHADE f(x): 449.38307
LSHADE_cnEpSin f(x): 449.12225
JADE f(x): 449.10799
jSO f(x): 449.25107
j2020 f(x): 474.63626
LSRTDE f(x): 446.6905
NLSHADE_RSP f(x): 477.163
IMODE f(x): 1143.2173
AGSK f(x): 459.71648
ARRDE f(x): 449.08483
GWO_DE f(x): 466.5408
NelderMead f(x): 450.55737
DA f(x): 449.08448
L_BFGS_B f(x): 449.08448
PSO f(x): 528.23266
DMSPSO f(x): 449.08486
SPSO2011 f(x): 472.80406
CMAES f(x): 449.0982
BIPOP_aCMAES f(x): 445.78458
RCMAES f(x): 449.46406
Scipy L-BFGS-B f(x): 449.08448
Scipy Nelder-Mead f(x): 888.69774
Scipy DA f(x): 449.08448
------------------------------------------------------------
Running optimization for func_3 (Dimension: 20)
============================================================
DE f(x): 605.26772
ABC f(x): 627.07364
LSHADE f(x): 603.07316
LSHADE_cnEpSin f(x): 601.38124
JADE f(x): 600.01872
jSO f(x): 601.49659
j2020 f(x): 600.25933
LSRTDE f(x): 602.03484
NLSHADE_RSP f(x): 605.87478
IMODE f(x): 637.59573
AGSK f(x): 632.95622
ARRDE f(x): 600.02385
GWO_DE f(x): 601.76909
NelderMead f(x): 668.5376
DA f(x): 625.11935
L_BFGS_B f(x): 668.5255
PSO f(x): 609.19358
DMSPSO f(x): 600.04564
SPSO2011 f(x): 602.3647
CMAES f(x): 600.00001
BIPOP_aCMAES f(x): 600.12058
RCMAES f(x): 600.00064
Scipy L-BFGS-B f(x): 668.52549
Scipy Nelder-Mead f(x): 675.70408
Scipy DA f(x): 616.39695
------------------------------------------------------------
Running optimization for func_4 (Dimension: 20)
============================================================
DE f(x): 817.15029
ABC f(x): 944.69928
LSHADE f(x): 875.84062
LSHADE_cnEpSin f(x): 875.65484
JADE f(x): 848.52088
jSO f(x): 898.90865
j2020 f(x): 933.90753
LSRTDE f(x): 889.72233
NLSHADE_RSP f(x): 867.09167
IMODE f(x): 860.69252
AGSK f(x): 927.31042
ARRDE f(x): 836.40883
GWO_DE f(x): 894.76464
NelderMead f(x): 890.54093
DA f(x): 923.37427
L_BFGS_B f(x): 890.54093
PSO f(x): 854.72293
DMSPSO f(x): 832.83492
SPSO2011 f(x): 881.2455
CMAES f(x): 821.89128
BIPOP_aCMAES f(x): 837.80837
RCMAES f(x): 807.95979
Scipy L-BFGS-B f(x): 890.54093
Scipy Nelder-Mead f(x): 905.87623
Scipy DA f(x): 890.54093
------------------------------------------------------------
Running optimization for func_5 (Dimension: 20)
============================================================
DE f(x): 1202.7482
ABC f(x): 2949.1588
LSHADE f(x): 916.96704
LSHADE_cnEpSin f(x): 903.00592
JADE f(x): 901.03453
jSO f(x): 901.51869
j2020 f(x): 973.51848
LSRTDE f(x): 902.4021
NLSHADE_RSP f(x): 1071.9947
IMODE f(x): 3699.1048
AGSK f(x): 1290.3339
ARRDE f(x): 900.90882
GWO_DE f(x): 911.69531
NelderMead f(x): 2456.1107
DA f(x): 3049.2139
L_BFGS_B f(x): 2458.8607
PSO f(x): 964.26555
DMSPSO f(x): 900.08958
SPSO2011 f(x): 901.73755
CMAES f(x): 900
BIPOP_aCMAES f(x): 900.08953
RCMAES f(x): 900
Scipy L-BFGS-B f(x): 2458.8608
Scipy Nelder-Mead f(x): 2466.2063
Scipy DA f(x): 2436.8814
------------------------------------------------------------
Running optimization for func_6 (Dimension: 20)
============================================================
DE f(x): 2001.4795
ABC f(x): 79695.375
LSHADE f(x): 2930.9272
LSHADE_cnEpSin f(x): 3601.2958
JADE f(x): 5712.6806
jSO f(x): 3003.1556
j2020 f(x): 2782211.5
LSRTDE f(x): 1943.0639
NLSHADE_RSP f(x): 2650.1729
IMODE f(x): 1.4668535e+08
AGSK f(x): 458339.03
ARRDE f(x): 2001.3007
GWO_DE f(x): 92569.529
NelderMead f(x): 1930.6357
DA f(x): 1902.3229
L_BFGS_B f(x): 1875.3024
PSO f(x): 2217.6482
DMSPSO f(x): 7137.3758
SPSO2011 f(x): 451270.38
CMAES f(x): 2447.3192
BIPOP_aCMAES f(x): 1974.8113
RCMAES f(x): 1946.785
Scipy L-BFGS-B f(x): 1872.5982
Scipy Nelder-Mead f(x): 2054.1894
Scipy DA f(x): 1825.5024
------------------------------------------------------------
Running optimization for func_7 (Dimension: 20)
============================================================
DE f(x): 2024.1839
ABC f(x): 2187.1636
LSHADE f(x): 2088.4042
LSHADE_cnEpSin f(x): 2089.2345
JADE f(x): 2039.5176
jSO f(x): 2093.4964
j2020 f(x): 2088.2756
LSRTDE f(x): 2034.4739
NLSHADE_RSP f(x): 2040.5639
IMODE f(x): 2190.9346
AGSK f(x): 2111.774
ARRDE f(x): 2031.68
GWO_DE f(x): 2079.8137
NelderMead f(x): 2546.5845
DA f(x): 2182.4238
L_BFGS_B f(x): 2528.594
PSO f(x): 2138.6779
DMSPSO f(x): 2046.9619
SPSO2011 f(x): 2126.0449
CMAES f(x): 2050.9847
BIPOP_aCMAES f(x): 2078.1172
RCMAES f(x): 2024.0517
Scipy L-BFGS-B f(x): 2595.2809
Scipy Nelder-Mead f(x): 2617.3528
Scipy DA f(x): 2173.5444
------------------------------------------------------------
Running optimization for func_8 (Dimension: 20)
============================================================
DE f(x): 2353.9212
ABC f(x): 2224.9259
LSHADE f(x): 2238.7499
LSHADE_cnEpSin f(x): 2230.5309
JADE f(x): 2227.1813
jSO f(x): 2236.8952
j2020 f(x): 2237.586
LSRTDE f(x): 2229.7068
NLSHADE_RSP f(x): 2230.1174
IMODE f(x): 2277.3083
AGSK f(x): 2240.1263
ARRDE f(x): 2232.3614
GWO_DE f(x): 2239.9511
NelderMead f(x): 2636.9036
DA f(x): 2362.1594
L_BFGS_B f(x): 2961.2445
PSO f(x): 2357.6243
DMSPSO f(x): 2232.1705
SPSO2011 f(x): 2248.0455
CMAES f(x): 2353.5708
BIPOP_aCMAES f(x): 2344.7665
RCMAES f(x): 2231.7355
Scipy L-BFGS-B f(x): 2903.5382
Scipy Nelder-Mead f(x): 2890.3671
Scipy DA f(x): 2348.557
------------------------------------------------------------
Running optimization for func_9 (Dimension: 20)
============================================================
DE f(x): 2528.1743
ABC f(x): 2511.816
LSHADE f(x): 2480.9607
LSHADE_cnEpSin f(x): 2480.867
JADE f(x): 2480.7815
jSO f(x): 2480.8175
j2020 f(x): 2480.9503
LSRTDE f(x): 2481.9435
NLSHADE_RSP f(x): 2486.9747
IMODE f(x): 2503.6158
AGSK f(x): 2481.5201
ARRDE f(x): 2480.7815
GWO_DE f(x): 2481.4462
NelderMead f(x): 2522.4987
DA f(x): 2480.7813
L_BFGS_B f(x): 2480.7813
PSO f(x): 2480.782
DMSPSO f(x): 2480.7816
SPSO2011 f(x): 2498.2139
CMAES f(x): 2480.801
BIPOP_aCMAES f(x): 2481.4449
RCMAES f(x): 2484.9445
Scipy L-BFGS-B f(x): 2480.7813
Scipy Nelder-Mead f(x): 2651.3649
Scipy DA f(x): 2480.7813
------------------------------------------------------------
Running optimization for func_10 (Dimension: 20)
============================================================
DE f(x): 2500.974
ABC f(x): 2613.9834
LSHADE f(x): 2500.9714
LSHADE_cnEpSin f(x): 2500.82
JADE f(x): 2500.5708
jSO f(x): 2500.8611
j2020 f(x): 2501.052
LSRTDE f(x): 2500.8716
NLSHADE_RSP f(x): 2502.1077
IMODE f(x): 2518.3887
AGSK f(x): 2501.0293
ARRDE f(x): 2635.7722
GWO_DE f(x): 2500.8651
NelderMead f(x): 6169.0617
DA f(x): 4368.065
L_BFGS_B f(x): 6109.5459
PSO f(x): 2500.8826
DMSPSO f(x): 2821.411
SPSO2011 f(x): 2500.801
CMAES f(x): 2638.8114
BIPOP_aCMAES f(x): 4363.5404
RCMAES f(x): 2500.4804
Scipy L-BFGS-B f(x): 6287.3529
Scipy Nelder-Mead f(x): 6530.8204
Scipy DA f(x): 2501.26
------------------------------------------------------------
Running optimization for func_11 (Dimension: 20)
============================================================
DE f(x): 3256.454
ABC f(x): 3550.2215
LSHADE f(x): 2944.6148
LSHADE_cnEpSin f(x): 2917.51
JADE f(x): 2900.0421
jSO f(x): 2912.3607
j2020 f(x): 3716.4447
LSRTDE f(x): 2966.9575
NLSHADE_RSP f(x): 3231.9349
IMODE f(x): 3235.873
AGSK f(x): 3328.527
ARRDE f(x): 2900.0141
GWO_DE f(x): 2997.3447
NelderMead f(x): 3000.0006
DA f(x): 2900
L_BFGS_B f(x): 2900
PSO f(x): 2900.0768
DMSPSO f(x): 3000.4364
SPSO2011 f(x): 2908.4908
CMAES f(x): 2900
BIPOP_aCMAES f(x): 2900
RCMAES f(x): 2900.002
Scipy L-BFGS-B f(x): 2900
Scipy Nelder-Mead f(x): 5999.3357
Scipy DA f(x): 2900
------------------------------------------------------------
Running optimization for func_12 (Dimension: 20)
============================================================
DE f(x): 2972.9413
ABC f(x): 3030.895
LSHADE f(x): 2946.2603
LSHADE_cnEpSin f(x): 2950.3474
JADE f(x): 2941.3209
jSO f(x): 2951.2821
j2020 f(x): 2962.7803
LSRTDE f(x): 2967.9779
NLSHADE_RSP f(x): 3021.4467
IMODE f(x): 3235.7416
AGSK f(x): 2960.6791
ARRDE f(x): 2933.0833
GWO_DE f(x): 2957.3298
NelderMead f(x): 5490.2128
DA f(x): 3025.7172
L_BFGS_B f(x): 5490.213
PSO f(x): 3014.8504
DMSPSO f(x): 2965.1288
SPSO2011 f(x): 2973.7025
CMAES f(x): 2984.5286
BIPOP_aCMAES f(x): 2991.2327
RCMAES f(x): 3073.6232
Scipy L-BFGS-B f(x): 3344.4993
Scipy Nelder-Mead f(x): 6393.643
Scipy DA f(x): 2963.9672
------------------------------------------------------------
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:
[15]:
# 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,
algo=algo, maxevals=Nmaxeval, callback=None, seed=0,
options={
"population_size": 0,
"func_noise_ratio" : 0.0,
"N_points_derivative": 1,
"convergence_tol" : 0.0}
).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.4887049e-12
LSHADE_cnEpSin : f(x) = 2.2760653e-16
JADE : f(x) = 2.8549496e-09
jSO : f(x) = 5.4336223e-13
j2020 : f(x) = 8.4535903e-05
LSRTDE : f(x) = 5.1056681e-15
NLSHADE_RSP : f(x) = 1.0850745e-06
ARRDE : f(x) = 1.2473721e-12
GWO_DE : f(x) = 1.2315456e-05
NelderMead : f(x) = 4.0539659e-15
DA : f(x) = 2.5733361e-05
L_BFGS_B : f(x) = 7.3320324e-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) = 2.1084646e-22
RCMAES : f(x) = 1.150172e-13
Scipy Dual Annealing (DA) : f(x) = 7.3247663e-07
Scipy L-BFGS-B : f(x) = 7.3247663e-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.
[16]:
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,
algo=algo, maxevals=Nmaxeval, callback=None, seed=None,
options={"population_size": 0, "convergence_tol": 0.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) = 4.3643422e-08
ABC : f(x) = 7.8145767e-07
LSHADE : f(x) = 8.3456067e-07
LSHADE_cnEpSin : f(x) = 1.4529575e-06
JADE : f(x) = 2.4388061e-07
jSO : f(x) = 3.025535e-06
j2020 : f(x) = 6.0027859e-07
LSRTDE : f(x) = 4.5803423e-06
NLSHADE_RSP : f(x) = 4.3805794e-07
ARRDE : f(x) = 4.433319e-09
GWO_DE : f(x) = 5.7814618e-08
NelderMead : f(x) = 7.3549528e-09
DA : f(x) = 1.2573343e-05
L_BFGS_B : f(x) = 2.5552938e-05
PSO : f(x) = 4.5127993e-09
DMSPSO : f(x) = 8.2520556e-09
SPSO2011 : f(x) = 3.2138426e-06
CMAES : f(x) = 6.716247e-09
BIPOP_aCMAES : f(x) = 7.4143992e-11
Scipy L-BFGS-B : f(x) = 2.4099675e-05
Scipy Dual Annealing : f(x) = 6.1466923e-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\).
[17]:
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
[18]:
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()
[19]:
# 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,
maxevals=Nmaxeval, callback=None, seed=None,
options={
"population_size": 0,
"func_noise_ratio" : 0.0,
"N_points_derivative": 1,
"convergence_tol" : 0.0
}
).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.09567722
ABC : f(x) = 13.802409
LSHADE : f(x) = 0.77263411
LSHADE_cnEpSin : f(x) = 0.82627114
JADE : f(x) = 2.6116883
jSO : f(x) = 0.031029586
j2020 : f(x) = 6.6513568
LSRTDE : f(x) = 0.97951373
NLSHADE_RSP : f(x) = 0.48241609
ARRDE : f(x) = 0.087737629
GWO_DE : f(x) = 2.2650603
NelderMead : f(x) = 0.072777402
DA : f(x) = 1.2922966
L_BFGS_B : f(x) = 0.015659395
PSO : f(x) = 0.23069079
DMSPSO : f(x) = 0.080728862
SPSO2011 : f(x) = 3.3587771
CMAES : f(x) = 1.0264104
BIPOP_aCMAES : f(x) = 0.3277669
Scipy L-BFGS-B : f(x) = 0.016101053
Scipy Dual Annealing : f(x) = 0.98322231
Scipy Nelder-Mead : f(x) = 0.072777402
============================================================
[ ]:
[ ]: