/// <summary> /// Mutates the neuron's values /// </summary> /// <param name="mutability">The mutation rate</param> public void Mutate(double mutability) { coeficient += RandomThreadSafe.NextDouble(-mutability, mutability); coeficient = Math.Max(1, coeficient); coeficient = Math.Min(0, coeficient); mutability += RandomThreadSafe.NextDouble(-mutability, mutability); mutability = Math.Max(1, mutability); mutability = Math.Min(0, mutability); foreach (var output in outputs) { output.Mutate(mutability); } }
/// <summary> /// Generates a random brain /// </summary> public void GenerateRandom() { if (Generated) { throw new InvalidOperationException("Brain already generated!"); } for (int i = 0; i < inputNeurons.Length; i++) { inputNeurons[i] = new SensoryNeuron(); } for (int i = 0; i < thinkingNeurons.Length; i++) { thinkingNeurons[i] = new Neuron(); } for (int i = 0; i < outputNeurons.Length; i++) { outputNeurons[i] = new Neuron(); } for (int i = 0; i < memory.Length; i++) { memory[i] = RandomThreadSafe.NextDouble(); } //Not the true max, as we do not limit multiple synapses between the same neurons, but it is the count of possible unique ones var MaxSynapsesBetweenLayers = inputNeurons.Length * thinkingNeurons.Length; for (int i = 0; i < RandomThreadSafe.Next(MaxSynapsesBetweenLayers); i++) { var fromIndex = RandomThreadSafe.Next(inputNeurons.Length); var toIndex = RandomThreadSafe.Next(thinkingNeurons.Length); var synapse = new Synapse(inputNeurons[fromIndex], thinkingNeurons[toIndex], RandomThreadSafe.NextDouble()); } MaxSynapsesBetweenLayers = thinkingNeurons.Length * outputNeurons.Length; for (int i = 0; i < RandomThreadSafe.Next(MaxSynapsesBetweenLayers); i++) { var fromIndex = RandomThreadSafe.Next(thinkingNeurons.Length); var toIndex = RandomThreadSafe.Next(outputNeurons.Length); var synapse = new Synapse(thinkingNeurons[fromIndex], outputNeurons[toIndex], RandomThreadSafe.NextDouble()); } Generated = true; }
/// <summary> /// Mutates the neuron's synapses /// </summary> /// <param name="mutability">Mutation rate</param> /// <param name="targetNeurons">Possible neurons to connect new synapses to</param> public void MutateSynapses(double mutability, Neuron[] targetNeurons) { var synapsesToDie = new List <Synapse>(); foreach (var synapse in outputs) { synapse.Mutate(mutability); if (RandomThreadSafe.NextDouble() < mutability) { synapsesToDie.Add(synapse); } } foreach (var synapseToDie in synapsesToDie) { outputs.Remove(synapseToDie); synapseToDie.To.inputs.Remove(synapseToDie); } if (RandomThreadSafe.NextDouble() < mutability) { var possibleTarget = targetNeurons[RandomThreadSafe.Next(0, targetNeurons.Length)]; var newSynapse = new Synapse(this, possibleTarget, RandomThreadSafe.NextDouble()); } }
/// <summary> /// Mutates the synapse weight /// </summary> /// <param name="mutability">The mutation rate</param> public void Mutate(double mutability) { Weight += RandomThreadSafe.NextDouble(-mutability, mutability); Weight = Math.Max(1, Weight); Weight = Math.Min(0, Weight); }
/// <summary> /// Constructs a random neuron /// </summary> public Neuron() { coeficient = RandomThreadSafe.NextDouble(); }