public void addSynapse(Synapse synapse, Genome parent1, Genome parent2) { if (this.fitness != -1) { return; } if (this.synapses.ContainsKey(synapse.innovationNumber)) { return; } synapse = synapse.clone(); if (parent1 != null && parent2 != null) { if (parent1.hasSynapse(synapse.innovationNumber) && parent2.hasSynapse(synapse.innovationNumber)) { bool dis1 = !parent1.synapses[synapse.innovationNumber].enabled; bool dis2 = !parent2.synapses[synapse.innovationNumber].enabled; if ((dis1 && !dis2) || (!dis1 && dis2)) { bool disabled = RandomUtil.success(Config.NEURON_DISABLE_CHANCE); synapse.enabled = !disabled; } } } this.synapses.Add(synapse.innovationNumber, synapse); }
public void removeDuplicateSynapses() { if (this.fitness != -1) { throw new Exception("Can't remove duplicate of a untested Genome"); } foreach (Species species in this.neat.popManager.currentPop.species) { foreach (Genome genome in species.genomes) { List <ZeroSynapse> conA = this.getAllSynapses(); List <ZeroSynapse> conB = genome.getAllSynapses(); if (ListUtil.equals(conB, conA)) { List <Synapse> toCloneFrom = new List <Synapse>(genome.synapses.Values); List <Synapse> toReplace = new List <Synapse>(this.synapses.Values); for (int i = 0; i < toCloneFrom.Count; i++) { if (toCloneFrom[i] == null || toReplace[i] == null) { return; } Synapse from = toCloneFrom[i]; Synapse to = toReplace[i]; int oldInno = to.innovationNumber; int changeTo = from.innovationNumber; Synapse old = this.synapses[oldInno]; if (!this.synapses.Remove(oldInno)) { new Exception("Synapse could not be removed " + old.toString()); } old.innovationNumber = changeTo; this.synapses.Add(old.innovationNumber, old); } } } } }
// REF: [GITHUB] SanderGielisse logic for distance // between genomes (eg compatibility) // (https://github.com/SanderGielisse/Mythan) public static double distance(Genome a, Genome b) { int aLength = a.getHighestInnovationNumber(); int bLength = b.getHighestInnovationNumber(); Genome longest; Genome shortest; if (aLength > bLength) { longest = a; shortest = b; } else { longest = b; shortest = a; } int shortestLength = shortest.getHighestInnovationNumber(); int longestLength = longest.getHighestInnovationNumber(); double disjoint = 0; double excess = 0; List <double> weights = new List <double>(); for (int i = 0; i < longestLength; i++) { Synapse aa = longest.getSynapse(i); Synapse bb = shortest.getSynapse(i); if ((aa == null && bb != null) || (aa != null && bb == null)) { // only present in one of them if (i <= shortestLength) { disjoint++; } else if (i > shortestLength) { excess++; } } if (aa != null && bb != null) { double distance = Math.Abs(aa.weight - bb.weight); weights.Add(distance); } } double total = 0; double size = 0; foreach (double w in weights) { total += w; size++; } double averageWeightDistance = total / size; double n = longest.synapses.Count; double c1 = Config.DISTANCE_EXCESS_WEIGHT; double c2 = Config.DISTANCE_DISJOINT_WEIGHT; double c3 = Config.DISTANCE_WEIGHTS_WEIGHT; double d = ((c1 * excess) / n) + ((c2 * disjoint) / n) + (c3 * averageWeightDistance); return(d); }