public NSGA2(int numParents, int populationSize) { PopulationSize = populationSize; NumParents = numParents; GenePool = new Solution[PopulationSize]; Parents = new Solution[numParents]; }
public Solution[] Tournament() { FitnessFunction(GenePool); // Tournament and assign first front var fronts = new List<List<Solution>>(NumFronts); fronts.Add(new List<Solution>()); foreach (var solution in GenePool) { solution.DominatedSolutions = new List<Solution>(); solution.DominationCounter = 0; foreach(var competitor in GenePool.Except(new List<Solution>() { solution })) { if(solution.Fitnesses.Average() > competitor.Fitnesses.Average()) { solution.DominatedSolutions.Add(competitor); } else if(solution.Fitnesses.Average() < competitor.Fitnesses.Average()) { solution.DominationCounter++; } } if(solution.Rank == 0) { solution.Rank = 1; fronts[0].Add(solution); } } // Assign other fronts for(var i = 0; i < NumFronts; i++) { foreach(var solution in fronts[i]) { foreach(var domCompetitor in solution.DominatedSolutions) { domCompetitor.DominationCounter--; if(domCompetitor.DominationCounter == 0) { domCompetitor.Rank = i + 1; fronts[i + 1].Add(domCompetitor); } } } } // Assign crowding distance var numObjectives = fronts[0][0].Fitnesses.Count(); foreach (var front in fronts) { for(var m = 0; m < numObjectives; m++) { front.Sort((solA, solB) => solA.Fitnesses[m].CompareTo(solB.Fitnesses[m])); var max = front.Max(sol => sol.Fitnesses[m]); var min = front.Min(sol => sol.Fitnesses[m]); var range = max - min; for (var i = 1; i < front.Count -1; i++) { front[i].CrowdingDistance[m] += (front[i].Fitnesses[i + 1] - front[i].Fitnesses[i - 1]) / range; } } } // Select the best var remaining = NumParents; var nParents = new Solution[NumParents]; while (remaining != 0) { foreach (var front in fronts) { var startIndex = NumParents - remaining; front.Sort((solA, solB) => { if (solA.Rank < solB.Rank || ((solA.Rank == solB.Rank) && solA.CrowdingDistance.Average() > solB.CrowdingDistance.Average())) { return 1; } else if (solB.Rank > solA.Rank || ((solA.Rank == solB.Rank) && solA.CrowdingDistance.Average() > solB.CrowdingDistance.Average())) { return -1; } else { return 0; } }); if (front.Count >= remaining) { for (var i = 0; i < remaining; i++) { nParents[startIndex + i] = front[i]; } } else { for (var i = 0; i < remaining; i++) { nParents[startIndex + i] = front[i]; } remaining -= front.Count; } } } return nParents; }