Changeset 14705
- Timestamp:
- 02/27/17 10:09:36 (8 years ago)
- Location:
- branches/ichiriac/HeuristicLab.Algorithms.GDE3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ichiriac/HeuristicLab.Algorithms.GDE3
-
Property
svn:ignore
set to
obj
-
Property
svn:ignore
set to
-
branches/ichiriac/HeuristicLab.Algorithms.GDE3/GDE3.cs
r14087 r14705 40 40 using HeuristicLab.Algorithms.GDE3; 41 41 42 namespace HeuristicLab.Algoritms.GDE3 43 { 44 45 [Item("Generalized Differential Evolution (GDE3)", "A generalized differential evolution algorithm.")] 46 [StorableClass] 47 [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 400)] 48 public class GDE3 : BasicAlgorithm 49 { 50 public override Type ProblemType 51 { 52 get { return typeof(MultiObjectiveTestFunctionProblem); } 53 } 54 public new MultiObjectiveTestFunctionProblem Problem 55 { 56 get { return (MultiObjectiveTestFunctionProblem)base.Problem; } 57 set { base.Problem = value; } 58 } 59 60 public ILookupParameter<DoubleMatrix> BestKnownFrontParameter 61 { 62 get 63 { 64 return (ILookupParameter<DoubleMatrix>)Parameters["BestKnownFront"]; 42 namespace HeuristicLab.Algoritms.GDE3 { 43 44 [Item("Generalized Differential Evolution (GDE3)", "A generalized differential evolution algorithm.")] 45 [StorableClass] 46 [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 400)] 47 public class GDE3 : BasicAlgorithm { 48 public override Type ProblemType { 49 get { return typeof(MultiObjectiveBasicProblem<RealVectorEncoding>); } 50 } 51 public new MultiObjectiveTestFunctionProblem Problem { 52 get { return (MultiObjectiveTestFunctionProblem)base.Problem; } 53 set { base.Problem = value; } 54 } 55 56 public ILookupParameter<DoubleMatrix> BestKnownFrontParameter { 57 get { 58 return (ILookupParameter<DoubleMatrix>)Parameters["BestKnownFront"]; 59 } 60 } 61 62 private readonly IRandom _random = new MersenneTwister(); 63 private int evals; 64 private double IGDSumm; 65 66 #region ParameterNames 67 private const string MaximumGenerationsParameterName = "Maximum Generations"; 68 private const string MaximumEvaluationsParameterName = "Maximum Evaluations"; 69 private const string CrossoverProbabilityParameterName = "CrossoverProbability"; 70 private const string PopulationSizeParameterName = "PopulationSize"; 71 private const string ScalingFactorParameterName = "ScalingFactor"; 72 73 #endregion 74 75 #region ParameterProperties 76 public IFixedValueParameter<IntValue> MaximumGenerationsParameter { 77 get { return (IFixedValueParameter<IntValue>)Parameters[MaximumGenerationsParameterName]; } 78 } 79 public IFixedValueParameter<IntValue> MaximumEvaluationsParameter { 80 get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluationsParameterName]; } 81 } 82 private ValueParameter<IntValue> PopulationSizeParameter { 83 get { return (ValueParameter<IntValue>)Parameters[PopulationSizeParameterName]; } 84 } 85 public ValueParameter<DoubleValue> CrossoverProbabilityParameter { 86 get { return (ValueParameter<DoubleValue>)Parameters[CrossoverProbabilityParameterName]; } 87 } 88 public ValueParameter<DoubleValue> ScalingFactorParameter { 89 get { return (ValueParameter<DoubleValue>)Parameters[ScalingFactorParameterName]; } 90 } 91 #endregion 92 93 #region Properties 94 public int MaximumGenerations { 95 get { return MaximumGenerationsParameter.Value.Value; } 96 set { MaximumGenerationsParameter.Value.Value = value; } 97 } 98 99 public int MaximumEvaluations { 100 get { return MaximumEvaluationsParameter.Value.Value; } 101 set { MaximumEvaluationsParameter.Value.Value = value; } 102 } 103 104 public Double CrossoverProbability { 105 get { return CrossoverProbabilityParameter.Value.Value; } 106 set { CrossoverProbabilityParameter.Value.Value = value; } 107 } 108 public Double ScalingFactor { 109 get { return ScalingFactorParameter.Value.Value; } 110 set { ScalingFactorParameter.Value.Value = value; } 111 } 112 public IntValue PopulationSize { 113 get { return PopulationSizeParameter.Value; } 114 set { PopulationSizeParameter.Value = value; } 115 } 116 #endregion 117 118 #region ResultsProperties 119 private double ResultsBestQuality { 120 get { return ((DoubleValue)Results["Best Quality"].Value).Value; } 121 set { ((DoubleValue)Results["Best Quality"].Value).Value = value; } 122 } 123 124 private double ResultsIGDMean { 125 get { return ((DoubleValue)Results["IGDMeanValue"].Value).Value; } 126 set { ((DoubleValue)Results["IGDMeanValue"].Value).Value = value; } 127 } 128 129 private double ResultsIGDBest { 130 get { return ((DoubleValue)Results["IGDBestValue"].Value).Value; } 131 set { ((DoubleValue)Results["IGDBestValue"].Value).Value = value; } 132 } 133 134 private double ResultsIGDWorst { 135 get { return ((DoubleValue)Results["IGDWorstValue"].Value).Value; } 136 set { ((DoubleValue)Results["IGDWorstValue"].Value).Value = value; } 137 } 138 139 private double ResultsInvertedGenerationalDistance { 140 get { return ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value; } 141 set { ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value = value; } 142 } 143 144 private double ResultsHypervolume { 145 get { return ((DoubleValue)Results["HyperVolumeValue"].Value).Value; } 146 set { ((DoubleValue)Results["HyperVolumeValue"].Value).Value = value; } 147 } 148 149 private DoubleMatrix ResultsBestFront { 150 get { return (DoubleMatrix)Results["Best Front"].Value; } 151 set { Results["Best Front"].Value = value; } 152 } 153 154 private int ResultsEvaluations { 155 get { return ((IntValue)Results["Evaluations"].Value).Value; } 156 set { ((IntValue)Results["Evaluations"].Value).Value = value; } 157 } 158 private int ResultsGenerations { 159 get { return ((IntValue)Results["Generations"].Value).Value; } 160 set { ((IntValue)Results["Generations"].Value).Value = value; } 161 } 162 private double ResultsGenerationalDistance { 163 get { return ((DoubleValue)Results["GenerationalDistance"].Value).Value; } 164 set { ((DoubleValue)Results["GenerationalDistance"].Value).Value = value; } 165 } 166 167 private double ResultsSpacing { 168 get { return ((DoubleValue)Results["Spacing"].Value).Value; } 169 set { ((DoubleValue)Results["Spacing"].Value).Value = value; } 170 } 171 172 private double ResultsCrowding { 173 get { return ((DoubleValue)Results["Crowding"].Value).Value; } 174 set { ((DoubleValue)Results["Crowding"].Value).Value = value; } 175 } 176 177 #endregion 178 179 [StorableConstructor] 180 protected GDE3(bool deserializing) : base(deserializing) { } 181 182 protected GDE3(GDE3 original, Cloner cloner) 183 : base(original, cloner) { 184 } 185 186 public override IDeepCloneable Clone(Cloner cloner) { 187 return new GDE3(this, cloner); 188 } 189 190 public GDE3() { 191 Parameters.Add(new FixedValueParameter<IntValue>(MaximumGenerationsParameterName, "", new IntValue(1000))); 192 Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(Int32.MaxValue))); 193 Parameters.Add(new ValueParameter<IntValue>(PopulationSizeParameterName, "The size of the population of solutions.", new IntValue(100))); 194 Parameters.Add(new ValueParameter<DoubleValue>(CrossoverProbabilityParameterName, "The value for crossover rate", new DoubleValue(0.5))); 195 Parameters.Add(new ValueParameter<DoubleValue>(ScalingFactorParameterName, "The value for scaling factor", new DoubleValue(0.5))); 196 Parameters.Add(new LookupParameter<DoubleMatrix>("BestKnownFront", "The currently best known Pareto front")); 197 } 198 199 protected override void Run(CancellationToken cancellationToken) { 200 // Set up the results display 201 Results.Add(new Result("Generations", new IntValue(0))); 202 Results.Add(new Result("Evaluations", new IntValue(0))); 203 Results.Add(new Result("Best Front", new DoubleMatrix())); 204 Results.Add(new Result("Crowding", new DoubleValue(0))); 205 Results.Add(new Result("InvertedGenerationalDistance", new DoubleValue(0))); 206 Results.Add(new Result("GenerationalDistance", new DoubleValue(0))); 207 Results.Add(new Result("HyperVolumeValue", new DoubleValue(0))); 208 Results.Add(new Result("IGDMeanValue", new DoubleValue(0))); 209 Results.Add(new Result("IGDBestValue", new DoubleValue(Int32.MaxValue))); 210 Results.Add(new Result("IGDWorstValue", new DoubleValue(0))); 211 212 Results.Add(new Result("Spacing", new DoubleValue(0))); 213 Results.Add(new Result("Scatterplot", typeof(IMOFrontModel))); 214 var table = new DataTable("Qualities"); 215 table.Rows.Add(new DataRow("Best Quality")); 216 Results.Add(new Result("Qualities", table)); 217 218 //setup the variables 219 List<SolutionSet> population; 220 List<SolutionSet> offspringPopulation; 221 SolutionSet[] parent; 222 double IGDSumm = 0; 223 224 //initialize population 225 population = new List<SolutionSet>(PopulationSizeParameter.Value.Value); 226 227 for(int i = 0; i < PopulationSizeParameter.Value.Value; ++i) { 228 var m = createIndividual(); 229 m.Quality = Problem.Evaluate(m.Population, _random); 230 //the test function is constrained 231 if(m.Quality.Length > Problem.Objectives) { 232 m.OverallConstrainViolation = m.Quality[Problem.Objectives]; 233 } else { 234 m.OverallConstrainViolation = 0; 235 } 236 population.Add(m); 237 } 238 239 this.initProgress(); 240 int generations = 1; 241 242 while(ResultsEvaluations < MaximumEvaluationsParameter.Value.Value 243 && !cancellationToken.IsCancellationRequested) { 244 var populationSize = PopulationSizeParameter.Value.Value; 245 246 // Create the offSpring solutionSet 247 offspringPopulation = new List<SolutionSet>(PopulationSizeParameter.Value.Value * 2); 248 249 for(int i = 0; i < populationSize; i++) { 250 // Obtain parents. Two parameters are required: the population and the 251 // index of the current individual 252 parent = selection(population, i); 253 254 SolutionSet child; 255 // Crossover. The parameters are the current individual and the index of the array of parents 256 child = reproduction(population[i], parent); 257 258 child.Quality = Problem.Evaluate(child.Population, _random); 259 260 this.updateProgres(); 261 262 //the test function is constrained 263 if(child.Quality.Length > Problem.Objectives) { 264 child.OverallConstrainViolation = child.Quality[Problem.Objectives]; 265 } else { 266 child.OverallConstrainViolation = 0; 267 } 268 269 // Dominance test 270 int result; 271 result = compareDomination(population[i], child); 272 273 if(result == -1) { // Solution i dominates child 274 offspringPopulation.Add(population[i]); 275 } else if(result == 1) { // child dominates 276 offspringPopulation.Add(child); 277 } else { // the two solutions are non-dominated 278 offspringPopulation.Add(child); 279 offspringPopulation.Add(population[i]); 280 } 281 } 282 283 // Ranking the offspring population 284 List<SolutionSet>[] ranking = computeRanking(offspringPopulation); 285 population = crowdingDistanceSelection(ranking); 286 generations++; 287 ResultsGenerations = generations; 288 displayResults(population); 289 } 290 } 291 292 public override bool SupportsPause { get { return false; } } // XXX does it actually support pause? 293 294 private void displayResults(List<SolutionSet> population) { 295 List<SolutionSet>[] rankingFinal = computeRanking(population); 296 297 int objectives = Problem.Objectives; 298 var optimalfront = Problem.TestFunction.OptimalParetoFront(objectives); 299 300 double[][] opf = new double[0][]; 301 if(optimalfront != null) { 302 opf = optimalfront.Select(s => s.ToArray()).ToArray(); 303 } 304 305 //compute the final qualities and population 306 double[][] qualitiesFinal = new double[rankingFinal[0].Count][]; 307 double[][] populationFinal = new double[rankingFinal[0].Count][]; 308 309 for(int i = 0; i < rankingFinal[0].Count; ++i) { 310 qualitiesFinal[i] = new double[Problem.Objectives]; 311 populationFinal[i] = new double[Problem.Objectives]; 312 for(int j = 0; j < Problem.Objectives; ++j) { 313 populationFinal[i][j] = rankingFinal[0][i].Population[j]; 314 qualitiesFinal[i][j] = rankingFinal[0][i].Quality[j]; 315 } 316 } 317 IEnumerable<double[]> en = qualitiesFinal; 318 IEnumerable<double[]> frontVectors = NonDominatedSelect.selectNonDominatedVectors(qualitiesFinal, Problem.TestFunction.Maximization(objectives), true); 319 //update the results 320 321 ResultsEvaluations = this.evals; 322 ResultsBestFront = new DoubleMatrix(MultiObjectiveTestFunctionProblem.To2D(qualitiesFinal)); 323 ResultsCrowding = Crowding.Calculate(qualitiesFinal, Problem.TestFunction.Bounds(objectives)); 324 GenerationalDistanceCalculator distance = new GenerationalDistanceCalculator(); 325 ResultsInvertedGenerationalDistance = distance.CalculateGenerationalDistance(qualitiesFinal, opf, Problem.Objectives); 326 ResultsHypervolume = Hypervolume.Calculate(frontVectors, Problem.TestFunction.ReferencePoint(objectives), Problem.TestFunction.Maximization(objectives)); 327 ResultsGenerationalDistance = GenerationalDistance.Calculate(qualitiesFinal, optimalfront, 1); 328 Results["Scatterplot"].Value = new MOSolution(qualitiesFinal, populationFinal, opf, objectives); 329 ResultsSpacing = Spacing.Calculate(qualitiesFinal); 330 331 if(ResultsIGDBest > ResultsInvertedGenerationalDistance) { 332 ResultsIGDBest = ResultsInvertedGenerationalDistance; 333 } 334 if(ResultsIGDWorst < ResultsInvertedGenerationalDistance) { 335 ResultsIGDWorst = ResultsInvertedGenerationalDistance; 336 } 337 this.IGDSumm += ResultsInvertedGenerationalDistance; 338 ResultsIGDMean = this.IGDSumm / ResultsGenerations; 339 } 340 341 private int getWorstIndex(List<SolutionSet> SolutionsList) { 342 int result = 0; 343 344 if((SolutionsList == null) || SolutionsList.Count == 0) { 345 result = 0; 346 } else { 347 SolutionSet worstKnown = SolutionsList[0], 348 candidateSolution; 349 int flag; 350 for(int i = 1; i < SolutionsList.Count; i++) { 351 candidateSolution = SolutionsList[i]; 352 flag = compareDomination(worstKnown, candidateSolution); 353 if(flag == -1) { 354 result = i; 355 worstKnown = candidateSolution; 356 } 357 } 358 } 359 return result; 360 } 361 362 private SolutionSet createIndividual() { 363 var dim = Problem.ProblemSize; 364 var lb = Problem.Bounds[0, 0]; 365 var ub = Problem.Bounds[0, 1]; 366 var range = ub - lb; 367 var v = new double[Problem.ProblemSize]; 368 SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value); 369 370 for(int i = 0; i < Problem.ProblemSize; ++i) { 371 v[i] = _random.NextDouble() * range + lb; 372 373 } 374 solutionObject.createSolution(v); 375 return solutionObject; 376 } 377 378 private SolutionSet createEmptyIndividual() { 379 SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value); 380 var n = new RealVector(Problem.ProblemSize); 381 solutionObject.Population = n; 382 return solutionObject; 383 } 384 385 private void initProgress() { 386 this.evals = PopulationSizeParameter.Value.Value; 387 } 388 389 private void updateProgres() { 390 this.evals++; 391 } 392 393 private SolutionSet[] selection(List<SolutionSet> population, int i) { 394 SolutionSet[] parents = new SolutionSet[3]; 395 int r0, r1, r2; 396 //assure the selected vectors r0, r1 and r2 are different 397 do { 398 r0 = _random.Next(0, PopulationSizeParameter.Value.Value); 399 } while(r0 == i); 400 do { 401 r1 = _random.Next(0, PopulationSizeParameter.Value.Value); 402 } while(r1 == i || r1 == r0); 403 do { 404 r2 = _random.Next(0, PopulationSizeParameter.Value.Value); 405 } while(r2 == i || r2 == r0 || r2 == r1); 406 407 parents[0] = population[r0]; 408 parents[1] = population[r1]; 409 parents[2] = population[r2]; 410 411 return parents; 412 } 413 414 private SolutionSet reproduction(SolutionSet parent, SolutionSet[] parentsSolutions) { 415 var individual = createEmptyIndividual(); 416 double rnbr = _random.Next(0, Problem.ProblemSize); 417 for(int m = 0; m < Problem.ProblemSize; m++) { 418 if(_random.NextDouble() < CrossoverProbabilityParameter.Value.Value || m == rnbr) { 419 double value; 420 value = parentsSolutions[2].Population[m] + 421 ScalingFactorParameter.Value.Value * (parentsSolutions[0].Population[m] - parentsSolutions[1].Population[m]); 422 //check the problem upper and lower bounds 423 if(value > Problem.Bounds[0, 1]) value = Problem.Bounds[0, 1]; 424 if(value < Problem.Bounds[0, 0]) value = Problem.Bounds[0, 0]; 425 individual.Population[m] = value; 426 } else { 427 double value; 428 value = parent.Population[m]; 429 individual.Population[m] = value; 430 } 431 } 432 return individual; 433 } 434 435 private List<SolutionSet> crowdingDistanceSelection(List<SolutionSet>[] ranking) { 436 List<SolutionSet> population = new List<SolutionSet>(); 437 int rankingIndex = 0; 438 while(populationIsNotFull(population)) { 439 if(subFrontFillsIntoThePopulation(ranking, rankingIndex, population)) { 440 addRankedSolutionToPopulation(ranking, rankingIndex, population); 441 rankingIndex++; 442 } else { 443 crowdingDistanceAssignment(ranking[rankingIndex]); 444 addLastRankedSolutionToPopulation(ranking, rankingIndex, population); 445 } 446 } 447 return population; 448 } 449 450 private void addLastRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population) { 451 List<SolutionSet> currentRankedFront = ranking[rankingIndex]; 452 //descending sort and add the front with highest crowding distance to the population 453 currentRankedFront.Sort((x, y) => -x.CrowdingDistance.CompareTo(y.CrowdingDistance)); 454 int i = 0; 455 while(population.Count < PopulationSizeParameter.Value.Value) { 456 population.Add(currentRankedFront[i]); 457 i++; 458 } 459 } 460 461 private void crowdingDistanceAssignment(List<SolutionSet> rankingSubfront) { 462 int size = rankingSubfront.Count; 463 464 if(size == 0) 465 return; 466 467 if(size == 1) { 468 rankingSubfront[0].CrowdingDistance = double.PositiveInfinity; 469 return; 470 } 471 472 if(size == 2) { 473 rankingSubfront[0].CrowdingDistance = double.PositiveInfinity; 474 rankingSubfront[1].CrowdingDistance = double.PositiveInfinity; 475 return; 476 } 477 478 //Use a new SolutionSet to evite alter original solutionSet 479 List<SolutionSet> front = new List<SolutionSet>(size); 480 for(int i = 0; i < size; i++) { 481 front.Add(rankingSubfront[i]); 482 } 483 484 for(int i = 0; i < size; i++) 485 front[i].CrowdingDistance = 0.0; 486 487 double objetiveMaxn; 488 double objetiveMinn; 489 double distance; 490 491 for(int i = 0; i < Problem.Objectives; i++) { 492 // Sort the front population by the objective i 493 front.Sort((x, y) => x.Quality[i].CompareTo(y.Quality[i])); 494 objetiveMinn = front[0].Quality[i]; 495 objetiveMaxn = front[front.Count - 1].Quality[i]; 496 497 //Set crowding distance for the current front 498 front[0].CrowdingDistance = double.PositiveInfinity; 499 front[size - 1].CrowdingDistance = double.PositiveInfinity; 500 501 for(int j = 1; j < size - 1; j++) { 502 distance = front[j + 1].Quality[i] - front[j - 1].Quality[i]; 503 distance = distance / (objetiveMaxn - objetiveMinn); 504 distance += front[j].CrowdingDistance; 505 front[j].CrowdingDistance = distance; 506 } 507 } 508 } 509 510 private void addRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population) { 511 foreach(SolutionSet solution in ranking[rankingIndex]) { 512 population.Add(solution); 513 } 514 } 515 516 private bool subFrontFillsIntoThePopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population) { 517 return ranking[rankingIndex].Count < (PopulationSizeParameter.Value.Value - population.Count); 518 } 519 520 private bool populationIsNotFull(List<SolutionSet> population) { 521 return population.Count < PopulationSizeParameter.Value.Value; 522 } 523 524 private List<SolutionSet>[] computeRanking(List<SolutionSet> tmpList) { 525 // dominateMe[i] contains the number of solutions dominating i 526 int[] dominateMe = new int[tmpList.Count]; 527 528 // iDominate[k] contains the list of solutions dominated by k 529 List<int>[] iDominate = new List<int>[tmpList.Count]; 530 531 // front[i] contains the list of individuals belonging to the front i 532 List<int>[] front = new List<int>[tmpList.Count + 1]; 533 534 // flagDominate is an auxiliar encodings.variable 535 int flagDominate; 536 537 // Initialize the fronts 538 for(int i = 0; i < front.Length; i++) { 539 front[i] = new List<int>(); 540 } 541 542 //-> Fast non dominated sorting algorithm 543 // Contribution of Guillaume Jacquenot 544 for(int p = 0; p < tmpList.Count; p++) { 545 // Initialize the list of individuals that i dominate and the number 546 // of individuals that dominate me 547 iDominate[p] = new List<int>(); 548 dominateMe[p] = 0; 549 } 550 for(int p = 0; p < (tmpList.Count - 1); p++) { 551 // For all q individuals , calculate if p dominates q or vice versa 552 for(int q = p + 1; q < tmpList.Count; q++) { 553 flagDominate = compareConstraintsViolation(tmpList[p], tmpList[q]); 554 if(flagDominate == 0) { 555 flagDominate = compareDomination(tmpList[p], tmpList[q]); 556 } 557 if(flagDominate == -1) { 558 iDominate[p].Add(q); 559 dominateMe[q]++; 560 } else if(flagDominate == 1) { 561 iDominate[q].Add(p); 562 dominateMe[p]++; 563 } 564 } 565 // If nobody dominates p, p belongs to the first front 566 } 567 for(int i = 0; i < tmpList.Count; i++) { 568 if(dominateMe[i] == 0) { 569 front[0].Add(i); 570 tmpList[i].Rank = 0; 571 } 572 } 573 574 //Obtain the rest of fronts 575 int k = 0; 576 577 while(front[k].Count != 0) { 578 k++; 579 foreach(var it1 in front[k - 1]) { 580 foreach(var it2 in iDominate[it1]) { 581 int index = it2; 582 dominateMe[index]--; 583 if(dominateMe[index] == 0) { 584 front[k].Add(index); 585 tmpList[index].Rank = k; 65 586 } 66 } 67 68 private readonly IRandom _random = new MersenneTwister(); 69 private int evals; 70 private double IGDSumm; 71 72 #region ParameterNames 73 private const string MaximumGenerationsParameterName = "Maximum Generations"; 74 private const string MaximumEvaluationsParameterName = "Maximum Evaluations"; 75 private const string CrossoverProbabilityParameterName = "CrossoverProbability"; 76 private const string PopulationSizeParameterName = "PopulationSize"; 77 private const string ScalingFactorParameterName = "ScalingFactor"; 78 79 #endregion 80 81 #region ParameterProperties 82 public IFixedValueParameter<IntValue> MaximumGenerationsParameter 83 { 84 get { return (IFixedValueParameter<IntValue>)Parameters[MaximumGenerationsParameterName]; } 85 } 86 public IFixedValueParameter<IntValue> MaximumEvaluationsParameter 87 { 88 get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluationsParameterName]; } 89 } 90 private ValueParameter<IntValue> PopulationSizeParameter 91 { 92 get { return (ValueParameter<IntValue>)Parameters[PopulationSizeParameterName]; } 93 } 94 public ValueParameter<DoubleValue> CrossoverProbabilityParameter 95 { 96 get { return (ValueParameter<DoubleValue>)Parameters[CrossoverProbabilityParameterName]; } 97 } 98 public ValueParameter<DoubleValue> ScalingFactorParameter 99 { 100 get { return (ValueParameter<DoubleValue>)Parameters[ScalingFactorParameterName]; } 101 } 102 #endregion 103 104 #region Properties 105 public int MaximumGenerations 106 { 107 get { return MaximumGenerationsParameter.Value.Value; } 108 set { MaximumGenerationsParameter.Value.Value = value; } 109 } 110 111 public int MaximumEvaluations 112 { 113 get { return MaximumEvaluationsParameter.Value.Value; } 114 set { MaximumEvaluationsParameter.Value.Value = value; } 115 } 116 117 public Double CrossoverProbability 118 { 119 get { return CrossoverProbabilityParameter.Value.Value; } 120 set { CrossoverProbabilityParameter.Value.Value = value; } 121 } 122 public Double ScalingFactor 123 { 124 get { return ScalingFactorParameter.Value.Value; } 125 set { ScalingFactorParameter.Value.Value = value; } 126 } 127 public IntValue PopulationSize 128 { 129 get { return PopulationSizeParameter.Value; } 130 set { PopulationSizeParameter.Value = value; } 131 } 132 #endregion 133 134 #region ResultsProperties 135 private double ResultsBestQuality 136 { 137 get { return ((DoubleValue)Results["Best Quality"].Value).Value; } 138 set { ((DoubleValue)Results["Best Quality"].Value).Value = value; } 139 } 140 141 private double ResultsIGDMean 142 { 143 get { return ((DoubleValue)Results["IGDMeanValue"].Value).Value; } 144 set { ((DoubleValue)Results["IGDMeanValue"].Value).Value = value; } 145 } 146 147 private double ResultsIGDBest 148 { 149 get { return ((DoubleValue)Results["IGDBestValue"].Value).Value; } 150 set { ((DoubleValue)Results["IGDBestValue"].Value).Value = value; } 151 } 152 153 private double ResultsIGDWorst 154 { 155 get { return ((DoubleValue)Results["IGDWorstValue"].Value).Value; } 156 set { ((DoubleValue)Results["IGDWorstValue"].Value).Value = value; } 157 } 158 159 private double ResultsInvertedGenerationalDistance 160 { 161 get { return ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value; } 162 set { ((DoubleValue)Results["InvertedGenerationalDistance"].Value).Value = value; } 163 } 164 165 private double ResultsHypervolume 166 { 167 get { return ((DoubleValue)Results["HyperVolumeValue"].Value).Value; } 168 set { ((DoubleValue)Results["HyperVolumeValue"].Value).Value = value; } 169 } 170 171 private DoubleMatrix ResultsBestFront 172 { 173 get { return (DoubleMatrix)Results["Best Front"].Value; } 174 set { Results["Best Front"].Value = value; } 175 } 176 177 private int ResultsEvaluations 178 { 179 get { return ((IntValue)Results["Evaluations"].Value).Value; } 180 set { ((IntValue)Results["Evaluations"].Value).Value = value; } 181 } 182 private int ResultsGenerations 183 { 184 get { return ((IntValue)Results["Generations"].Value).Value; } 185 set { ((IntValue)Results["Generations"].Value).Value = value; } 186 } 187 private double ResultsGenerationalDistance 188 { 189 get { return ((DoubleValue)Results["GenerationalDistance"].Value).Value; } 190 set { ((DoubleValue)Results["GenerationalDistance"].Value).Value = value; } 191 } 192 193 private double ResultsSpacing 194 { 195 get { return ((DoubleValue)Results["Spacing"].Value).Value; } 196 set { ((DoubleValue)Results["Spacing"].Value).Value = value; } 197 } 198 199 private double ResultsCrowding 200 { 201 get { return ((DoubleValue)Results["Crowding"].Value).Value; } 202 set { ((DoubleValue)Results["Crowding"].Value).Value = value; } 203 } 204 205 #endregion 206 207 [StorableConstructor] 208 protected GDE3(bool deserializing) : base(deserializing) { } 209 210 protected GDE3(GDE3 original, Cloner cloner) 211 : base(original, cloner) 212 { 213 } 214 215 public override IDeepCloneable Clone(Cloner cloner) 216 { 217 return new GDE3(this, cloner); 218 } 219 220 public GDE3() 221 { 222 Parameters.Add(new FixedValueParameter<IntValue>(MaximumGenerationsParameterName, "", new IntValue(1000))); 223 Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(Int32.MaxValue))); 224 Parameters.Add(new ValueParameter<IntValue>(PopulationSizeParameterName, "The size of the population of solutions.", new IntValue(100))); 225 Parameters.Add(new ValueParameter<DoubleValue>(CrossoverProbabilityParameterName, "The value for crossover rate", new DoubleValue(0.5))); 226 Parameters.Add(new ValueParameter<DoubleValue>(ScalingFactorParameterName, "The value for scaling factor", new DoubleValue(0.5))); 227 Parameters.Add(new LookupParameter<DoubleMatrix>("BestKnownFront", "The currently best known Pareto front")); 228 } 229 230 protected override void Run(CancellationToken cancellationToken) 231 { 232 // Set up the results display 233 Results.Add(new Result("Generations", new IntValue(0))); 234 Results.Add(new Result("Evaluations", new IntValue(0))); 235 Results.Add(new Result("Best Front", new DoubleMatrix())); 236 Results.Add(new Result("Crowding", new DoubleValue(0))); 237 Results.Add(new Result("InvertedGenerationalDistance", new DoubleValue(0))); 238 Results.Add(new Result("GenerationalDistance", new DoubleValue(0))); 239 Results.Add(new Result("HyperVolumeValue", new DoubleValue(0))); 240 Results.Add(new Result("IGDMeanValue", new DoubleValue(0))); 241 Results.Add(new Result("IGDBestValue", new DoubleValue(Int32.MaxValue))); 242 Results.Add(new Result("IGDWorstValue", new DoubleValue(0))); 243 244 Results.Add(new Result("Spacing", new DoubleValue(0))); 245 Results.Add(new Result("Scatterplot", typeof(IMOFrontModel))); 246 var table = new DataTable("Qualities"); 247 table.Rows.Add(new DataRow("Best Quality")); 248 Results.Add(new Result("Qualities", table)); 249 250 //setup the variables 251 List<SolutionSet> population; 252 List<SolutionSet> offspringPopulation; 253 SolutionSet[] parent; 254 double IGDSumm = 0; 255 256 //initialize population 257 population = new List<SolutionSet>(PopulationSizeParameter.Value.Value); 258 259 for (int i = 0; i < PopulationSizeParameter.Value.Value; ++i) 260 { 261 var m = createIndividual(); 262 m.Quality = Problem.Evaluate(m.Population, _random); 263 //the test function is constrained 264 if (m.Quality.Length > Problem.Objectives) 265 { 266 m.OverallConstrainViolation = m.Quality[Problem.Objectives]; 267 } else { 268 m.OverallConstrainViolation = 0; 269 } 270 population.Add(m); 271 } 272 273 this.initProgress(); 274 int generations = 1; 275 276 while (ResultsEvaluations < MaximumEvaluationsParameter.Value.Value 277 && !cancellationToken.IsCancellationRequested) 278 { 279 var populationSize = PopulationSizeParameter.Value.Value; 280 281 // Create the offSpring solutionSet 282 offspringPopulation = new List<SolutionSet>(PopulationSizeParameter.Value.Value * 2); 283 284 for (int i = 0; i < populationSize; i++) 285 { 286 // Obtain parents. Two parameters are required: the population and the 287 // index of the current individual 288 parent = selection(population, i); 289 290 SolutionSet child; 291 // Crossover. The parameters are the current individual and the index of the array of parents 292 child = reproduction(population[i], parent); 293 294 child.Quality = Problem.Evaluate(child.Population, _random); 295 296 this.updateProgres(); 297 298 //the test function is constrained 299 if (child.Quality.Length > Problem.Objectives) 300 { 301 child.OverallConstrainViolation = child.Quality[Problem.Objectives]; 302 } else { 303 child.OverallConstrainViolation = 0; 304 } 305 306 // Dominance test 307 int result; 308 result = compareDomination(population[i], child); 309 310 if (result == -1) 311 { // Solution i dominates child 312 offspringPopulation.Add(population[i]); 313 } 314 else if (result == 1) 315 { // child dominates 316 offspringPopulation.Add(child); 317 } 318 else 319 { // the two solutions are non-dominated 320 offspringPopulation.Add(child); 321 offspringPopulation.Add(population[i]); 322 } 323 } 324 325 // Ranking the offspring population 326 List<SolutionSet>[] ranking = computeRanking(offspringPopulation); 327 population = crowdingDistanceSelection(ranking); 328 generations++; 329 ResultsGenerations = generations; 330 displayResults(population); 331 } 332 } 333 334 private void displayResults(List<SolutionSet> population) 335 { 336 List<SolutionSet>[] rankingFinal = computeRanking(population); 337 338 int objectives = Problem.Objectives; 339 var optimalfront = Problem.TestFunction.OptimalParetoFront(objectives); 340 341 double[][] opf = new double[0][]; 342 if (optimalfront != null) 343 { 344 opf = optimalfront.Select(s => s.ToArray()).ToArray(); 345 } 346 347 //compute the final qualities and population 348 double[][] qualitiesFinal = new double[rankingFinal[0].Count][]; 349 double[][] populationFinal = new double[rankingFinal[0].Count][]; 350 351 for (int i = 0; i < rankingFinal[0].Count; ++i) 352 { 353 qualitiesFinal[i] = new double[Problem.Objectives]; 354 populationFinal[i] = new double[Problem.Objectives]; 355 for (int j = 0; j < Problem.Objectives; ++j) 356 { 357 populationFinal[i][j] = rankingFinal[0][i].Population[j]; 358 qualitiesFinal[i][j] = rankingFinal[0][i].Quality[j]; 359 } 360 } 361 IEnumerable<double[]> en = qualitiesFinal; 362 IEnumerable<double[]> frontVectors = NonDominatedSelect.selectNonDominatedVectors(qualitiesFinal, Problem.TestFunction.Maximization(objectives), true); 363 //update the results 364 365 ResultsEvaluations = this.evals; 366 ResultsBestFront = new DoubleMatrix(MultiObjectiveTestFunctionProblem.To2D(qualitiesFinal)); 367 ResultsCrowding = Crowding.Calculate(qualitiesFinal, Problem.TestFunction.Bounds(objectives)); 368 GenerationalDistanceCalculator distance = new GenerationalDistanceCalculator(); 369 ResultsInvertedGenerationalDistance = distance.CalculateGenerationalDistance(qualitiesFinal, opf, Problem.Objectives); 370 ResultsHypervolume = Hypervolume.Calculate(frontVectors, Problem.TestFunction.ReferencePoint(objectives), Problem.TestFunction.Maximization(objectives)); 371 ResultsGenerationalDistance = GenerationalDistance.Calculate(qualitiesFinal, optimalfront, 1); 372 Results["Scatterplot"].Value = new MOSolution(qualitiesFinal, populationFinal, opf, objectives); 373 ResultsSpacing = Spacing.Calculate(qualitiesFinal); 374 375 if (ResultsIGDBest > ResultsInvertedGenerationalDistance) { 376 ResultsIGDBest = ResultsInvertedGenerationalDistance; 377 } 378 if (ResultsIGDWorst < ResultsInvertedGenerationalDistance) 379 { 380 ResultsIGDWorst = ResultsInvertedGenerationalDistance; 381 } 382 this.IGDSumm += ResultsInvertedGenerationalDistance; 383 ResultsIGDMean = this.IGDSumm / ResultsGenerations; 384 } 385 386 private int getWorstIndex(List<SolutionSet> SolutionsList) 387 { 388 int result = 0; 389 390 if ((SolutionsList == null) || SolutionsList.Count == 0) 391 { 392 result = 0; 393 } 394 else 395 { 396 SolutionSet worstKnown = SolutionsList[0], 397 candidateSolution; 398 int flag; 399 for (int i = 1; i < SolutionsList.Count; i++) 400 { 401 candidateSolution = SolutionsList[i]; 402 flag = compareDomination(worstKnown, candidateSolution); 403 if (flag == -1) 404 { 405 result = i; 406 worstKnown = candidateSolution; 407 } 408 } 409 } 410 return result; 411 } 412 413 private SolutionSet createIndividual() 414 { 415 var dim = Problem.ProblemSize; 416 var lb = Problem.Bounds[0, 0]; 417 var ub = Problem.Bounds[0, 1]; 418 var range = ub - lb; 419 var v = new double[Problem.ProblemSize]; 420 SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value); 421 422 for (int i = 0; i < Problem.ProblemSize; ++i) 423 { 424 v[i] = _random.NextDouble() * range + lb; 425 426 } 427 solutionObject.createSolution(v); 428 return solutionObject; 429 } 430 431 private SolutionSet createEmptyIndividual() 432 { 433 SolutionSet solutionObject = new SolutionSet(PopulationSizeParameter.Value.Value); 434 var n = new RealVector(Problem.ProblemSize); 435 solutionObject.Population = n; 436 return solutionObject; 437 } 438 439 private void initProgress() 440 { 441 this.evals = PopulationSizeParameter.Value.Value; 442 } 443 444 private void updateProgres() 445 { 446 this.evals++; 447 } 448 449 private SolutionSet[] selection(List<SolutionSet> population, int i) 450 { 451 SolutionSet[] parents = new SolutionSet[3]; 452 int r0, r1, r2; 453 //assure the selected vectors r0, r1 and r2 are different 454 do 455 { 456 r0 = _random.Next(0, PopulationSizeParameter.Value.Value); 457 } while (r0 == i); 458 do 459 { 460 r1 = _random.Next(0, PopulationSizeParameter.Value.Value); 461 } while (r1 == i || r1 == r0); 462 do 463 { 464 r2 = _random.Next(0, PopulationSizeParameter.Value.Value); 465 } while (r2 == i || r2 == r0 || r2 == r1); 466 467 parents[0] = population[r0]; 468 parents[1] = population[r1]; 469 parents[2] = population[r2]; 470 471 return parents; 472 } 473 474 private SolutionSet reproduction(SolutionSet parent, SolutionSet[] parentsSolutions) 475 { 476 var individual = createEmptyIndividual(); 477 double rnbr = _random.Next(0, Problem.ProblemSize); 478 for (int m = 0; m < Problem.ProblemSize; m++) 479 { 480 if (_random.NextDouble() < CrossoverProbabilityParameter.Value.Value || m == rnbr) 481 { 482 double value; 483 value = parentsSolutions[2].Population[m] + 484 ScalingFactorParameter.Value.Value * (parentsSolutions[0].Population[m] - parentsSolutions[1].Population[m]); 485 //check the problem upper and lower bounds 486 if (value > Problem.Bounds[0, 1]) value = Problem.Bounds[0, 1]; 487 if (value < Problem.Bounds[0, 0]) value = Problem.Bounds[0, 0]; 488 individual.Population[m] = value; 489 } 490 else 491 { 492 double value; 493 value = parent.Population[m]; 494 individual.Population[m] = value; 495 } 496 } 497 return individual; 498 } 499 500 private List<SolutionSet> crowdingDistanceSelection(List<SolutionSet>[] ranking) 501 { 502 List<SolutionSet> population = new List<SolutionSet>(); 503 int rankingIndex = 0; 504 while (populationIsNotFull(population)) 505 { 506 if (subFrontFillsIntoThePopulation(ranking, rankingIndex, population)) 507 { 508 addRankedSolutionToPopulation(ranking, rankingIndex, population); 509 rankingIndex++; 510 } 511 else { 512 crowdingDistanceAssignment(ranking[rankingIndex]); 513 addLastRankedSolutionToPopulation(ranking, rankingIndex, population); 514 } 515 } 516 return population; 517 } 518 519 private void addLastRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population) 520 { 521 List<SolutionSet> currentRankedFront = ranking[rankingIndex]; 522 //descending sort and add the front with highest crowding distance to the population 523 currentRankedFront.Sort((x, y) => -x.CrowdingDistance.CompareTo(y.CrowdingDistance)); 524 int i = 0; 525 while (population.Count < PopulationSizeParameter.Value.Value) 526 { 527 population.Add(currentRankedFront[i]); 528 i++; 529 } 530 } 531 532 private void crowdingDistanceAssignment(List<SolutionSet> rankingSubfront) 533 { 534 int size = rankingSubfront.Count; 535 536 if (size == 0) 537 return; 538 539 if (size == 1) 540 { 541 rankingSubfront[0].CrowdingDistance = double.PositiveInfinity; 542 return; 543 } 544 545 if (size == 2) 546 { 547 rankingSubfront[0].CrowdingDistance = double.PositiveInfinity; 548 rankingSubfront[1].CrowdingDistance = double.PositiveInfinity; 549 return; 550 } 551 552 //Use a new SolutionSet to evite alter original solutionSet 553 List<SolutionSet> front = new List<SolutionSet>(size); 554 for (int i = 0; i < size; i++) 555 { 556 front.Add(rankingSubfront[i]); 557 } 558 559 for (int i = 0; i < size; i++) 560 front[i].CrowdingDistance = 0.0; 561 562 double objetiveMaxn; 563 double objetiveMinn; 564 double distance; 565 566 for (int i = 0; i < Problem.Objectives; i++) 567 { 568 // Sort the front population by the objective i 569 front.Sort((x, y) => x.Quality[i].CompareTo(y.Quality[i])); 570 objetiveMinn = front[0].Quality[i]; 571 objetiveMaxn = front[front.Count - 1].Quality[i]; 572 573 //Set crowding distance for the current front 574 front[0].CrowdingDistance = double.PositiveInfinity; 575 front[size - 1].CrowdingDistance = double.PositiveInfinity; 576 577 for (int j = 1; j < size - 1; j++) 578 { 579 distance = front[j + 1].Quality[i] - front[j - 1].Quality[i]; 580 distance = distance / (objetiveMaxn - objetiveMinn); 581 distance += front[j].CrowdingDistance; 582 front[j].CrowdingDistance = distance; 583 } 584 } 585 } 586 587 private void addRankedSolutionToPopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population) 588 { 589 foreach (SolutionSet solution in ranking[rankingIndex]) 590 { 591 population.Add(solution); 592 } 593 } 594 595 private bool subFrontFillsIntoThePopulation(List<SolutionSet>[] ranking, int rankingIndex, List<SolutionSet> population) 596 { 597 return ranking[rankingIndex].Count < (PopulationSizeParameter.Value.Value - population.Count); 598 } 599 600 private bool populationIsNotFull(List<SolutionSet> population) 601 { 602 return population.Count < PopulationSizeParameter.Value.Value; 603 } 604 605 private List<SolutionSet>[] computeRanking(List<SolutionSet> tmpList) 606 { 607 // dominateMe[i] contains the number of solutions dominating i 608 int[] dominateMe = new int[tmpList.Count]; 609 610 // iDominate[k] contains the list of solutions dominated by k 611 List<int>[] iDominate = new List<int>[tmpList.Count]; 612 613 // front[i] contains the list of individuals belonging to the front i 614 List<int>[] front = new List<int>[tmpList.Count + 1]; 615 616 // flagDominate is an auxiliar encodings.variable 617 int flagDominate; 618 619 // Initialize the fronts 620 for (int i = 0; i < front.Length; i++) 621 { 622 front[i] = new List<int>(); 623 } 624 625 //-> Fast non dominated sorting algorithm 626 // Contribution of Guillaume Jacquenot 627 for (int p = 0; p < tmpList.Count; p++) 628 { 629 // Initialize the list of individuals that i dominate and the number 630 // of individuals that dominate me 631 iDominate[p] = new List<int>(); 632 dominateMe[p] = 0; 633 } 634 for (int p = 0; p < (tmpList.Count - 1); p++) 635 { 636 // For all q individuals , calculate if p dominates q or vice versa 637 for (int q = p + 1; q < tmpList.Count; q++) 638 { 639 flagDominate = compareConstraintsViolation(tmpList[p], tmpList[q]); 640 if (flagDominate == 0) { 641 flagDominate = compareDomination(tmpList[p], tmpList[q]); 642 } 643 if (flagDominate == -1) 644 { 645 iDominate[p].Add(q); 646 dominateMe[q]++; 647 } 648 else if (flagDominate == 1) 649 { 650 iDominate[q].Add(p); 651 dominateMe[p]++; 652 } 653 } 654 // If nobody dominates p, p belongs to the first front 655 } 656 for (int i = 0; i < tmpList.Count; i++) 657 { 658 if (dominateMe[i] == 0) 659 { 660 front[0].Add(i); 661 tmpList[i].Rank = 0; 662 } 663 } 664 665 //Obtain the rest of fronts 666 int k = 0; 667 668 while (front[k].Count != 0) 669 { 670 k++; 671 foreach (var it1 in front[k - 1]) 672 { 673 foreach (var it2 in iDominate[it1]) 674 { 675 int index = it2; 676 dominateMe[index]--; 677 if (dominateMe[index] == 0) 678 { 679 front[k].Add(index); 680 tmpList[index].Rank = k; 681 } 682 } 683 } 684 } 685 //<- 686 687 var rankedSubpopulation = new List<SolutionSet>[k]; 688 //0,1,2,....,i-1 are front, then i fronts 689 for (int j = 0; j < k; j++) 690 { 691 rankedSubpopulation[j] = new List<SolutionSet>(front[j].Count); 692 foreach (var it1 in front[j]) 693 { 694 rankedSubpopulation[j].Add(tmpList[it1]); 695 } 696 } 697 return rankedSubpopulation; 698 } 699 700 private int compareDomination(SolutionSet solution1, SolutionSet solution2) 701 { 702 int dominate1; // dominate1 indicates if some objective of solution1 703 // dominates the same objective in solution2. dominate2 704 int dominate2; // is the complementary of dominate1. 705 706 dominate1 = 0; 707 dominate2 = 0; 708 709 int flag; //stores the result of the comparison 710 711 // Test to determine whether at least a solution violates some constraint 712 if (needToCompareViolations(solution1, solution2)) 713 { 714 return compareConstraintsViolation(solution1, solution2); 715 } 716 717 // Equal number of violated constraints. Applying a dominance Test then 718 double value1, value2; 719 for (int i = 0; i < Problem.Objectives; i++) 720 { 721 value1 = solution1.Quality[i]; 722 value2 = solution2.Quality[i]; 723 if (value1 < value2) 724 { 725 flag = -1; 726 } 727 else if (value2 < value1) 728 { 729 flag = 1; 730 } 731 else 732 { 733 flag = 0; 734 } 735 736 if (flag == -1) 737 { 738 dominate1 = 1; 739 } 740 741 if (flag == 1) 742 { 743 dominate2 = 1; 744 } 745 } 746 747 if (dominate1 == dominate2) 748 { 749 return 0; //No one dominate the other 750 } 751 if (dominate1 == 1) 752 { 753 return -1; // solution1 dominate 754 } 755 return 1; // solution2 dominate 756 } 757 758 private bool needToCompareViolations(SolutionSet solution1, SolutionSet solution2) 759 { 760 bool needToCompare; 761 needToCompare = (solution1.OverallConstrainViolation < 0) || (solution2.OverallConstrainViolation < 0); 762 763 return needToCompare; 764 } 765 766 private int compareConstraintsViolation(SolutionSet solution1, SolutionSet solution2) 767 { 768 int result; 769 double overall1, overall2; 770 overall1 = solution1.OverallConstrainViolation; 771 overall2 = solution2.OverallConstrainViolation; 772 773 if ((overall1 < 0) && (overall2 < 0)) 774 { 775 if (overall1 > overall2) 776 { 777 result = -1; 778 } 779 else if (overall2 > overall1) 780 { 781 result = 1; 782 } 783 else 784 { 785 result = 0; 786 } 787 } 788 else if ((overall1 == 0) && (overall2 < 0)) 789 { 790 result = -1; 791 } 792 else if ((overall1 < 0) && (overall2 == 0)) 793 { 794 result = 1; 795 } 796 else 797 { 798 result = 0; 799 } 800 return result; 801 } 802 } 587 } 588 } 589 } 590 //<- 591 592 var rankedSubpopulation = new List<SolutionSet>[k]; 593 //0,1,2,....,i-1 are front, then i fronts 594 for(int j = 0; j < k; j++) { 595 rankedSubpopulation[j] = new List<SolutionSet>(front[j].Count); 596 foreach(var it1 in front[j]) { 597 rankedSubpopulation[j].Add(tmpList[it1]); 598 } 599 } 600 return rankedSubpopulation; 601 } 602 603 private int compareDomination(SolutionSet solution1, SolutionSet solution2) { 604 int dominate1; // dominate1 indicates if some objective of solution1 605 // dominates the same objective in solution2. dominate2 606 int dominate2; // is the complementary of dominate1. 607 608 dominate1 = 0; 609 dominate2 = 0; 610 611 int flag; //stores the result of the comparison 612 613 // Test to determine whether at least a solution violates some constraint 614 if(needToCompareViolations(solution1, solution2)) { 615 return compareConstraintsViolation(solution1, solution2); 616 } 617 618 // Equal number of violated constraints. Applying a dominance Test then 619 double value1, value2; 620 for(int i = 0; i < Problem.Objectives; i++) { 621 value1 = solution1.Quality[i]; 622 value2 = solution2.Quality[i]; 623 if(value1 < value2) { 624 flag = -1; 625 } else if(value2 < value1) { 626 flag = 1; 627 } else { 628 flag = 0; 629 } 630 631 if(flag == -1) { 632 dominate1 = 1; 633 } 634 635 if(flag == 1) { 636 dominate2 = 1; 637 } 638 } 639 640 if(dominate1 == dominate2) { 641 return 0; //No one dominate the other 642 } 643 if(dominate1 == 1) { 644 return -1; // solution1 dominate 645 } 646 return 1; // solution2 dominate 647 } 648 649 private bool needToCompareViolations(SolutionSet solution1, SolutionSet solution2) { 650 bool needToCompare; 651 needToCompare = (solution1.OverallConstrainViolation < 0) || (solution2.OverallConstrainViolation < 0); 652 653 return needToCompare; 654 } 655 656 private int compareConstraintsViolation(SolutionSet solution1, SolutionSet solution2) { 657 int result; 658 double overall1, overall2; 659 overall1 = solution1.OverallConstrainViolation; 660 overall2 = solution2.OverallConstrainViolation; 661 662 if((overall1 < 0) && (overall2 < 0)) { 663 if(overall1 > overall2) { 664 result = -1; 665 } else if(overall2 > overall1) { 666 result = 1; 667 } else { 668 result = 0; 669 } 670 } else if((overall1 == 0) && (overall2 < 0)) { 671 result = -1; 672 } else if((overall1 < 0) && (overall2 == 0)) { 673 result = 1; 674 } else { 675 result = 0; 676 } 677 return result; 678 } 679 } 803 680 } 804 681 -
branches/ichiriac/HeuristicLab.Algorithms.GDE3/HeuristicLab.Algorithms.GDE3.csproj
r13756 r14705 91 91 <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath> 92 92 </Reference> 93 <Reference Include="HeuristicLab.Problems.MultiObjectiveTestFunctions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">94 <SpecificVersion>False</SpecificVersion>95 <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.MultiObjectiveTestFunctions-3.3.dll</HintPath>96 </Reference>97 93 <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 98 94 <SpecificVersion>False</SpecificVersion>
Note: See TracChangeset
for help on using the changeset viewer.