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()); }