Yabox: Yet another black-box optimization library for Python - https://github.com/pablormier/yabox
This notebook compares the performance of the Differential Evolution (DE) algorithm and the DE with parallel evaluation (PDE) implemented in Yabox against the default Scipy's implementation over a collection of common optimization functions.
Author: Pablo Rodríguez-Mier, @pablormier
In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
import sys
from time import time
# Load Yabox (from local)
# Comment this line to use the installed version
sys.path.insert(0, '../')
import yabox as yb
import scipy as sp
import numpy as np
# Import the DE implementations
from yabox.algorithms import DE, PDE
from yabox.utils import benchmark
from scipy.optimize import differential_evolution as SDE
In [ ]:
print('Yabox version: ', yb.__version__)
print('Scipy version: ', sp.__version__)
In [ ]:
config = dict(
# Runs per method and function, average the final results
runs = 1,
# Time limit for each method (in seconds)
stop_after = 30,
# Max number of iterations
maxiters = 1000000,
# Use a constant mutation factor (0-1)
mutation = 0.5,
# Recombination probability (0-1)
recombination = 0.5,
# Number of individuals in the population. NOTE: Since Scipy uses num_individuals = dimensions * popsize
# Select a size for popsize and a set of dimensions to test so that popsize / dimensions in every case
# produces an integer number
popsize = 64,
# Methods to be tested
methods = ['yabox_de', 'yabox_pde', 'scipy_de']
)
"The Ackley function is widely used for testing optimization algorithms. In its two-dimensional form, as shown in the plot above, it is characterized by a nearly flat outer region, and a large hole at the centre. The function poses a risk for optimization algorithms, particularly hillclimbing algorithms, to be trapped in one of its many local minima."
Global minimum:
$ f(\mathbf{x^*}) = 0, \text{at}~\mathbf{x^*} = (0, \dots, 0) $
In [ ]:
from yabox.problems import Ackley
Ackley().plot3d();
In [ ]:
# Run the set of benchmarks on Ackley using the config defined at the beginning of this notebook
ackley_data = benchmark.test(Ackley, config)
# Plot the performance of each algorithm (execution time vs. fitness)
benchmark.plot_results(ackley_data)
In [ ]:
benchmark.plot_results(ackley_data, use_time=False)
In [ ]:
benchmark.plot_time_per_iteration(ackley_data)
"The Rastrigin function has several local minima. It is highly multimodal, but locations of the minima are regularly distributed. It is shown in the plot in its two-dimensional form."
Global minimum:
$ f(\mathbf{x^*}) = 0, \text{at}~\mathbf{x^*} = (0, \dots, 0) $
In [ ]:
from yabox.problems import Rastrigin
Rastrigin().plot3d();
In [ ]:
rastrigin_data = benchmark.test(Rastrigin, config)
benchmark.plot_results(rastrigin_data)
In [ ]:
benchmark.plot_results(rastrigin_data, use_time=False)
In [ ]:
benchmark.plot_time_per_iteration(rastrigin_data)
"The Schwefel function is complex, with many local minima. The plot shows the two-dimensional form of the function."
Global minimum:
$ f(\mathbf{x^*}) = 0, \text{at}~\mathbf{x^*} = (420.9687, \dots, 420.9687) $
In [ ]:
from yabox.problems import Schwefel
Schwefel().plot3d();
In [ ]:
schwefel_data = benchmark.test(Schwefel, config)
benchmark.plot_results(schwefel_data)
In [ ]:
benchmark.plot_results(schwefel_data, use_time=False)
In [ ]:
benchmark.plot_time_per_iteration(schwefel_data)
"The Michalewicz function has d! local minima, and it is multimodal. The parameter m defines the steepness of they valleys and ridges; a larger m leads to a more difficult search. The recommended value of m is m = 10."
In [ ]:
from yabox.problems import Michalewicz
Michalewicz().plot3d();
In [ ]:
michalewicz_data = benchmark.test(Michalewicz, config)
benchmark.plot_results(michalewicz_data)
"The Griewank function has many widespread local minima, which are regularly distributed."
Global minimum:
$ f(\mathbf{x^*}) = 0, \text{at}~\mathbf{x^*} = (0, \dots, 0) $
In [ ]:
from yabox.problems import Griewank
Griewank().plot3d();
In [ ]:
griewank_data = benchmark.test(Griewank, config)
benchmark.plot_results(griewank_data)