public async Task <ImmutableHashSet <TChromosome> > SelectAsync( IEnumerable <TChromosome> parents, IEnumerable <TChromosome> offspring, int expectedOffspringCount, CancellationToken token) { var uniqueOffspring = offspring.ToImmutableHashSet(); if (uniqueOffspring.Count <= expectedOffspringCount) { return(uniqueOffspring); } var fronts = FastNondominatedSorter .Sort(uniqueOffspring, _offspringComparer); var selectedOffspring = new List <TChromosome>(); IEnumerable <TChromosome> lastFront = new TChromosome[] { }; foreach (var front in fronts) { if (selectedOffspring.Count + front.Count() > expectedOffspringCount) { lastFront = front; break; } selectedOffspring.AddRange(front); } if (selectedOffspring.Count >= expectedOffspringCount) { return(selectedOffspring .Take(expectedOffspringCount) .ToImmutableHashSet()); } return(await _selector.SelectAsync( selectedOffspring.ToImmutableHashSet(), lastFront.ToImmutableHashSet(), expectedOffspringCount, token)); }
public async Task <ImmutableHashSet <TChromosome> > SelectAsync( IEnumerable <TChromosome> parents, IEnumerable <TChromosome> offspring, int expectedOffspringCount, CancellationToken token) { var uniqueOffspring = offspring.ToImmutableHashSet(); if (uniqueOffspring.Count <= expectedOffspringCount) { return(uniqueOffspring); } var fronts = FastNondominatedSorter.Sort(uniqueOffspring, _offspringComparer); var selectedOffspring = new List <TChromosome>(); IEnumerable <TChromosome> lastFront = new TChromosome[] { }; foreach (var front in fronts) { if (selectedOffspring.Count + front.Count() > expectedOffspringCount) { lastFront = front; break; } selectedOffspring.AddRange(front); } if (selectedOffspring.Count >= expectedOffspringCount) { return(selectedOffspring.Take(expectedOffspringCount).ToImmutableHashSet()); } var calculatable = lastFront.Union(selectedOffspring).ToArray(); var tasks = _objectives.Select(async objective => { double CalculateDistance(TChromosome left, TChromosome right) { return(Math.Sqrt(_objectives.Sum(innerObjective => Math.Pow(_mapper.GetValue(innerObjective, left.Fitness) - _mapper.GetValue(innerObjective, right.Fitness), 2)))); } var orderedChromosome = calculatable.OrderBy(chromosome => _mapper.GetValue(objective, chromosome.Fitness)) .ThenBy(chromosome => _objectives.Average(obj => _mapper.GetValue(obj, chromosome.Fitness))) .ToImmutableArray(); var first = orderedChromosome.First(); var last = orderedChromosome.Last(); var distances = calculatable.ToDictionary(chromosome => chromosome, _ => 0d); var longestDistance = CalculateDistance(first, last); distances[first] += longestDistance; distances[last] += longestDistance; var innerTasks = orderedChromosome.Skip(1).Take(orderedChromosome.Length - 2) .Select((chromosome, i) => Task.Run(() => { var upper = orderedChromosome[i + 2]; var lower = orderedChromosome[i]; distances[chromosome] += CalculateDistance(upper, lower); }, token)); await Task.WhenAll(innerTasks); return(distances); }); var allDistances = await Task.WhenAll(tasks); return(calculatable.ToDictionary(chromosome => chromosome, chromosome => allDistances.Sum(distances => distances[chromosome])) .OrderByDescending(kv => kv.Value) .Take(expectedOffspringCount) .Select(kv => kv.Key) .ToImmutableHashSet()); }