Пример #1
0
        public int[] FindIndicesOfFittestIndividuals(Array <Fitness> fitnesses)
        {
            if (fitnesses.ContainsNulls())
            {
                throw new ArgumentException(nameof(fitnesses));
            }
            if (fitnesses.Length < _fittestCount)
            {
                throw new ArgumentException(nameof(fitnesses));
            }
            var objectiveCount = fitnesses[0].Count;

            for (int i = 0; i < fitnesses.Length; i++)
            {
                if (fitnesses[i].Count != objectiveCount)
                {
                    throw new ArgumentException(nameof(fitnesses));
                }
            }

            var dominatedByCounts = Pareto.ComputeDominatedByCounts(fitnesses);
            var indices           = new int[fitnesses.Length];

            for (int i = 0; i < indices.Length; i++)
            {
                indices[i] = i;
            }

            var fronts = indices
                         .GroupBy(i => dominatedByCounts[i])
                         .OrderBy(g => g.Key)
                         .Select(g => g.ToList())
                         .ToList();

            var fittestIndices = new List <int>(_fittestCount);

            foreach (var front in fronts)
            {
                if (fittestIndices.Count + front.Count <= _fittestCount)
                {
                    fittestIndices.AddRange(front);
                }
                else
                {
                    var mostDiverse = OrderFrontByDiversity(front, fitnesses).Take(_fittestCount - (fittestIndices.Count));
                    fittestIndices.AddRange(mostDiverse);
                    break;
                }
            }

            // Sanity check
            if (fittestIndices.Count != _fittestCount)
            {
                throw new InvalidOperationException();
            }

            // Sanity check
            if (fittestIndices.Distinct().Count() != fittestIndices.Count)
            {
                throw new InvalidOperationException();
            }

            // Sanity check
            if (fittestIndices.Any(i => i < 0))
            {
                throw new InvalidOperationException();
            }

            return(fittestIndices.ToArray());
        }