How it works
The program has three parts that are kept separate: a genotype (a short list of integers), a procedure that develops a genotype into a picture, and a procedure that copies a genotype with a small random change. Selection is not in the program. You supply it.
1. The genotype
A basic biomorph has nine genes. Genes 1 to 8 are integers from −9 to 9. Gene 9 is an integer from 1 to 8. The genes do not describe the picture point by point. They are parameters of a drawing rule.
2. Development
Development is a recursive tree-drawing procedure. There are eight directions, numbered 0 to 7. Each direction has a horizontal step dx and a vertical step dy, and genes 1 to 8 fill in those steps. The table is built so that directions on the left mirror directions on the right, which is why basic biomorphs are bilaterally symmetrical.
| Direction | dx | dy |
|---|---|---|
| 0 | −g2 | g6 |
| 1 | −g1 | g5 |
| 2 (trunk) | 0 | g4 |
| 3 | g1 | g5 |
| 4 | g2 | g6 |
| 5 | g3 | g7 |
| 6 | 0 | g8 |
| 7 | −g3 | g7 |
The drawing rule is short. It draws one line, then calls itself twice: once turned one direction to the left and once turned one direction to the right, each time with a shorter length.
function tree(x, y, length, dir) {
dir = (dir + 8) % 8;
const xnew = x + length * dx[dir];
const ynew = y + length * dy[dir];
line(x, y, xnew, ynew);
if (length > 0) {
tree(xnew, ynew, length - 1, dir - 1);
tree(xnew, ynew, length - 1, dir + 1);
}
}
tree(0, 0, gene9, 2); // start with the trunk
Gene 9 sets the starting length, which is also the depth of branching. A depth of n produces 2n+1 − 1 lines, so each added unit of gene 9 roughly doubles the complexity of the figure. Press “Watch it grow” under the parent to see the lines appear in the order the recursion draws them.
Every twig follows the same local rule. No gene stands for a wing, a leg, or an antenna. Shapes that look like those things come from the interaction of the eight vectors with the branching depth. A change of one unit in one gene alters every branch that uses that direction, at every level of the tree.
3. Reproduction
Reproduction copies the parent genotype and applies one mutation: one gene, picked at random, moves up or down by one. This is done twelve times to fill the grid, and duplicate offspring are avoided where possible. The caption under each offspring names its mutation.
4. Selection
The program has no fitness function. You choose which offspring reproduces, so this is artificial selection, as in plant or animal breeding. Because each generation starts from the previous choice, small changes accumulate. After 20 to 40 generations the figure is usually far from the starting tree, even though no single step was large. The lineage strip under the grid records the ancestors, and clicking one returns to it.
Crossover and several parents
Turn on “Select several parents” to mark any number of offspring, then press the breed button. With two or more parents, each offspring is made in two steps. First, two different parents are drawn at random and their genomes are recombined. Then one mutation is applied, as before. The caption gives the pair and the mutation, for example “2 × 5, gene 4 +1”, using the numbers shown under the parent thumbnails. If you mark only one offspring, reproduction is asexual.
Two kinds of crossover are available. Uniform crossover takes each gene from one parent or the other with equal probability. One-point crossover picks a random cut in the gene list (genes 1 to 9, segments, spacing, left-right symmetry, spokes, then the ten gradients) and takes everything before the cut from one parent and everything after it from the other. A gene that has the same value in both parents is unchanged by either method, so crossover only has an effect where the selected parents differ.
Crossover can combine changes that arose in separate offspring, which mutation alone would have to find again one step at a time. The result is not always a blend. Every gene acts on the whole figure through the recursion, so a recombinant can look unlike both of its parents. Click a parent thumbnail to show that parent in the large view, the genome table, and the direction diagram.
Changing the embryology
The nine basic genes define a fixed space of possible forms. Selection can move around inside that space but cannot leave it. The three extra gene groups change the developmental procedure itself, and with it the set of forms that can be reached. They are switched off at the start so you can compare.
- Symmetry. One gene turns left-right symmetry on or off. With it off, the trunk of each segment sends out only one of its two main branches. A second gene, labeled Spokes, adds a copy of the body rotated by 180 degrees, or three copies rotated by 90, 180, and 270 degrees.
- Segmentation. One gene sets how many times the basic body is repeated along the vertical axis. Another sets the spacing between repeats. In asymmetrical bodies, successive segments branch on alternate sides.
- Gradients. Each basic gene, and the spacing gene, can carry a gradient of −1, 0, or +1. The gene’s effective value changes by that amount with each segment from front to rear, so segments can taper or swell. Gradients have no visible effect until there are at least two segments.
A suggested experiment: breed for about 20 generations with only the basic genes, and note what kinds of shape never turn up. Then allow segmentation and continue from the same parent. Forms that were unreachable are now a few mutations away. This is the point of the paper’s title. Some embryologies give selection more to work with than others, and a change to the embryology can matter more for later evolution than any single adaptation within it. The limits remain, too: this program can produce four-way radial symmetry but never five-way, however long you select.
Where this version departs from the 1988 program
- Figures are scaled to fit their cell, with an upper limit on the scale so that small bodies still look small.
- Twelve offspring per generation, each with one mutation of size one. The original also had genes for mutation size and mutation rate, which are omitted here.
- The paper does not give the code for asymmetry, spokes, or gradients. The rules used here follow its figures and descriptions: one main branch dropped for asymmetry, rotation about the base of the trunk for spokes, and a per-segment increment for gradients.
- The 1988 program reproduces asexually from one parent. Selecting several parents and crossover are additions in this version.
- The genome table lets you edit any gene directly. Direct edits do not count as generations.
Source: Dawkins, R. (1988). The Evolution of Evolvability. In C. Langton (ed.), Artificial Life, SFI Studies in the Sciences of Complexity, Addison-Wesley, pp. 201 to 220.