Ensemble of Differential Evolution Variants (EDEV)

A powerful hybrid ensemble of three differential evolution variants: JADE (adaptive differential evolution with optional external archive), CoDE (differential evolution with composite trial vector generation strategies and control parameters), and EPSDE (differential evolution algorithm with ensemble of parameters and mutation strategies).

Original paper: Wu, G., Shen, X., Li, H., Chen, H., Lin, A., Suganthan, P. N. (2018). Ensemble of differential evolution variants. Information Sciences, 423, 172-186.

What can you use?

  • Multi processing: ✔️

  • Discrete spaces: ✔️

  • Continuous spaces: ✔️

  • Mixed Discrete/Continuous spaces: ✔️

Parameters

class neorl.hybrid.edev.EDEV(mode, bounds, fit, npop=100, int_transform='nearest_int', ncores=1, seed=None)[source]

Ensemble of differential evolution variants

Parameters
  • mode – (str) problem type, either min for minimization problem or max for maximization

  • bounds – (dict) input parameter type and lower/upper bounds in dictionary form. Example: bounds={'x1': ['int', 1, 4], 'x2': ['float', 0.1, 0.8], 'x3': ['float', 2.2, 6.2]}

  • fit – (function) the fitness function

  • npop – (int): total size of the full population, which will be divided into three sub-populations

  • int_transform – (str): method of handling int/discrete variables, choose from: nearest_int, sigmoid, minmax.

  • ncores – (int) number of parallel processors (must be <= npop)

  • seed – (int) random seed for sampling

evolute(ngen, ng=20, x0=None, verbose=False)[source]

This function evolutes the EDEV algorithm for a number of generations.

Parameters
  • ngen – (int) number of generations to evolute

  • ng – (int) the period or number of generations to determine the best performing DE variant and reward subpopulation assignment, ng < ngen (see Notes below for more info).

  • x0 – (list of lists) initial position of the individuals (must be of same size as npop)

  • verbose – (bool) print statistics to screen

Returns

(tuple) (best individual, best fitness, and dictionary containing major search results)

Example

from neorl import EDEV

#Define the fitness function
def FIT(individual):
    """Sphere test objective function.
                    F(x) = sum_{i=1}^d xi^2
                    d=1,2,3,...
                    Range: [-100,100]
                    Minima: 0
    """
    y=sum(x**2 for x in individual)
    return y

#Setup the parameter space (d=5)
nx=5
BOUNDS={}
for i in range(1,nx+1):
    BOUNDS['x'+str(i)]=['float', -100, 100]

#setup and evolute EDEV
edev=EDEV(mode='min', bounds=BOUNDS, fit=FIT, npop=100, ncores=1, seed=1)
x_best, y_best, edev_hist=edev.evolute(ngen=100, ng=10, verbose=1)

Notes

  • Choosing the value of npop and lambda_ should be careful for EDEV. The third variant (EPSDE) performs mutation and crossover on 6 different individuals. Therefore, make sure that the second and third sub-populations have more than 6 individuals for optimal performance, or simply ensure that int(npop * lambda_) > 6.

  • Increasing lambda_ value will make the size of the three sub-populations comparable. In the original paper, one population is bigger than the others, so for lambda_ = 0.1 and npop=100, the three sub-populations have sizes 80, 10, and 10.

  • The parallelization of EDEV is bottlenecked by the size of the sub-populations. For example, for sub-populations of size 80, 10, and 10, using ncores = 80 will ensure that the first sub-population is executed in one round, but the other two sub-populations will be evaluated in sequence with 10 cores only.

  • Unlike standalone DE, for EDEV, the values of the hyperparameters F and CR are automatically adapted.

  • The parameter ng in the evolute function helps to determine the frequency/period at which the three sub-populations are swapped between the DE variants based on their prior performance. For example, if ngen = 100 and ng=20, five updates will occur during the full evolution process.

  • Look for an optimal balance between npop and ngen, it is recommended to keep population size optimal to allow for more generations, but also sufficient to keep the three sub-populations active.

  • As EDEV is a bit complex, the total number of cost evaluations for EDEV can be accessed via the returned dictionary key: edev_hist['F-Evals'] in the example above.