School of Computing. Dublin City University.
Online coding site: Ancient Brain
coders JavaScript worlds
Reproduction could involve:
Parent:
0011010110011101101Child could be identical (clone):
0011010110011101101Or have occasional mutation:
0011010110011111101
0000000000000000000 1111111111111111111Children could be identical:
0000000000000000000 1111111111111111111Or part of one, part of other. A synchronised "crossover":
0000000000000111111 1111111111111000000
And can add some mutation at random also while doing this.
And might do multiple crossover points:
Child = Start of parent A, middle of parent B, end of parent A.
The hope of crossover as heuristic search:
Parents were somewhat fit. (That is why they were picked to reproduce.)
One may be good at one thing. The other at another thing.
Crossover might get child which is good at both things.
(Get best parts from each parent.)
Parents (change of color shows new gene):
0000000000000000 1111111111111111Crossover only at gene boundaries:
0000000000001111 1111111111110000If we do this, we only ever reshuffle combinations of existing genes. We never create a new gene with crossover.
Crossover in the middle of a gene:
0000000001111111 1111111110000000This will create new genes.
However, no mutation at all turns out to be bad. See the following.
Genotype X is slightly fitter and popular. Children are crossover of X and X, i.e. child is identical to X. Other crossovers produce nothing interesting. There is no mutation. X gets more popular. More children identical to X. Whole population becomes X.
Often have:
Probability of mutation starts high and declines.
Probability of crossover starts high and declines.
For many problems, it is not simply a matter of constructing the individuals out of random values of the n parameters or genes, and then testing the fitness. Say the individual will simply not run at all if gene 1 is not > 3.
If you just encode the parameters as numbers, and search for combinations of numbers, it may be that 99 percent of parameter combinations won't even run.
Our initial random population will all have zero fitness, and so will almost any mutation or crossover of a fit individual.
Work on the encoding: Might try to change the genotype encoding to reflect this complexity, so the bitstring in gene 1 was simply interpreted as from 3 upwards, the bitstring in gene 2 was interpreted as 0-7, etc.
May still have search space with many unviable individuals: Consider constraints like: "Unless gene 3 < gene 7 < gene 11, the individual will not run"? This knocks out a huge chunk of the multi-dimensional space.
One solution is a loop when we are constructing new chromosomes:
given parents: do { crossover, constructing child1 and child2 cout << "searching for viable crossover .. \n" } while ( ! ( child1.viable() && child2.viable() ) )where viable() is defined in the application.
We need a similar loop in the initial randomise population function:
repeat n times: do { construct new randomised individual x cout << "searching for viable randomisation .. \n" } while ( ! x.viable() )This can work, but only if chromosome interpretation has already done much of the job.
May end up spending a lot of time on:
Nature has this problem too: