Differential evolution: DE/rand/1/bin#

de_rand_1_bin_crossover() adds a scaled difference of two random members of the population to a third one, and takes each variable of the offspring from this mutant or from the target. One random variable always comes from the mutant. pymoo (VariantDE), jMetalPy (DifferentialEvolutionCrossover) and DESDEO (DifferentialEvolutionCrossover) provide this operator. pymoo forces a variable to come from the mutant only when no variable was chosen, instead of forcing a random variable in every offspring.

KS test results#

moocore

pymoo

jMetalPy

desdeo

moocore

<0.001

0.275

0.786

pymoo

<0.001

<0.001

<0.001

jMetalPy

0.275

<0.001

0.549

desdeo

0.786

<0.001

0.549

moocore, jMetalPy and DESDEO produce the same distribution of offspring. pymoo differs from all three because of its rule for the forced variable. With 3 variables and \(CR = 0.9\), it keeps the value of the target in 13% to 14% of the variables, against 9% to 11% in the other packages.

Performance over number of parents#

../../_images/crossover_bench-de_rand_1_bin-nparents-time.png

moocore is the fastest for every number of parents. With 10 000 parents, it takes 1.9 ms, while DESDEO, pymoo and jMetalPy take 2.2, 17 and 140 times as long.

Performance over number of variables#

../../_images/crossover_bench-de_rand_1_bin-nvars-time.png

moocore is the fastest for every number of variables. With 1000 variables, pymoo, DESDEO and jMetalPy take 2.6, 6.5 and 550 times as long.