Differential Evolution › Formula
Machine Learning from ScratchAll chapters Differential Evolution › FormulaSection view · Sections in this chapter4 / 10 ↓
Reading tools Definitions, links & notes
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
We need a representation and initialization, a mutation rule, a crossover mask, and a selection rule. The standard DE/rand/1/bin construction below follows Storn and Price (1997). We will distinguish the rule itself from the particular choices made in our implementation.
Continuous populations and differential mutation
We start with the object we are manipulating. The population at generation is an indexed collection of real vectors for , where is the number of decision variables and is the scalar objective we want to minimize.
Before we can mutate anything we need somewhere to start, so the first ingredient is initialization. Drawing each coordinate uniformly inside the box constraints gives
where:
- : the -th coordinate of population member at generation
- : lower bound of the box constraint for coordinate
- : upper bound of the box constraint for coordinate
- : an independent draw from the uniform distribution on
Uniform initialization uses only the stated box bounds; it does not ensure that every region is sampled. The minimum population size for this variant is , because each target needs three mutually distinct donor indices that also exclude the target.
With a population in hand, the central question is how to generate a new candidate. Gradient descent would answer with ; simulated annealing would answer with a perturbation whose size we had to choose. DE answers differently: it takes a displacement that the population already contains. For each target , pick three indices uniformly at random, mutually distinct and all different from , and form the mutant
where:
- : the mutant vector for target at generation
- : the base vector, a randomly selected population member
- : two other distinct population members whose difference forms the mutation direction
- : the mutation factor scaling the difference vector
This single line contains the whole idea, so it is worth reading slowly.
The quantity in parentheses is a difference of two population members. In coordinate it equals , so its sign tells us which of the two members is larger in that coordinate, and its magnitude is how far apart they are. The full vector is therefore a displacement from to , a direction together with a length. Multiplying by rescales that displacement. Adding the scaled displacement to a third member places the mutant at the point we would reach by standing at and stepping times the way from toward .
The mutation factor multiplies the donor difference. Our implementation accepts and uses in the main comparison. At the mutant is just the base donor. Increasing lengthens a fixed nonzero difference; it does not guarantee a better proposal. The parameter sweep later tests several values under a fixed budget.
We can quantify self-scaling under an idealized model. Suppose two donor vectors are independent draws from a distribution with mean and covariance . This assumption is a model for the calculation, not a claim that evolved population members remain independent. The expected difference is zero:
where:
- : independent draws from the population distribution
- : the mean of that distribution
Thus the idealized difference has zero mean. This describes a displacement around its base donor, not an unbiased estimate of a direction that reduces the objective. Its covariance is:
where:
- : independent draws from the population distribution
- : the covariance matrix of that distribution
Under this independent-draw model, coordinate of the scaled difference has standard deviation , where is the distribution standard deviation. This is not exactly twice the empirical covariance of a fixed finite donor pool sampled without replacement. For a pool of eligible vectors with covariance computed using divisor , the difference covariance is times that covariance. The model explains why population spread influences step size without promising contraction or improvement.
In matrix notation the same generation can be written compactly. Let be the matrix whose -th row is , and let be index vectors of length that encode, row by row, which members were drawn as donors:
Here selects rows. For each target row, its three selected donor indices must be distinct and exclude that target. With scalar , the expression is an ordinary scalar-matrix product. It describes a whole generation compactly; our teaching implementation uses a loop over targets while freezing the donor population. SciPy also supports a mutation interval that samples one per generation, as discussed below.
The geometry can be checked on explicit donor coordinates. The dashed arrow shows the unscaled difference; the solid arrow attaches its scaled copy to the base donor. A later crossover chooses coordinates from the mutant and target, so a trial can be a corner of their axis-aligned rectangle rather than a point on the line segment joining them.
PythonIn [3]Expand
geometry_donors = np.array([[-1.5, -0.5], [1.5, 1.5], [-0.5, 1.0]])
geometry_F = 0.7
geometry_difference = geometry_donors[1] - geometry_donors[2]
geometry_mutant = geometry_donors[0] + geometry_F * geometry_differenceVisualizationOut [4]Expand

