Lamarckism and Baldwinism
Up to now, we (mostly) used algorithms inspired by Darwinian evolution. However, there are more evolutionary theories. In this lesson, we will discuss Lamarckian and Baldwinian evolution and try to use them in the framework of evolutionary algorithms.
Lamarckism
Lamarckism is in many aspects similar to Darwinian evolution. It states that individuals inherit their characteristics from their parents and that useful characteristics are developed during the life of the individual. However, it also states that the characteristics are inherited in the form they have at the time the offspring is conceived. According to Lamarck, a blacksmith has developed strong muscles in his arms due to his work, and therefore his sons will also have strong arms. Similarly, giraffes stretch their necks to get to leaves on trees and therefore their offspring have even longer necks. It is interesting to imagine a person having two children – one at a time when they are overweight, and another after they start doing sports. According to Lamarck, the first child should thus also be overweight, while the second should be athletic.
In evolutionary algorithms, we can use the part of the theory which states the improved characteristics are inherited. We let the parents improve during their “life”. This can be done as a clever mutation that improves the individual, whose offspring then inherit the improved genes.
Baldwinism
Baldwin states that evolution does not select individuals based on their performance, but it favors individuals who can quickly learn good behaviors. He states that when the environment changes, the individuals who can quickly adapt are selected by the natural selection, and thanks to the selection, the next generation can adapt even faster. Thus, after a few generations, the adapted behavior may seem as instinctive. Imagine, for example, that there is a new predator in the environment. The individuals who can quickly learn a behavior which makes it hard for the predator to catch them have an advantage and multiply in the population. Their offspring will also be able to learn the required behavior quickly. During the next generations, thanks to (Darwinian) natural selection, the individuals are able to learn the behavior so quickly it looks instinctive.
For evolutionary algorithms, we again take what we like from the theory. Instead of evaluating the quality of the individual, we first let it learn for a while and then select it based on what it was able to learn. We can do this by running a local search during the fitness assignment and assigning the fitness based on the improved individual. The genome of the individual does not change in this case.
Lamarck and Baldwin for continuous optimization
There is a natural way to use Baldwinian and Lamarckian ideas in evolutionary algorithms. We can use a gradient-based method as the learning during the “life” of the individual (i.e. during the mutation in Lamarckian evolution and during the fitness assignment in the Baldwinian evolution). Our fitness function can numerically compute its own gradient at any of its points (the numerical_derivative function in co_functions.py). We can multiply the gradient by a suitable step size and subtract it (we are minimizing) from the individual vector. It is better to make a number of shorter steps instead of one longer step.
We can of course use any other local search method instead of the gradient-based one. For example, simulated annealing or even another evolutionary algorithm.
Be careful – the library does not count the number of fitness evaluations directly; it computes it from the population size and the number of generations (when the graphs are created). Therefore, it does not in any way count the evaluations you need in the local search. The numerical computation of the gradient, for example, needs at least as many evaluations as is the dimension of the problem. Pay attention to this while comparing the algorithm to the one from last lesson.