First off, we'd need to come up with a way for the user to create a custom gaussian distribution, where he can decide what values the standard deviation includes (taht is, so he can determine the range for 99% of the generated values).
Ok, this should be the basis of every correct mutation systems.
But I think this should only apply to immediate values and maybe pointers. I can't understand, for example, why an add command, to become a sqrt command, should pass by a sub and a mult command. Hope you're getting the point. Graduality in immediate values is (often) obvious.
5 .up store should be more likely to change in
6 .up store than in
500 .up store.
(but often is not: there is no apparent relation between -1 .shoot store and -2 .shoot store or 2 .shoot store ... and this is a big problem)
Same thing don't applies to instructions and even pointers. Is aimsx more similar to dx or to shoot? Who knows? Does the question even makes sense?
Another problem. Think a the eyeN values. They go from 0 to 100. Now take the refnrg value. It goes from 0 to 32000. Take the shootval value (memory shots): makes sense from 0 to 1000. Take the up, dn etc commands. They make sense (maybe) from -30 to 30.
This is a BIG problem. Mutations should be able to create new functionalities by mixing the code at random. But what can happen if I take a .refnrg value and put it in .dn? Nothing useful. Because the range of values offered by .refnrg is completely different from that accepted by .dn. What happens if the code
"5 . up store"? is mutated in "5 .repro store"? Nothing useful, again. A repro with a 5 value is nearly useless.
I think that these problem are deep in the structure of darwinbots.
A solution for the second problem could be this one: writing in the sysvars file the range of each var. You'd have
1 .up -20 20
2 .dn -20 20
....
5 .aimdx -600 600
...
501 .eye1 0 100
this way you would be able to normalize each value read or written to a var to an universal range... and have much more meaningful mutations.
Mutations aren't limited to reproduction only, nor are they limited to children during reproduction.
This again it's ok for me. Correct from the biological point of view. The only doubt I have about this is that it will likely introduce something like a maximum life span: because if you have, say, one point mutation every 100 dna positions every one thousand cycles on average, this makes it unlikely for a robot to live for arbitrarily long time (death by aging was one of the possibilities I wanted to leave open to evolution).
But on the other hand, robots could evolve multiple copies of the fundamental genes to avoid this problem.
Changes in type always move up or down by 1
This makes no sense, there is no reason for that. There is no reason for instructions to be "nearer" to pointers than immediate values are.
During reproduction, much more massive changes are possible.
I agree on that and on the mutation types you proposed
Mutations which result in a non existant command will show up as number@number (or some other code), with a toggle to turn off display of all Junk in most DNA viewing windows and recording areas.
The beauty of this is that as we add stuff to the program, we don't have to modify the mutations code. It's all set up to handle whatever we throw at it.
No. I perfectly understand what you mean, but keep in mind that those will always be useless mutations until you insert new commands into the dna interpreter. A useless mutation is a mutation that:
- either leave unchanged the functionality of the dna so that is in fact a non-mutation
- makes the code non executable or strongly disfunctional, so that you'll waste cpu cycles just for bringing the new mutated robot to death
Moreover, you have to keep in mind that you cannot add new commands AFTER the mutations are in the dna, because each mutation has to be positively selected by its effects. Introducing new commands after the mutations are in the dna means changing abruptly the way dnas a re interpreted. And that's no good.
So, I think that the best thing to do is allowing the mutations routines to produce only the actual instructions. Simply code them with numbers going from 1 to max and, when you introduce the (n+1)th instruction, change the max to n+1.