Closed schrum2 closed 6 years ago
Before getting too far on this, you may consider using SharpNEAT for Unity instead: https://github.com/lordjesus/UnityNEAT
UnityNEAT project has been successfully forked, set up, and tested as a separate project - ScopeUnityNEAT. There were import issues adding the assets to the existing art gallery and this seemed like a good step.
Here is how I would like mutations implemented in this code base (should improve over what is in mine): Note that in the following I will use terminology specific to Java ... may need to be translated into C# in some cases.
Define a global static variable ArrayList
Of course, what is a Mutation instance? Make this fully general. First define a Mutation
public boolean mutate(T genotype) {
if( random number < rate ) return apply(genotype);
else return false;
}
where the boolean indicates whether the genotype was actually altered by mutation. This calls an apply method
public abstract boolean apply(T genotype);
Is it virtual in C#? In any case, note that although apply will attempt to actually mutate the genotype, even it will not always be successful in altering the genotype, which is why it must also return a boolean.
Once this structure is in place, the actual 4 mutation types you will need are
AddLinkMutation<TWEANNGenotype>
SpliceNodeMutation<TWEANNGenotype>
PerturbWeightsMutation<TWEANNGenotype>
SwitchActivationFunctionMutation<TWEANNGenotype>
Most of these will simply override apply and call a single method in the TWEANNGenotype. However, PerturbWeightsMutation is a little trickier, since this mutation actually loops through ALL weights of the network and if the random number is less than the rate, the link will be altered. Therefore, the default link mutation rate should be small.
On a separate note, TWEANN crossover is very complicated, but also not incredibly important. Make a separate issue for TWEANNCrossover and just ignore it for now. We can actually make a perfectly functional prototype without using crossover at all.
Since crossover is no longer part of this issue, is it complete? If not, what is left?
Good point. crossover is standalone now so this can be closed
Once you have very simple evolution working ( #4 ) you should create a more complex genotype. Essentially, you will be making your own version of the TWEANN and TWEANNGenotype classes from the MM-NEAT code. Those classes are extremely complex, and you will not need every piece of code from the MM-NEAT versions, since you are creating something more stripped down. Also, since you are starting from scratch, you may find that there are simpler, cleaner ways to do some of the things I originally did in my code.
Ultimately, your TWEANN network class should focus on the methods defined in my Network interface, but you can ignore effectiveNumOutputs, isMultitask, chooseMode, and all of the methods about modules ... there really aren't that many methods you need. Just a way to send input and get output.
The TWEANNGenotype basically needs the methods of the Genotype interface, excluding the two methods about parents.