/// <summary>
 /// Обучить нейрон-победитель.
 /// </summary>
 /// <param name="neuronWinner">Нейрон-победитель.</param>
 /// <param name="inputEntity">Входной вектор.</param>
 /// <param name="learningRate">Скорость обучения.</param>
 public void StudyNeuron(KohonenNeuron neuronWinner, NetworkDataEntity inputEntity, double learningRate)
 {
     for (int i = 0; i < neuronWinner.Weights.Count(); i++)
     {
         neuronWinner.Weights[i] = neuronWinner.Weights[i] +
                                   learningRate * (inputEntity.AttributeValues[i].GetNormalizedValue(NormalizationType) - neuronWinner.Weights[i]);
     }
 }
        /// <summary>
        /// Обучить входной вектор (провести итерацию обучения).
        /// </summary>
        /// <param name="inputEntity">Входной вектор.</param>
        /// <param name="currentIteration">Номер текущей итерации обучения.</param>
        /// <param name="iterationsCount">Общее количество итераций обучения.</param>
        /// <returns>Ошибка обучения.</returns>
        public override double StudyInputEntity(NetworkDataEntity inputEntity, int currentIteration, int iterationsCount)
        {
            var neuronWinner = GetNeuronWinner(inputEntity);

            var learningRate = GetLearningRate(currentIteration, iterationsCount);

            StudyNeuron(neuronWinner, inputEntity, learningRate);

            var    attributeValues = inputEntity.AttributeValues.Select(v => v.GetNormalizedValue(NormalizationType));
            double error           = GetEuclideanDistance(neuronWinner.Weights, attributeValues);

            return(error);
        }
        /// <summary>
        /// Получить нейрон-победитель.
        /// </summary>
        /// <param name="inputEntity">Входной вектор.</param>
        /// <returns>Нейрон-победитель для входного вектора.</returns>
        public override KohonenNeuron GetNeuronWinner(NetworkDataEntity inputEntity)
        {
            var           attributeValues = inputEntity.AttributeValues.Select(v => v.GetNormalizedValue(NormalizationType));
            double        minDistance     = GetEuclideanDistance(Neurons[0].Weights, attributeValues);
            KohonenNeuron neuronWinner    = Neurons[0];

            for (int i = 1; i < Neurons.Count; i++)
            {
                double currentDistance = GetEuclideanDistance(Neurons[i].Weights, attributeValues);
                if (currentDistance < minDistance)
                {
                    minDistance  = currentDistance;
                    neuronWinner = Neurons[i];
                }
            }
            return(neuronWinner);
        }