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 void MutateAddNeuron() { bool done = false; while (!done) { int index = Random.Range(0, weights.Count); var weight = weights.ElementAt(index).Value; if (weight.enabled && !weight.recurrent && neurons[weight.neuronIn].type != Neuron.Type.BIAS) { done = true; float oldValue = weight.value; weight.enabled = false; int from = weight.neuronIn; int to = weight.neuronOut; float newSplitX = (neurons[from].splitX + neurons[to].splitX) / 2f; float newSplitY = (neurons[from].splitY + neurons[to].splitY) / 2f; // check whether new neuron is already in innovation database var oldNeuronInnovID = innovationDB.CheckNeuronInnovation(from, to); // new innovation if (oldNeuronInnovID == -1) { var neuronInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_NEURON, from, to, Neuron.Type.HIDDEN, newSplitX, newSplitY); var newNeuron = new Neuron(neuronInnov.neuronID, Neuron.Type.HIDDEN, newSplitX, newSplitY); neurons.Add(newNeuron.ID, newNeuron); var weightInInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_WEIGHT, from, newNeuron.ID, Neuron.Type.NONE, -1, -1); var weightIn = new Weight(weightInInnov.ID, from, newNeuron.ID, 1f, true, false); weights.Add(weightInInnov.ID, weightIn); var weightOutInnov = innovationDB.CreateInnovation(InnovationDB.Innovation.Type.NEW_WEIGHT, newNeuron.ID, to, Neuron.Type.NONE, -1, -1); var weightOut = new Weight(weightOutInnov.ID, newNeuron.ID, to, oldValue, true, false); weights.Add(weightOut.innovID, weightOut); } // innovation is already in innovation database else { var newNeuronID = innovationDB.GetNeuronID(oldNeuronInnovID); var oldWeightInID = innovationDB.CheckWeightInnovation(from, newNeuronID); var oldWeightOutID = innovationDB.CheckWeightInnovation(newNeuronID, to); if (oldWeightInID == -1 || oldWeightOutID == -1) { Debug.LogError("old innov ID " + oldNeuronInnovID); Debug.LogError("Error in MutateAddNeuron: weights not in database, from " + from + ", to " + to + " newNeuronID " + newNeuronID); return; } var newNeuron = new Neuron(newNeuronID, Neuron.Type.HIDDEN, newSplitX, newSplitY); neurons.Add(newNeuron.ID, newNeuron); var weightIn = new Weight(oldWeightInID, from, newNeuron.ID, 1f, true, false); weights.Add(weightIn.innovID, weightIn); var weightOut = new Weight(oldWeightOutID, newNeuron.ID, to, oldValue, true, false); weights.Add(weightOut.innovID, weightOut); } } } }