<jupyter_start><jupyter_text>DifferentialEvolutionDriver```{note}DifferentialEvolutionDriver is based on SimpleGADriver and supports most of the same options and capabilities.```This [differential evolution](https://en.wikipedia.org/wiki/Differential_evolution) variant of a genetic algorithm optimizer supports only continuous variables. The DifferentialEvolutionDriver supports both constrained and unconstrained optimization.The DifferentialEvolutionDriver has advantages and disadvantages when compared to the SimpleGADriver: - Pros    - DifferentialEvolutionDriver is typically about 3 times faster than SimpleGADriver    - DifferentialEvolutionDriver is usually more accurate than SimpleGADriver because it does not limit the number of bits available to represent inputs    - DifferentialEvolutionDriver does not require the user to manually specify a number of representation bits - Cons    - DifferentialEvolutionDriver only supports continuous input variables; SimpleGADriver also supports discrete    - DifferentialEvolutionDriver does not support SimpleGADriver’s “compute_pareto” option for multi-objective optimizationGenetic algorithms do not use gradient information to find optimal solutions. This makes them ideal for problems that do not have gradients or problems with many local minima where gradient information is not helpful in finding the global minimum. A well known example of this is finding the global minimum of of the Rastrigin function: ![2D Rastrigin Example](rastrigin2d.png)The example below shows an OpenMDAO solution of a higher order [Rastrigin function](https://en.wikipedia.org/wiki/Rastrigin_function).<jupyter_code>import openmdao.api as om
import numpy as np

ORDER = 6  # dimension of problem
span = 5   # upper and lower limits

class RastriginComp(om.ExplicitComponent):
    def setup(self):
        self.add_input('x', np.zeros(ORDER))
        self.add_output('y', 0.0)

    def compute(self, inputs, outputs):
        x = inputs['x']

        # nth dimensional Rastrigin function, array input and scalar output
        # global minimum at f(0,0,0...) = 0
        n = len(x)
        s = 10 * n
        for i in range(n):
            if np.abs(x[i]) < 1e-200:  # avoid underflow runtime warnings from squaring tiny numbers
                x[i] = 0.0
            s += x[i] * x[i] - 10 * np.cos(2 * np.pi * x[i])

        outputs['y'] = s

prob = om.Problem()

prob.model.add_subsystem('rastrigin', RastriginComp(), promotes_inputs=['x'])
prob.model.add_design_var('x',
                          lower=-span * np.ones(ORDER),
                          upper=span * np.ones(ORDER))
prob.model.add_objective('rastrigin.y')

prob.driver = om.DifferentialEvolutionDriver()
prob.driver.options['max_gen'] = 400
prob.driver.options['Pc'] = 0.5
prob.driver.options['F'] = 0.5

prob.setup()
prob.run_driver()

print(prob['rastrigin.y'])
print(prob['x'])
from openmdao.utils.assert_utils import assert_near_equal
assert_near_equal(prob['rastrigin.y'], 0.0, 1e-6)
assert_near_equal(prob['x'], np.zeros(ORDER), 1e-6)<jupyter_output><empty_output><jupyter_text>DifferentialEvolutionDriver Options<jupyter_code>om.show_options_table("openmdao.drivers.differential_evolution_driver.DifferentialEvolutionDriver")<jupyter_output><empty_output><jupyter_text>DifferentialEvolutionDriver ConstructorThe call signature for the DifferentialEvolutionDriver constructor is:```{eval-rst}    .. automethod:: openmdao.drivers.differential_evolution_driver.DifferentialEvolutionDriver.__init__       :noindex:```  Using DifferentialEvolutionDriverYou can change the number of generations to run the genetic algorithm by setting the “max_gen” option.<jupyter_code>import openmdao.api as om
from openmdao.test_suite.components.branin import Branin

prob = om.Problem()
model = prob.model

model.add_subsystem('comp', Branin(), promotes_inputs=[('x0', 'xI'), ('x1', 'xC')])

model.add_design_var('xI', lower=-5.0, upper=10.0)
model.add_design_var('xC', lower=0.0, upper=15.0)
model.add_objective('comp.f')

prob.driver = om.DifferentialEvolutionDriver()
prob.driver.options['max_gen'] = 5

prob.setup()
prob.run_driver()<jupyter_output><empty_output><jupyter_text>You can change the population size by setting the “pop_size” option. The default value for pop_size is 0, which means that the driver automatically computes a population size that is 20 times the total number of input variables.<jupyter_code>import openmdao.api as om
from openmdao.test_suite.components.branin import Branin

prob = om.Problem()
model = prob.model

model.add_subsystem('comp', Branin(), promotes_inputs=[('x0', 'xI'), ('x1', 'xC')])

model.add_design_var('xI', lower=-5.0, upper=10.0)
model.add_design_var('xC', lower=0.0, upper=15.0)
model.add_objective('comp.f')

prob.driver = om.DifferentialEvolutionDriver()
prob.driver.options['pop_size'] = 10

prob.setup()
prob.run_driver()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10254841997961264, 'fraction_numerical': 0.013251783893985729, 'mean_word_length': 5.049321824907522, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '55707', 'license': 'Apache-2.0', 'n_tokens_mistral': 1530, 'n_tokens_neox': 1445, 'n_words': 415, 'path': 'openmdao/docs/openmdao_book/features/building_blocks/drivers/differential_evolution.ipynb', 'repo_name': 'sebasgo/OpenMDAO', 'size': '4905'}