Differential Evolution Optimization Example in Python

    Differential Evolution (DE) is a population-based metaheuristic search algorithm to find the global minimum of a multivariate function. DE is a kind of evolutionary computing algorithm that starts with an initial set of candidate solution and updates it iteratively. 

    SciPy provides differential_evolution() function to implement differential evolution method in Python. In this tutorial, we'll briefly learn how to implement and solve optimization problem with differential evolution method by using this differential_evolution() function.

    The tutorial covers:

  1. Understanding the problem
  2. Differential Evolution implementation
  3. Source code listing

 We'll start by loading the required libraries.


import numpy as np
from scipy.optimize import differential_evolution
import matplotlib.pyplot as plt
from matplotlib import cm
 
 
Understanding the problem
 
   We'll start creating the objective function to optimize and visualize it in a 3D plot.  In below code, we'll define ranges and function in a mesh grid then visualize it in a plot.
 
 
# define ranges
x_range = np.arange(-4, 4, 0.1)
y_range = np.arange(-4, 4, 0.1)

# create meshgrid
x, y = np.meshgrid(x_range, y_range)

# define the function 
z = np.sqrt(np.sqrt(x**2+y**2))

# Plot the surface.
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
surf = ax.plot_surface(x, y, z, cmap=cm.jet,
                       linewidth=0, antialiased=False)

fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
  
 
Our task is to search a global minimum of the above function in given range. 

 
Differential Evolution implementation
 
    We'll use differential_evolution() function to find the minimum of a given function. The function requires search bounds and callable objective function. We'll define function without changing the formula above. 
 
 
# define function
def func(p):
    x, y = p
    r = np.sqrt(x**2+y**2)
    return np.sqrt(r)
 

We'll set variable bounds that can be specified by defining the max and min values.

 
bounds = [[-4, 4], [-4, 4]]
 

Then execute the differential evolution with SciPy differential_evolution() function.


# execute differential evolution search
result = differential_evolution(func, bounds)
 
print(result)
 
 fun: 0.0
message: 'Optimization terminated successfully.'
nfev: 3033
nit: 98
success: True
x: array([0., 0.])
 
 

The result shows that minimum of the function is located in a point of (0, 0). 

   Here, result contains the following attributes:

    fun - value of objective function 
    nfev -  the number of evaluation, 
    nit - the number of iterations, 
    success - the existence of optimizer, 
    x -  the solution of the optimization

To print evaluated function at every iteration, we'll set true to the 'disp' parameter.


result = differential_evolution(func, bounds, disp=True)
 
differential_evolution step 1: f(x)= 0.681272
differential_evolution step 2: f(x)= 0.457103
differential_evolution step 3: f(x)= 0.457103
differential_evolution step 4: f(x)= 0.301956
differential_evolution step 5: f(x)= 0.301956
...
differential_evolution step 83: f(x)= 5.01213e-08
differential_evolution step 84: f(x)= 3.54411e-08
differential_evolution step 85: f(x)= 2.98023e-08
differential_evolution step 86: f(x)= 0
differential_evolution step 87: f(x)= 0
differential_evolution step 88: f(x)= 0
differential_evolution step 89: f(x)= 0
differential_evolution step 90: f(x)= 0
differential_evolution step 91: f(x)= 0
differential_evolution step 92: f(x)= 0
differential_evolution step 93: f(x)= 0 
  
 
    In this tutorial, we've briefly learned how to use differential evolution method with differential_evolution() function in Python. The full source code is listed below. 
 
 
Source code listing

 
import numpy as np
from scipy.optimize import differential_evolution
import matplotlib.pyplot as plt
from matplotlib import cm

# define ranges
x_range = np.arange(-4, 4, 0.1)
y_range = np.arange(-4, 4, 0.1)

# create meshgrid
x, y = np.meshgrid(x_range, y_range)

# define the function
z = np.sqrt(np.sqrt(x**2+y**2))

# plot the surface
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
surf = ax.plot_surface(x, y, z, cmap=cm.jet,
                       linewidth=0, antialiased=False)

fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()

# set bounds
bounds = [[-4, 4], [-4, 4]]

# define function
def func(p):
    x,y = p
    r = np.sqrt(x**2+y**2)
    return np.sqrt(r)

# execute differentian evolution search 
result = differential_evolution(func, bounds)
 
print(result) 

result = differential_evolution(func, bounds, disp=True)
    
 
 
References:

No comments:

Post a Comment