- Timestamp:
- 07/22/20 12:53:10 (4 years ago)
- Location:
- branches/2825-NSGA3/HeuristicLab.Algorithms.NSGA3/3.3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2825-NSGA3/HeuristicLab.Algorithms.NSGA3/3.3/NSGA3.cs
r17688 r17692 1 1 using System; 2 2 using System.Collections.Generic; 3 using System.Diagnostics;4 3 using System.Linq; 5 4 using System.Threading; … … 179 178 public DoubleValue ResultsGenerationalDistance 180 179 { 181 get { return (DoubleValue)Results[GenerationalDistanceResultName].Value; }180 get { return (DoubleValue)Results[GenerationalDistanceResultName].Value; } 182 181 set { Results[GenerationalDistanceResultName].Value = value; } 183 182 } … … 204 203 Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true))); 205 204 Parameters.Add(new FixedValueParameter<IntValue>(PopulationSizeName, "The size of the population of Individuals.", new IntValue(200))); 206 Parameters.Add(new FixedValueParameter<PercentValue>(CrossoverProbabilityName, "The probability that the crossover operator is applied on two parents.", new PercentValue( 0.9)));205 Parameters.Add(new FixedValueParameter<PercentValue>(CrossoverProbabilityName, "The probability that the crossover operator is applied on two parents.", new PercentValue(1.0))); 207 206 Parameters.Add(new FixedValueParameter<DoubleValue>(CrossoverContiguityName, "The contiguity value for the Simulated Binary Crossover that specifies how close a child should be to its parents (larger value means closer). The value must be greater than or equal than 0. Typical values are in the range [2;5].")); 208 207 Parameters.Add(new FixedValueParameter<PercentValue>(MutationProbabilityName, "The probability that the mutation operator is applied on a Individual.", new PercentValue(0.05))); … … 224 223 random = cloner.Clone(original.random); 225 224 solutions = original.solutions != null ? original.solutions.Select(cloner.Clone).ToList() : null; 226 referencePoints = original.referencePoints != null ? original.referencePoints.Select(r => { 225 referencePoints = original.referencePoints != null ? original.referencePoints.Select(r => 226 { 227 227 var refPoint = new ReferencePoint(random, r.NumberOfDimensions); 228 228 r.Values.CopyTo(refPoint.Values, 0); … … 244 244 base.Initialize(cancellationToken); 245 245 246 // Set population size 246 247 int numberOfGeneratedReferencePoints = ReferencePoint.GetNumberOfGeneratedReferencePoints(NumberOfObjectives); 247 248 int pop = ((numberOfGeneratedReferencePoints + 3) / 4) * 4; 248 249 PopulationSize.Value = pop; 250 251 // Set mutation probability 252 double mutationProbability = 1.0 / Problem.Encoding.Length; 253 MutationProbability.Value = mutationProbability; 254 249 255 InitResults(); 250 256 InitFields(); … … 273 279 InitReferencePoints(); 274 280 } 281 275 282 private void InitReferencePoints() 276 283 { … … 280 287 } 281 288 282 283 289 private void InitSolutions() 284 290 { … … 291 297 { 292 298 RealVector randomRealVector = new RealVector(Problem.Encoding.Length, random, minBound, maxBound); 293 294 solution s.Add(new Solution(randomRealVector));295 solutions [i].Fitness = Evaluate(solutions[i].Chromosome);299 var solution = new Solution(randomRealVector); 300 solution.Fitness = Evaluate(solution.Chromosome); 301 solutions.Add(solution); 296 302 } 297 303 } … … 305 311 while (ResultsCurrentGeneration.Value < MaximumGenerations.Value) 306 312 { 307 308 313 try 309 314 { 310 List<Solution> qt = Mutate(Recombine(solutions)); 315 // todo: make parameter out of this 316 List<Solution> qt = Mutate(Recombine(solutions), 30); 317 foreach (var solution in qt) 318 solution.Fitness = Evaluate(solution.Chromosome); 319 311 320 List<Solution> rt = Utility.Concat(solutions, qt); 312 321 313 // create copies of generated reference points (to preserve the original ones for 314 // the next generation) maybe todo: use cloner? 315 solutions = NSGA3Selection.SelectSolutionsForNextGeneration(rt, GetCopyOfReferencePoints(), Problem.Maximization, random); 322 solutions = NSGA3Selection.SelectSolutionsForNextGeneration(rt, GetCopyOfReferencePoints(), Problem.Maximization, PopulationSize.Value, random); 316 323 317 324 ResultsCurrentGeneration.Value++; 318 325 Analyze(); 326 cancellationToken.ThrowIfCancellationRequested(); 327 } 328 catch (OperationCanceledException ex) 329 { 330 throw new OperationCanceledException("Optimization process was cancelled.", ex); 319 331 } 320 332 catch (Exception ex) 321 333 { 322 throw new Exception($"Failed in generation {ResultsCurrentGeneration}", ex); 334 throw new Exception($"Failed in generation {ResultsCurrentGeneration}.", ex); 335 } 336 finally 337 { 338 Analyze(); 323 339 } 324 340 } … … 384 400 385 401 // Do crossover with crossoverProbabilty == 1 in order to guarantee that a crossover happens 386 var children = SimulatedBinaryCrossover.Apply(random, Problem.Encoding.Bounds, parent1.Chromosome, parent2.Chromosome, 1); 387 Debug.Assert(children != null); 388 389 var child1 = new Solution(children.Item1); 390 var child2 = new Solution(children.Item2); 391 child1.Fitness = Evaluate(child1.Chromosome); 392 child2.Fitness = Evaluate(child1.Chromosome); 393 394 childSolutions.Add(child1); 395 childSolutions.Add(child2); 402 var children = SimulatedBinaryCrossover.Apply(random, 403 Problem.Encoding.Bounds, parent1.Chromosome, parent2.Chromosome, CrossoverProbability.Value); 404 405 childSolutions.Add(new Solution(children.Item1)); 406 childSolutions.Add(new Solution(children.Item2)); 396 407 } 397 408 … … 399 410 } 400 411 401 private List<Solution> Mutate(List<Solution> solutions )412 private List<Solution> Mutate(List<Solution> solutions, double eta) 402 413 { 403 414 foreach (var solution in solutions) 404 415 { 405 UniformOnePositionManipulator.Apply(random, solution.Chromosome, Problem.Encoding.Bounds); 416 for (int i = 0; i < solution.Chromosome.Length; i++) 417 { 418 if (random.NextDouble() > MutationProbability.Value) continue; 419 420 double y = solution.Chromosome[i]; 421 double lb; 422 double ub; 423 var problem = Problem as MultiObjectiveTestFunctionProblem; 424 if (problem.Bounds.Rows == 1) lb = problem.Bounds[0, 0]; 425 else lb = problem.Bounds[i, 0]; 426 if (problem.Bounds.Rows == 1) ub = problem.Bounds[0, 1]; 427 else ub = problem.Bounds[i, 1]; 428 429 double delta1 = (y - lb) / (ub - lb); 430 double delta2 = (ub - y) / (ub - lb); 431 432 double mut_pow = 1.0 / (eta + 1.0); 433 434 double rnd = random.NextDouble(); 435 var deltaq = 0.0; 436 if (rnd <= 0.5) 437 { 438 double xy = 1.0 - delta1; 439 double val = 2.0 * rnd + (1.0 - 2.0 * rnd) * (Math.Pow(xy, (eta + 1.0))); 440 deltaq = Math.Pow(val, mut_pow) - 1.0; 441 } 442 else 443 { 444 double xy = 1.0 - delta2; 445 double val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * (Math.Pow(xy, (eta + 1.0))); 446 deltaq = 1.0 - (Math.Pow(val, mut_pow)); 447 } 448 449 y = y + deltaq * (ub - lb); 450 y = Math.Min(ub, Math.Max(lb, y)); 451 452 solution.Chromosome[i] = y; 453 } 406 454 } 407 455 return solutions; -
branches/2825-NSGA3/HeuristicLab.Algorithms.NSGA3/3.3/NSGA3Selection.cs
r17668 r17692 15 15 /// have the same number of objectives, undefined behavior happens. 16 16 /// </summary> 17 /// <param name="rt"> </param>17 /// <param name="rt">The previous generation and its mutated children.</param> 18 18 /// <param name="referencePoints"></param> 19 19 /// <param name="maximization"></param> 20 /// <param name="N">Number of solutions to select.</param> 21 /// <param name="random">The <see cref="IRandom" /> to use for randomness.</param> 20 22 /// <returns></returns> 21 public static List<Solution> SelectSolutionsForNextGeneration(List<Solution> rt, List<ReferencePoint> referencePoints, bool[] maximization, IRandom random) 22 { 23 int N = rt.Count / 2; // number of solutions in a generation 23 public static List<Solution> SelectSolutionsForNextGeneration(List<Solution> rt, List<ReferencePoint> referencePoints, bool[] maximization, int N, IRandom random) 24 { 24 25 int numberOfObjectives = rt.First().Fitness.Length; 25 26 List<Solution> st = new List<Solution>(); … … 64 65 // Find the ideal point 65 66 double[] idealPoint = new double[numberOfObjectives]; 67 68 foreach (var solution in st) 69 solution.ConvertedFitness = new double[numberOfObjectives]; 70 66 71 for (int j = 0; j < numberOfObjectives; j++) 67 72 { … … 69 74 idealPoint[j] = Utility.Min(s => s.Fitness[j], st); 70 75 71 // Translate objectives 76 // Translate objectives and save the modified fitness values in ConvertedFitness 72 77 foreach (var solution in st) 73 solution. Fitness[j] -=idealPoint[j];78 solution.ConvertedFitness[j] = solution.Fitness[j] - idealPoint[j]; 74 79 } 75 80 … … 83 88 weights[j] = 1; 84 89 85 extremePoints[j] = Utility.ArgMin(s => ASF(s. Fitness, weights), st);90 extremePoints[j] = Utility.ArgMin(s => ASF(s.ConvertedFitness, weights), st); 86 91 } 87 92 … … 103 108 if (Math.Abs(intercepts[i] - idealPoint[i]) > EPSILON) 104 109 { 105 solution. Fitness[i] = solution.Fitness[i] / (intercepts[i] - idealPoint[i]);110 solution.ConvertedFitness[i] = solution.ConvertedFitness[i] / (intercepts[i] - idealPoint[i]); 106 111 } 107 112 else 108 113 { 109 solution. Fitness[i] = solution.Fitness[i] / EPSILON;114 solution.ConvertedFitness[i] = solution.ConvertedFitness[i] / EPSILON; 110 115 } 111 116 } … … 121 126 // find reference point for which the perpendicular distance to the current 122 127 // solution is the lowest 123 var rpAndDist = Utility.MinArgMin(rp => GetPerpendicularDistance(rp.Values, solution. Fitness), referencePoints);128 var rpAndDist = Utility.MinArgMin(rp => GetPerpendicularDistance(rp.Values, solution.ConvertedFitness), referencePoints); 124 129 // associated reference point 125 130 var arp = rpAndDist.Item1; … … 235 240 for (int j = i + 1; !duplicate && j < extremePoints.Count; j++) 236 241 { 237 // maybe todo: override Equals method of solution? 238 duplicate = extremePoints[i].Equals(extremePoints[j]); 242 duplicate = extremePoints[i] == extremePoints[j]; 239 243 } 240 244 } … … 242 246 List<double> intercepts = new List<double>(); 243 247 248 // todo: do handling of this case as in Tsung Che Chiang's implementation 244 249 if (duplicate) 245 250 { // cannot construct the unique hyperplane (this is a casual method to deal with the condition) … … 248 253 // extreme_points[f] stands for the individual with the largest value of 249 254 // objective f 250 intercepts.Add(extremePoints[f]. Fitness[f]);255 intercepts.Add(extremePoints[f].ConvertedFitness[f]); 251 256 } 252 257 } … … 260 265 } 261 266 262 List<List<double>> a = new List<List<double>>(); 263 foreach (Solution s in extremePoints) 264 { 265 List<double> aux = new List<double>(); 266 for (int i = 0; i < numberOfObjectives; i++) 267 aux.Add(s.Fitness[i]); 268 a.Add(aux); 269 } 267 List<List<double>> a = extremePoints.Select(p => p.ConvertedFitness.ToList()).ToList(); 268 270 269 List<double> x = GaussianElimination(a, b); 271 270 -
branches/2825-NSGA3/HeuristicLab.Algorithms.NSGA3/3.3/Solution.cs
r17657 r17692 12 12 public RealVector Chromosome { get; set; } 13 13 14 // Fitness14 // actual fitness of solution as given by Problem 15 15 public double[] Fitness { get; set; } 16 17 // normalized fitness used in selection process (in order to not overwrite the original Fitness) 18 public double[] ConvertedFitness { get; set; } 16 19 17 20 public Solution(RealVector chromosome) … … 23 26 { 24 27 Chromosome = cloner.Clone(solution.Chromosome); 25 Fitness = new double[solution.Fitness.Length]; 26 Array.Copy(solution.Fitness, Fitness, solution.Fitness.Length); 28 if (solution.Fitness != null) 29 { 30 Fitness = new double[solution.Fitness.Length]; 31 Array.Copy(solution.Fitness, Fitness, solution.Fitness.Length); 32 } 33 if (solution.ConvertedFitness != null) 34 { 35 ConvertedFitness = new double[solution.ConvertedFitness.Length]; 36 Array.Copy(solution.ConvertedFitness, ConvertedFitness, solution.ConvertedFitness.Length); 37 } 27 38 } 28 39
Note: See TracChangeset
for help on using the changeset viewer.