genetic_algorithm_driver.py

genetic_algorithm_driver.py#

Driver for a simple genetic algorithm.

This is the Simple Genetic Algorithm implementation based on 2009 AAE550: MDO Lecture notes of Prof. William A. Crossley.

This basic GA algorithm is compartmentalized into the GeneticAlgorithm class so that it can be used in more complicated driver.

The following reference is only for the automatic population sizing: Williams E.A., Crossley W.A. (1998) Empirically-Derived Population Size and Mutation Rate Guidelines for a Genetic Algorithm with Uniform Crossover. In: Chawdhry P.K., Roy R., Pant R.K. (eds) Soft Computing in Engineering Design and Manufacturing. Springer, London.

The following reference is only for the penalty function: Smith, A. E., Coit, D. W. (1995) Penalty functions. In: Handbook of Evolutionary Computation, 97(1).

The following reference is only for weighted sum multi-objective optimization: Sobieszczanski-Sobieski, J., Morris, A. J., van Tooren, M. J. L. (2015) Multidisciplinary Design Optimization Supported by Knowledge Based Engineering. John Wiley & Sons, Ltd.

class openmdao.drivers.genetic_algorithm_driver.GeneticAlgorithm(objfun, comm=None, model_mpi=None)[source]

Bases: object

Simple Genetic Algorithm.

This is the Simple Genetic Algorithm implementation based on 2009 AAE550: MDO Lecture notes of Prof. William A. Crossley. It can be used standalone or as part of the OpenMDAO Driver.

Parameters:
objfunfunction

Objective callback function.

commMPI communicator or None

The MPI communicator that will be used objective evaluation for each generation.

model_mpiNone or tuple

If the model in objfun is also parallel, then this will contain a tuple with the the total number of population points to evaluate concurrently, and the color of the point to evaluate on this rank.

Attributes:
commMPI communicator or None

The MPI communicator that will be used objective evaluation for each generation.

elitebool

Elitism flag.

gray_codebool

Gray code binary representation flag.

cross_bitsbool

Crossover swaps bits instead of tails flag. Swapping bits is similar to mutation, so when used Pc should be increased and Pm reduced.

lchromint

Chromosome length.

model_mpiNone or tuple

If the model in objfun is also parallel, then this will contain a tuple with the the total number of population points to evaluate concurrently, and the color of the point to evaluate on this rank.

nobjint

Number of objectives.

npopint

Population size.

objfunfunction

Objective function callback.

_lhsfunction

A lazily imported instance of the pyDOE3 latin hypercube sampling function.

Methods

crossover(old_gen, Pc)

Apply crossover to the current generation.

decode(gen, vlb, vub, bits)

Decode from binary array to real value array.

encode(x, vlb, vub, bits)

Encode array of real values to array of binary arrays.

eval_pareto(x, obj, x_nd, obj_nd)

Produce a set of non dominated designs.

execute_ga(x0, vlb, vub, vob, bits, ...[, ...])

Perform the genetic algorithm.

from_gray(g)

Convert a Gray coded binary array to normal binary coding.

mutate(current_gen, Pm)

Apply mutations to the current generation.

shuffle(old_gen)

Shuffle (reorder) the points in the population.

to_gray(g)

Convert a binary array representing a single population member to Gray code.

tournament(old_gen, fitness)

Apply tournament selection and keep the best points.

tournament_multi_obj(old_gen, obj_val)

Apply tournament selection and keep the best points.

__init__(objfun, comm=None, model_mpi=None)[source]

Initialize genetic algorithm object.

crossover(old_gen, Pc)[source]

Apply crossover to the current generation.

Crossover swaps tails (k-point crossover) of two adjacent genes.

Parameters:
old_genndarray

Points in current generation.

Pcfloat

Probability of crossover.

Returns:
ndarray

Current generation with crossovers applied.

decode(gen, vlb, vub, bits)[source]

Decode from binary array to real value array.

Parameters:
genndarray

Population of points, encoded.

