public void addHiddenNeuron(Neuron neuron) { hiddenNeurons.Add(neuron); }
public Neuron clone() { Neuron n = new Neuron(type); return(n); }
public Individual mutate(NEATConfig config) { Individual newIndiv = clone(); NeuralGraph newGraph = newIndiv.getGraph(); if (Utils.rand.NextDouble() < config.newConnectionProb) { // Select two random neurons and create (or enable) a link in-between int hiddenCount = newGraph.getHiddenNeurons().Count(); int inputCount = newGraph.getInputNeurons().Count(); int outputCount = newGraph.getOutputNeurons().Count(); // Select the input and output neurons int sourceIndex = Utils.rand.Next(hiddenCount + inputCount + outputCount); int destIndex = Utils.rand.Next(hiddenCount + outputCount); Neuron source, dest; if (sourceIndex < hiddenCount) { source = newGraph.getHiddenNeurons()[sourceIndex]; } else if (sourceIndex < hiddenCount + inputCount) { source = newGraph.getInputNeurons()[sourceIndex - hiddenCount]; } else { source = newGraph.getOutputNeurons()[sourceIndex - hiddenCount - inputCount]; } if (destIndex < hiddenCount) { dest = newGraph.getHiddenNeurons()[destIndex]; } else { dest = newGraph.getOutputNeurons()[destIndex - hiddenCount]; } Connection connection; if (!newGraph.getConnections()[dest].TryGetValue(source, out connection)) { connection = new Connection(source, dest, -1); // TODO what the crap is the parent innovation supposed to be here newGraph.addConnection(connection); } else { connection.enable(); } } if (Utils.rand.NextDouble() < config.newNodeProb) { // When adding a node, disable a connection and replace it by a neuron and two connections // The new input connection to that neuron has weight of 1, while output has same weight as disabled connection Connection connection = newGraph.getConnectionList()[Utils.rand.Next(newGraph.getConnectionList().Count)]; connection.disable(); Neuron neuron = new Neuron(NeuronType.Hidden); Connection newConn1 = new Connection(connection.getSource(), neuron, connection.getInnovation()); Connection newConn2 = new Connection(neuron, connection.getDest(), connection.getInnovation()); newGraph.addHiddenNeuron(neuron); newGraph.addConnection(newConn1); newGraph.addConnection(newConn2); } // Mutate each connection weight foreach (Connection connection in newGraph.getConnectionList()) { if (Utils.rand.NextDouble() < config.mutationProb) { if (Utils.rand.NextDouble() < config.uniformPerturbationMutationProb) { connection.setWeight(connection.getWeight() + Utils.rand.NextDouble() * 2 * config.perturbationStep - config.perturbationStep); } else { connection.setWeight(Utils.nextGaussian(0, 1)); } } } return(newIndiv); }