public ConnectionNeurons GetConnectionNeurons(int vacantConnectionIdx, NeatChromosome neatChromosome, HiddenNeuronList hiddenNeurons) { var outerLayersVacantConnectionCount = _maxOuterLayersConnectionCount - neatChromosome.OuterLayersConnections.Count; return(vacantConnectionIdx < outerLayersVacantConnectionCount ? GetOuterLayersVacantConnectionNeurons(vacantConnectionIdx, neatChromosome.OuterLayersConnections) : GetHiddenLayersVacantConnectionNeurons(vacantConnectionIdx - outerLayersVacantConnectionCount, neatChromosome, hiddenNeurons)); }
public NeatChromosome(NeatChromosome neatChromosome) { _outerLayersConnections = new List <ConnectionGene>(neatChromosome.OuterLayersConnections); _hiddenLayersConnections = new List <ConnectionGene>(neatChromosome.HiddenLayersConnections); InputCount = neatChromosome.InputCount; OutputCount = neatChromosome.OutputCount; OuterLayersNeuronCount = neatChromosome.OuterLayersNeuronCount; HiddenNeuronCount = neatChromosome.HiddenNeuronCount; _maxInnovationId = neatChromosome._maxInnovationId; }
internal int GetVacantConnectionCount(NeatChromosome neatChromosome, HiddenNeuronList hiddenNeurons) { var maxInputToHiddenCount = _inputs.Count * hiddenNeurons.Count; var maxHiddenToOutputCount = hiddenNeurons.Count * _outputs.Count; var maxOutputToHiddenCount = _isRecurrent ? maxHiddenToOutputCount : 0; var maxHiddenToHiddenCount = hiddenNeurons.Count * (_isRecurrent ? hiddenNeurons.Count : hiddenNeurons.Count - 1); return(_maxOuterLayersConnectionCount + maxInputToHiddenCount + maxHiddenToOutputCount + maxOutputToHiddenCount + maxHiddenToHiddenCount - neatChromosome.Count); }
private ConnectionNeurons GetHiddenLayersVacantConnectionNeurons(int vacantConnectionIdx, NeatChromosome neatChromosome, HiddenNeuronList hiddenNeurons) { NeuronGene GetSourceNeuronGene(int sourceNeuronIdx, int targetNeuronIdx) { if (sourceNeuronIdx < _inputs.Count) { return(_inputs[sourceNeuronIdx]); } if (_isRecurrent) { return(sourceNeuronIdx < _inputs.Count + _outputs.Count ? _outputs[sourceNeuronIdx - _inputs.Count] : hiddenNeurons.Keys[sourceNeuronIdx - _inputs.Count - _outputs.Count]); } //feedforward var sourceHiddenNeuronIdx = sourceNeuronIdx - _inputs.Count; return(sourceHiddenNeuronIdx < targetNeuronIdx ? hiddenNeurons.Keys[sourceHiddenNeuronIdx] : hiddenNeurons.Keys[sourceHiddenNeuronIdx + 1]); } var maxInConnectionCount = _inputs.Count + hiddenNeurons.Count + (_isRecurrent ? _outputs.Count : -1); var vacantConnectionSum = 0; int hiddenNeuronIdx; var inConnectionCount = 0; for (hiddenNeuronIdx = 0; hiddenNeuronIdx < hiddenNeurons.Count; hiddenNeuronIdx++) { inConnectionCount = hiddenNeurons.Values[hiddenNeuronIdx].@in; vacantConnectionSum += maxInConnectionCount - inConnectionCount; if (vacantConnectionSum > vacantConnectionIdx) { break; } } var hiddenLayersConnections = neatChromosome.HiddenLayersConnections; // There are no enough incoming vacant connections in hidden neurons, search in hidden to output connections if (vacantConnectionSum <= vacantConnectionIdx) { return(GetHiddenToOuterLayerVacantConnectionNeurons(vacantConnectionIdx - vacantConnectionSum, hiddenLayersConnections, hiddenNeurons)); } var hiddenNeuronVacantConnectionIdx = vacantConnectionIdx - (vacantConnectionSum - (maxInConnectionCount - inConnectionCount)); var targetHiddenNeuron = hiddenNeurons.Keys[hiddenNeuronIdx]; if (inConnectionCount == 0) { return(new ConnectionNeurons(GetSourceNeuronGene(hiddenNeuronVacantConnectionIdx, hiddenNeuronIdx), targetHiddenNeuron)); } var connectionIdx = neatChromosome.FindFirstHiddenLayerConnectionIdx(targetHiddenNeuron.Id); int connectionCount; var connection = hiddenLayersConnections[connectionIdx]; for (connectionCount = 0; connection.Target == targetHiddenNeuron; connection = hiddenLayersConnections[connectionIdx]) { if (!connection.Source.IsHidden) { var vacantConnectionCount = connection.SourceId - connectionCount; if (vacantConnectionCount > hiddenNeuronVacantConnectionIdx) { break; } } else //connection source is hidden neuron { var sourceNeuronIdx = hiddenNeurons.IndexOfKey(connection.Source); var vacantConnectionCount = _inputs.Count + (_isRecurrent ? _outputs.Count : 0) + sourceNeuronIdx - (!_isRecurrent && sourceNeuronIdx >= hiddenNeuronIdx ? 1 : 0) - connectionCount; if (vacantConnectionCount > hiddenNeuronVacantConnectionIdx) { break; } } connectionCount++; if (++connectionIdx == hiddenLayersConnections.Count) { break; } } var sourceIdx = connectionCount + hiddenNeuronVacantConnectionIdx; return(new ConnectionNeurons(GetSourceNeuronGene(sourceIdx, hiddenNeuronIdx), targetHiddenNeuron)); }