vlbndarray

Lower bound array.

vubndarray

Upper bound array.

bitsndarray(dtype=int)

Number of bits for decoding.

Returns:
ndarray

Decoded design variable values.

encode(x, vlb, vub, bits)[source]

Encode array of real values to array of binary arrays.

The array of arrays represents a single population member.

Parameters:
xndarray

Design variable values.

vlbndarray

Lower bound array.

vubndarray

Upper bound array.

bitsndarray(dtype=int)

Number of bits for decoding.

Returns:
ndarray

Single population member, encoded.

eval_pareto(x, obj, x_nd, obj_nd)[source]

Produce a set of non dominated designs.

Parameters:
xndarray

Design points from new generation.

objndarray

Objective values from new generation.

x_ndndarray

Non dominated design points from previous pareto evaluation.

obj_ndndarray

Non dominated objective values from previous pareto evaluation.

Returns:
ndarray

Nondominated design points.

ndarray

Objective at nondominated design points.

execute_ga(x0, vlb, vub, vob, bits, pop_size, max_gen, random_state, Pm=None, Pc=0.5)[source]

Perform the genetic algorithm.

Parameters:
x0ndarray

Initial design values.

vlbndarray

Lower bounds array.

vubndarray

Upper bounds array. This includes over-allocation so that every point falls on an integer value.

vobndarray

Outer bounds array. This is purely for bounds check.

bitsndarray

Number of bits to encode the design space for each element of the design vector.

pop_sizeint

Number of points in the population.

max_genint

Number of generations to run the GA.

random_statenp.random.RandomState, int

Random state (or seed-number) which controls the seed and random draws.

Pmfloat or None

Mutation rate.

Pcfloat

Crossover rate.

Returns:
ndarray

Best design point.

float

Objective value at best design point.

int

Number of successful function evaluations.

static from_gray(g)[source]

Convert a Gray coded binary array to normal binary coding.

The input and output arrays represent a single population member.

Parameters:
gbinary array

Gray coded binary array, e.g. np.array([0, 0, 1, 1]).

Returns:
ndarray

Binary array using normal coding, e.g. np.array([0, 0, 1, 0]).

mutate(current_gen, Pm)[source]

Apply mutations to the current generation.

A mutation flips the state of the gene from 0 to 1 or 1 to 0.

Parameters:
current_genndarray

Points in current generation.

Pmfloat

Probability of mutation.

Returns:
ndarray

Current generation with mutations applied.

shuffle(old_gen)[source]

Shuffle (reorder) the points in the population.

Used in tournament selection.

Parameters:
old_genndarray

Old population.

Returns:
ndarray

New shuffled population.

ndarray(dtype=int)

Index array that maps the shuffle from old to new.

static to_gray(g)[source]

Convert a binary array representing a single population member to Gray code.

Parameters:
gbinary array

Normal binary array, e.g. np.array([0, 0, 1, 0]).

Returns:
ndarray

Binary array using Gray code, e.g. np.array([0, 0, 1, 1]).

tournament(old_gen, fitness)[source]

Apply tournament selection and keep the best points.

Parameters:
old_genndarray

Points in current generation.

fitnessndarray

Objective value of each point.

Returns:
ndarray

New generation with best points.

tournament_multi_obj(old_gen, obj_val)[source]

Apply tournament selection and keep the best points.

This method is used if there are multiple objectives and the non-dominated set is being kept.

Parameters:
old_genndarray

Points in current generation.

obj_valndarray

Objective value of each point.

Returns:
ndarray

New generation with best points.

ndarray

Corresponding objective values.

class openmdao.drivers.genetic_algorithm_driver.SimpleGADriver(**kwargs)[source]

Bases: Driver

Driver for a simple genetic algorithm.

Parameters:
**kwargsdict of keyword arguments

Keyword arguments that will be mapped into the Driver options.

Attributes:
_problem_commMPI.Comm or None

The MPI communicator for the Problem.

