This page is an experiment. DNA (which codes for proteins that peform functions in individual cells) is like the source code for the biological machinery in living organisms. So if the process of evolution generated all the biological complexity encoded in DNA, then shouldn't it also be able to generate complex computer programs? The code on this page simulates chemical evolution to try and evolve simple JavaScript functions with given behaviours from basic building blocks. The question is, does the evolutionary process cause the random starting programs to become more complex?

But that's where I need your help: Your challenge, should you choose to accept it, is to tune the parameters below, to reliably evolve a function with one of the example behaviours. But be warned: this may not be as simple as you think...

The Algorithm

The following pseudocode describes the basic genetic search algorithm we've implemented to simulate the evolutionary process.

  1. Create initial population P of random viable programs.
  2. Evaluate the fitness of every p in P using the fitness function.
  3. While generation g is less than MAX GENERATIONS:
    1. Select Q to the top MAX PARENTS in P by fitness.
    2. For every parent program p1 in Q
      Repeat CHILDREN PER PARENT times:
      1. If SEXUAL REPRODUCTION enabled:
        1. Select random parent p2 from Q.
        2. Generate c by combining p1 and p2 using crossover function.
      2. Else
        1. Generate c by cloning p1
      3. Mutate c with random probabilty.
      4. Evaluate fitness of c using fitness function.
      5. Add c to Q'
    3. Replace P with Q union Q'
    4. Increment g

Child programs are generated in sexual reproduction by combining two parent programs using the crossover function. This function combines the statement/expression trees by recursively combining any statements with the same number of placeholders, and then randomly choosing to use the expression from the left or right parent wherever there are different numbers of placeholders.

Child programs are mutated with random probability by: swapping random sub-statements/expressions, replacing a statement with another random statement, inserting a random statement, or deleting a random branch.

Examples Choose an example:

Choose an example from the list above to pre-populate the search fields.

Fitness formulae

These equations are like genetic markers which define what it means for a candidate JavaScript program to be "fit" in a given environment. Together with the fitness test function below, these define how likely a candidate program is to surive and reproduce (i.e. be selected). They should be one per line in the form f(args) = return_value.

Search space

These templates are like a "pre-biotic soup" containing the basic building blocks from which to build the candidate programs. They should be one per line, and can contain placeholders using the ?? wildcard. Together with the maximum program size parameter they define the search space of all possible programs to consider.

Search space size: possible programs.
Search parameters

The following inputs allow you to "tune the dials" on the evolutionary process:


Search space size: possible programs.





This function evaluates the fitness of a given candidate function. It does this by comparing the actual return values returned by the candidate to expected return values defined in the equations. It should return a positive numeric error value to represent "how far" the actual values are from the required solutions. Here lower values indicate better results, where 0 means the function returned the exact values required. If an actual equals null this means the candidate raised an Exception (e.g. SyntaxError) to that input arg. If this function returns null, it means that this candidate is not viable and is therefore considered completely unfit i.e. "dead".

Search status 0
0
0 of possible.
0
0


Why didn't it work?