/// <summary> /// Construct an innovation list, that includes the initial innovations. /// </summary> /// <param name="population">The population to base this innovation list on.</param> public NEATInnovationList(NEATPopulation population) { Population = population; FindInnovation(Population.AssignGeneId()); // bias // input neurons for (int i = 0; i < Population.InputCount; i++) { FindInnovation(Population.AssignGeneId()); } // output neurons for (int i = 0; i < Population.OutputCount; i++) { FindInnovation(Population.AssignGeneId()); } // connections for (var fromId = 0; fromId < Population.InputCount + 1; fromId++) { for (var toId = 0; toId < Population.OutputCount; toId++) { FindInnovation(fromId, toId); } } }
/// <summary> /// Find an innovation for a hidden neuron that split a existing link. This /// is the means by which hidden neurons are introduced in NEAT. /// </summary> /// <param name="fromId">The source neuron ID in the link.</param> /// <param name="toId">The target neuron ID in the link.</param> /// <returns>The newly created innovation, or the one that matched the search.</returns> public NEATInnovation FindInnovationSplit(long fromId, long toId) { String key = ProduceKeyNeuronSplit(fromId, toId); lock (_list) { if (_list.ContainsKey(key)) { return(_list[key]); } long neuronId = Population.AssignGeneId(); var innovation = new NEATInnovation { InnovationId = Population.AssignInnovationId(), NeuronId = neuronId }; _list[key] = innovation; // create other sides of split, if needed FindInnovation(fromId, neuronId); FindInnovation(neuronId, toId); return(innovation); } }