_concurrent_pop_sizeint

Number of points to run concurrently when model is a parallel one.

_concurrent_colorint

Color of current rank when running a parallel model.

_desvar_idxdict

Keeps track of the indices for each desvar, since GeneticAlgorithm sees an array of design variables.

_ga<GeneticAlgorithm>

Main genetic algorithm lies here.

_randomstatenp.random.RandomState, int

Random state (or seed-number) which controls the seed and random draws.

_nfitint

Number of successful function evaluations.

Methods

add_recorder(recorder)

Add a recorder to the driver.

check_relevance()

Check if there are constraints that don't depend on any design vars.

cleanup()

Clean up resources prior to exit.

compute_lagrange_multipliers([...])

Get the approximated Lagrange multipliers of one or more constraints.

declare_coloring([num_full_jacs, tol, ...])

Set options for total deriv coloring.

get_coloring_fname([mode])

Get the filename for the coloring file.

get_constraint_values([ctype, lintype, ...])

Return constraint values.

get_design_var_values([get_remote, ...])

Return the design variable values.

get_driver_derivative_calls()

Return number of derivative evaluations made during a driver run.

get_driver_objective_calls()

Return number of objective evaluations made during a driver run.

get_exit_status()

Return exit status of driver run.

get_objective_values([driver_scaling])

Return objective values.

get_reports_dir()

Get the path to the directory where the report files should go.

objective_callback(x, icase)

Evaluate problem objective at the requested point.

record_derivatives()

Record the current total jacobian.

record_iteration()

Record an iteration of the current Driver.

run()

Execute the genetic algorithm.

scaling_report([outfile, title, ...])

Generate a self-contained html file containing a detailed connection viewer.

set_design_var(name, value[, set_remote])

Set the value of a design variable.

use_fixed_coloring([coloring])

Tell the driver to use a precomputed coloring.

__init__(**kwargs)[source]

Initialize the SimpleGADriver driver.

objective_callback(x, icase)[source]

Evaluate problem objective at the requested point.

In case of multi-objective optimization, a simple weighted sum method is used:

\[f = (\sum_{k=1}^{N_f} w_k \cdot f_k)^a\]

where \(N_f\) is the number of objectives and \(a>0\) is an exponential weight. Choosing \(a=1\) is equivalent to the conventional weighted sum method.

The weights given in the options are normalized, so:

\[\sum_{k=1}^{N_f} w_k = 1\]

If one of the objectives \(f_k\) is not a scalar, its elements will have the same weights, and it will be normed with length of the vector.

Takes into account constraints with a penalty function.

All constraints are converted to the form of \(g_i(x) \leq 0\) for inequality constraints and \(h_i(x) = 0\) for equality constraints. The constraint vector for inequality constraints is the following:

\[ \begin{align}\begin{aligned}g = [g_1, g_2 \dots g_N], g_i \in R^{N_{g_i}}\\h = [h_1, h_2 \dots h_N], h_i \in R^{N_{h_i}}\end{aligned}\end{align} \]

The number of all constraints:

\[N_g = \sum_{i=1}^N N_{g_i}, N_h = \sum_{i=1}^N N_{h_i}\]

The fitness function is constructed with the penalty parameter \(p\) and the exponent \(\kappa\):

\[\Phi(x) = f(x) + p \cdot \sum_{k=1}^{N^g}(\delta_k \cdot g_k)^{\kappa} + p \cdot \sum_{k=1}^{N^h}|h_k|^{\kappa}\]

where \(\delta_k = 0\) if \(g_k\) is satisfied, 1 otherwise

Note

The values of \(\kappa\) and \(p\) can be defined as driver options.

Parameters:
xndarray

Value of design variables.

icaseint

Case number, used for identification when run in parallel.

Returns:
float

Objective value.

bool

Success flag, True if successful.

int

Case number, used for identification when run in parallel.

run()[source]

Execute the genetic algorithm.

Returns:
bool

Failure flag; True if failed to converge, False is successful.