Donor sampling without replacement and exclusion of the target are defining conditions of this variant. DE/rand/1/bin names a random base donor, one difference vector, and binomial crossover. Other strategies change these ingredients; their performance must be checked on the intended problem rather than inferred from the name.
Crossover and greedy selection
A mutant contains donor-derived values in every coordinate. Binomial crossover chooses between those values and the target values, coordinate by coordinate. It does not inspect which coordinate choices improve the objective; only the completed trial is evaluated:
where:
- : the -th coordinate of the trial vector for target
- : the -th coordinate of the mutant vector
- : the -th coordinate of the target vector
- : an independent draw from the uniform distribution on
- : the crossover rate in
- : a uniformly drawn index from that is always inherited from the mutant
For a non-forced coordinate, is its probability of being selected from the mutant. At every coordinate is selected from the mutant; at exactly the forced coordinate is selected. The forced index is drawn independently and uniformly for each target.
The forced coordinate guarantees donor inheritance, not numerical novelty. If target and mutant coordinates coincide, or repair maps them to the same values, the trial can equal its target. Duplicate trials still consume evaluations. The random-threshold and forced-index events can overlap: their union probability for one coordinate is . Equivalently, the forced coordinate contributes one selected entry, and the other coordinates each contribute in expectation:
Here is one when the mask selects the mutant coordinate and zero otherwise. For , the expected selected counts are at and at . These count selected entries, not accidental numerical equalities. For , a smaller selects fewer mutant coordinates in expectation. At , the forced coordinate keeps the selected count at one for every . Coordinate dependence alone does not supply a universal best setting.
In matrix form, let be the zero-one mask with when coordinate of row is inherited from the mutant, including the forced column. Then
where:
- : the matrix of trial vectors
- : the binary mask selecting mutant coordinates
- : the matrix of mutant vectors
- : the matrix of target vectors
- : elementwise (Hadamard) product
- : the all-ones matrix, so selects the target coordinates
Writing it this way makes clear that crossover is a selection of entries, not an arithmetic blend: no new coordinate values are created, only copied.
Selection is then greedy and one-to-one. Each trial competes only with its own target:
where:
- : the target vector for slot at the next generation
- : the trial vector for slot
- : the current target vector
- : the objective function to minimize
This rule compares a trial only with its own target. Our <= convention accepts ties; a strictly worse trial is discarded. For a fixed deterministic objective, every retained slot value is non-increasing, so the population minimum is non-increasing too. This property does not ensure diversity or a global optimum.
In a deferred generation, every donor and target comes from generation , and the accepted replacements are installed together. Our code freezes that population explicitly. An immediate variant allows later proposals in a sweep to use earlier replacements. With fixed update order and random-number stream either can be reproducible, but the trajectories can differ; there is no general faster-convergence guarantee.
Bounds, constraints, and stopping criteria
Initialization respects the box, but a mutant can leave it. This can happen even for , depending on the base and donor difference. We will clip mutants before crossover; other choices change the proposal distribution:
- Clipping maps a coordinate to . It enforces its interval but can concentrate proposals on the boundaries. It does not enforce coupled non-box constraints.
- Reflection sends a lower-bound violation to or an upper-bound violation to . Large overshoots need repeated reflection or an equivalent folding rule.
- Reinitialization samples a violating coordinate again inside its interval, discarding that coordinate's differential step. These are different search choices, not interchangeable guarantees.
For non-box constraints, a penalty, a repair procedure, or a feasible reparametrization needs its own validation. A penalty alone does not certify feasibility. Count every objective evaluation performed while repairing or comparing candidates, and validate every reported solution against the original constraints.
Our comparison stops at a fixed candidate-evaluation budget. Population spread, changes in the incumbent, or a generation limit can also be stopping rules without knowing the optimum. A tolerance on objective spread measures agreement among current candidates; it is not a test of distance to the global optimum. Every stopping rule and its evaluation cost should be reported.
Mathematical Properties
For a fixed deterministic objective, let . Each selected slot either retains its old value or takes a value no larger, so and therefore . An archived minimum over all evaluated candidates is also non-increasing. Neither statement implies strict progress; with noisy evaluations it applies to the stored observations, not necessarily to true expected costs.
The mutation operator is translation and rotation equivariant: if we rotate every population member by an orthogonal matrix , the mutant rotates by as well, because
Binomial crossover is not rotation equivariant because it chooses entries in a fixed coordinate basis. Diagonal affine changes of units are different: for with diagonal having positive entries, mutation gives . The same crossover mask commutes with this coordinate-wise transformation. With matching bounds, initialization, and arithmetic, this preserves the transformed search; it does not imply rotation invariance or immunity to numerical tolerances.
These update rules provide no finite-budget global-optimum guarantee. A small spread can explain short mutation steps, but the population may have contracted in the wrong basin. We do not assume a geometric convergence rate or identify this mechanism with an annealing theorem.
Comments
Add to the conversation
A question, a correction, or an example from your own work.
No comments yet. Be the first to share your thoughts!