Skip to content

shakibv/PythonDE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 

Repository files navigation

PythonDE

Differential evolution optimization (DE)

Table of Contents

To Use

To clone and run this repository you'll need Git installed on your computer. From your command line:

# Clone this repository
git clone https://github.com/shakibv/PythonDE
# Go into the repository
cd PythonDE
# Install the package
python setup.py install --user

Example Usages: Normal Mode

A simple example showing how PythonDE can be utilized to minimze the Goldstein-Price function. The true global minimum is at (x,y) = (0, -1) where f(x,y) = 3:

from pythonde import DEvolution

def GoldsteinPrice(x):
    return (1+(x[0]+x[1]+1)**2*(19-14*x[0]+3*x[0]**2-14*x[1]+6*x[0]*x[1]+3*x[1]**2))* \
           (30+(2*x[0]-3*x[1])**2*(18-32*x[0]+12*x[0]**2+48*x[1]-36*x[0]*x[1]+27*x[1]**2))

maxGen, nPopulation, bounds = 100, 50, [[-2,2],[-2,2]]
DE = DEvolution(GoldsteinPrice, bounds, nPopulation)
MinPoint, MinValue = DE.Optimize(maxGen)

print(MinPoint, MinValue)
#[  1.24805183e-09  -1.00000000e+00] 3.0

Now let's walk through each section of the code. We start off with importing the class from the package:

from pythonde import DEvolution

Then we define the objective function to be minimized. In this case the Goldstein-Price function:

def GoldsteinPrice(x):
    return (1+(x[0]+x[1]+1)**2*(19-14*x[0]+3*x[0]**2-14*x[1]+6*x[0]*x[1]+3*x[1]**2))* \
           (30+(2*x[0]-3*x[1])**2*(18-32*x[0]+12*x[0]**2+48*x[1]-36*x[0]*x[1]+27*x[1]**2))

Next we have to specify the limits of the input parameters that the optimizer is allowed to search within (bounds), the size of population (nPopulation) and the maximum number of generations allowed (maxGen). For the sake of clarity, we have defined them prior to calling the optimizer. In this example the bounds on the input parameters are -2 ≤ x,y ≤ 2 and are passed using the bounds = [[-2,2],[-2,2]] variable:

maxGen, nPopulation, bounds = 100, 50, [[-2,2],[-2,2]]

Now we can create a DEvolution instance and run the optimizer for maxGen generations:

DE = DEvolution(GoldsteinPrice, bounds, nPopulation)
MinPoint, MinValue = DE.Optimize(maxGen)

print(MinPoint, MinValue)

Finaly, to access the best-fit solution found by the algorithm we can simply access the two variables MinPoint and MinValue.

Coroutine Mode

This mode is used in the case that the Fitness Function is provided from an external source to the Differential Evolution algorithm. For example, from an experimental setup or an external function. A simple example showing how PythonDE can be used as a coroutine to minimze an external fitness function is provided here. The true global minimum is at (x,y) = (1, 1) where f(x,y) = 0:

from pythonde import DEvolution

def fitness_func(x):
    error = (1 - x[0]) ** 2 + 100 * (x[1] - x[0] ** 2) ** 2
    return error

maxGen, nPopulation, bounds = 100, 50, [[-5,6],[-5,6]]
DE = DEvolution(None, bounds, nPopulation)
coDE = DE();

param = next(coDE)
for i in range(maxGen * nPopulation):
    param = coDE.send(fitness_func(param))
coDE.close()

print(DE.MinimumPoint, DE.MinimumValue)
#[ 1.00000113  1.00000246] 5.57046840346e-12

Now let's walk through each section of the code. To start using PythonDE as a coroutine we start off with importing the class from the package:

from pythonde import DEvolution

Then we define the external fitness function. It takes a parameter set and returns the corresponding fitness value:

def fitness_func(x):
    error = (1 - x[0]) ** 2 + 100 * (x[1] - x[0] ** 2) ** 2
    return error

Next we have to specify the limits of the input parameters that the optimizer is allowed to search within (bounds), the size of population (nPopulation) and the maximum number of generations allowed (maxGen). In this example the bounds on the input parameters are -5 ≤ x,y ≤ 6 and are passed using the bounds = [[-5,6],[-5,6]] variable:

maxGen, nPopulation, bounds = 100, 50, [[-5,6],[-5,6]]

Now we can create a DEvolution instance and run the optimizer as a coroutine for arbitrary number of generations. In this example the fitness function is not directly passed to the algorithm. So, the value None will be placed instead:

DE = DEvolution(None, bounds, nPopulation)
coDE = DE();

param = next(coDE)
for i in range(maxGen * nPopulation):
    param = coDE.send(fitness_func(param))
coDE.close()

print(DE.MinimumPoint, DE.MinimumValue)
#[ 1.00000113  1.00000246] 5.57046840346e-12

Finaly, to access the best-fit solution found by the algorithm we can simply access the two properties DE.MinimumPoint and DE.MinimumValue.

Generator Mode

Choice of Control Variables

[Storn, R., Price, K.]

It is interesting to note that DE’s control variables, nPopulation, F and CR, are not difficult to choose in order to obtain good results. According to our experience a reasonable choice for nPopulation is between 5xDimension and 10xDimension but nPopulation must be at least 4 to ensure that DE will have enough mutually different vectors with which to work. As for F, F = 0.5 is usually a good initial choice. If the population converges prematurely, then F and/or nPopulation should be increased. Values of F smaller than 0.4, like those greater than 1, are only occasionally effective. A good first choice for CR is 0.1, but since a large CR often speeds convergence, to first try CR = 0.9 or CR = 1.0 is appropriate in order to see if a quick solution is possible. For fastest convergence, it is best to pick the initial parameter range such that it covers the region of the suspected global optimum, although this choice doesn’t seem to be mandatory...

References

Storn, R., Price, K., Journal of Global Optimization 11: 341--359, 1997

About

Differential evolution optimization (DE)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages