// create weight at network initialization public void CreateStartWeight(int neuronIn, int neuronOut, float value) { var oldWeightInnovID = innovationDB.CheckWeightInnovation(neuronIn, neuronOut); Weight newWeight; // new innovation if (oldWeightInnovID == -1) { var weightInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_WEIGHT, neuronIn, neuronOut, Neuron.Type.NONE, -1, -1); newWeight = new Weight(weightInnov.ID, neuronIn, neuronOut, value, true, false); } else { newWeight = new Weight(oldWeightInnovID, neuronIn, neuronOut, value, true, false); } weights.Add(newWeight.innovID, newWeight); }
public void MutateEnableDisable(bool enable) { var candidates = new IntWeightDictionary(); for (int i = 0; i < weights.Count; i++) { var weight = weights.ElementAt(i).Value; if (weight.enabled != enable) { candidates.Add(i, weight); } } if (candidates.Count == 0) { return; } var chosen = candidates.ElementAt(Random.Range(0, candidates.Count)).Value; chosen.enabled = enable; }
public Genome Crossover(Genome other) { var parentA = this; var parentB = other; Genome best = new Genome(); if (parentA.fitness == parentB.fitness) { // if same fitness pick shortest genome if (parentA.NumGenes() < parentB.NumGenes()) { best = parentA; } else if (parentB.NumGenes() < parentA.NumGenes()) { best = parentB; } else { int randomElement = Random.Range(0, 2); best = randomElement == 0 ? parentA : parentB; } } else if (parentA.fitness > parentB.fitness) { best = parentA; } else { best = parentB; } var childWeights = new IntWeightDictionary(); var childNeurons = new IntNeuronDictionary(); int parentAIndex = 0, parentBIndex = 0; Weight parentAWeight = null, parentBWeight = null; // while end of both genes is not reached while (parentAIndex < parentA.weights.Count || parentBIndex < parentB.weights.Count) { if (parentAIndex < parentA.weights.Count) { parentAWeight = parentA.weights.ElementAt(parentAIndex).Value.Copy(); } if (parentBIndex < parentB.weights.Count) { parentBWeight = parentB.weights.ElementAt(parentBIndex).Value.Copy(); } Weight selectedWeight = null; if (parentAIndex == parentA.weights.Count && parentBIndex != parentB.weights.Count) { // add excess genes if (parentB == best) { selectedWeight = parentBWeight; } parentBIndex++; } else if (parentBIndex == parentB.weights.Count && parentAIndex != parentA.weights.Count) { // add excess genes if (parentA == best) { selectedWeight = parentAWeight; } parentAIndex++; } else if (parentAWeight.innovID < parentBWeight.innovID) { // add parentA disjoint genes if (parentA == best) { selectedWeight = parentAWeight; } parentAIndex++; } else if (parentBWeight.innovID < parentAWeight.innovID) { // add parentB disjoint genes if (parentB == best) { selectedWeight = parentBWeight; } parentBIndex++; } else { int randomElement = Random.Range(0, 2); selectedWeight = randomElement == 0 ? parentAWeight : parentBWeight; if (!parentAWeight.enabled && !parentBWeight.enabled) { float random = Random.value; if (random <= pWeightEnabled) { selectedWeight.enabled = true; } } parentAIndex++; parentBIndex++; } if (selectedWeight != null && !childWeights.ContainsKey(selectedWeight.innovID)) { childWeights.Add(selectedWeight.innovID, selectedWeight); } if (selectedWeight != null) { if (!childNeurons.ContainsKey(selectedWeight.neuronIn)) { Neuron neuron = null; if (parentA.weights.Any(x => x.Value.neuronIn == selectedWeight.neuronIn)) { neuron = parentA.neurons[selectedWeight.neuronIn].Copy(); } else if (parentB.weights.Any(x => x.Value.neuronIn == selectedWeight.neuronIn)) { neuron = parentB.neurons[selectedWeight.neuronIn].Copy(); } if (neuron == null) { Debug.LogError("NEURON IS NULL!"); } childNeurons.Add(neuron.ID, neuron); } if (!childNeurons.ContainsKey(selectedWeight.neuronOut)) { Neuron neuron = null; if (parentA.weights.Any(x => x.Value.neuronOut == selectedWeight.neuronOut)) { neuron = parentA.neurons[selectedWeight.neuronOut].Copy(); } else if (parentB.weights.Any(x => x.Value.neuronOut == selectedWeight.neuronOut)) { neuron = parentB.neurons[selectedWeight.neuronOut].Copy(); } if (neuron == null) { Debug.LogError("NEURON IS NULL!"); } childNeurons.Add(neuron.ID, neuron); } } } return(new Genome(childNeurons, childWeights)); }