Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3055_SMSEMOA/HeuristicLab.Algorithms.SMSEMOA/3.4/SMSEMOAAlgorithm.cs @ 17440

Last change on this file since 17440 was 17440, checked in by kyang, 4 years ago

#3055: Fixed the bug of "no reference point" on real-world test problems

File size: 9.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Author: Kaifeng Yang
4 *
5 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
6 *
7 * This file is part of HeuristicLab.
8 *
9 * HeuristicLab is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * HeuristicLab is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23// SMS-EMOA
24/*
25Implemenetation of a real-coded SMS_EMOA algorithm.
26This implementation follows the description of: 'M. Emmerich, N. Beume, and B. Naujoks.
27An EMO Algorithm Using the Hypervolume Measure as Selection Criterion.EMO 2005.'
28*/
29#endregion
30
31using HEAL.Attic;                       
32using HeuristicLab.Common;             
33using HeuristicLab.Core;               
34using HeuristicLab.Data;               
35using HeuristicLab.Random;             
36using System.Linq;                     
37using System;
38using CancellationToken = System.Threading.CancellationToken;
39
40
41/*  This algorithm is SMS-EMOA implementation on HL. The main structure and interfaces with HL are copied from MOEA/D on HL, which was written by Dr. Bogdan Burlacu. The S-metric selection operator was adapted from Kaifeng's MATLAB toolbox in SMS-EMOA. The computational complexity of HVC is AT LEAST $O (n^2 \log n)$ in 2-D and 3-D cases. HVC should definitely be reduced to $\Theta (n \times \log n)$.
42 * 
43 *  This algorithm assumes:
44 *    1. minimization problems. For maximization problems, it is better to add "-" symbol.
45 * 
46 *  This algorithm works on:
47 *    1. continuous, discrete, mixed-integer MOO problems. For different types of problems, the operators should be adjusted accordingly.
48 *    2. both multi-objective and many-objective problems. For many-objective problems, the bottleneck is the computational complexity of HV.
49 *
50 * This algorithm is the basic implementation of SMS-EMOA, proposed by Michael Emmerich et. al. Some potential improvements can be:
51 *    1. Dynamic reference point strategy
52 *    2. Normalized fitness value strategy ---- desirability function. See, Yali, Longmei, Kaifeng, Michael Emmerich CEC paper.
53 *    3. HVC calculation should definitely be improved, at least in the 2D and 3D cases.
54 *    4. multiple point strategy when $\lambda>1$
55 *    5. multiple reference points strategy, in ICNC 2016, Zhiwei Yang et. al.
56 *    6. HVC approximation by R2 for MANY OBJECTIVE cases, by Ishibushi 2019, IEEE TEC 
57 *    7. Maybe: See maps
58 *
59 * Global parameters:
60 *    1. population 
61 *   
62 * Many thanks for Bogdan Burlacu and Johannes Karder, especially Bogdan for his explanation, help, and supports.
63 */
64
65namespace HeuristicLab.Algorithms.SMSEMOA {
66  // Format:
67  // The indexed name of the algorithm/item, Description of the algorithm/item in HL 
68  [Item("SMS-EMOA", "SMS-EMOA implementation adapted from MATLAB.")]
69
70  // Call "HeuristicLab.Core"
71  // Define the category of this class.
72  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 125)]
73
74  // Call "HEAL.Attic"
75  // Define GUID for this Class
76  [StorableType("05B0D578-B285-4049-B01F-9A4D348A8C73")]
77
78  public class SMSEMOAAlgorithm : SMSEMOAAlgorithmBase {
79    public SMSEMOAAlgorithm() { }
80
81    protected SMSEMOAAlgorithm(SMSEMOAAlgorithm original, Cloner cloner) : base(original, cloner) { }
82
83    public override IDeepCloneable Clone(Cloner cloner) {
84      return new SMSEMOAAlgorithm(this, cloner);
85    }
86
87    [StorableConstructor]
88    protected SMSEMOAAlgorithm(StorableConstructorFlag deserializing) : base(deserializing) { }
89
90    protected override void Run(CancellationToken cancellationToken) {
91      if (previousExecutionState != ExecutionState.Paused) { // Call "base" class, SMSEMOAAlgorithmBase
92        InitializeAlgorithm(cancellationToken);
93      }
94
95      var populationSize = PopulationSize.Value;
96      bool[] maximization = ((BoolArray)Problem.MaximizationParameter.ActualValue).CloneAsArray();
97      var maximumEvaluatedSolutions = MaximumEvaluatedSolutions.Value;
98      var crossover = Crossover;
99      var crossoverProbability = CrossoverProbability.Value;
100      var mutator = Mutator;
101      var mutationProbability = MutationProbability.Value;
102      var evaluator = Problem.Evaluator;
103      var analyzer = Analyzer;
104      var rand = RandomParameter.Value;
105      //int lambda = 1;            // the size of offspring
106      var lambda = Lambda.Value;
107      //int indexOffspring = 0;    // the index of offspring to be generated
108
109      // cancellation token for the inner operations which should not be immediately cancelled
110      var innerToken = new CancellationToken();
111
112
113      // initilize the offspring population.
114      offspringPopulation = new ISMSEMOASolution[lambda];
115      jointPopulation = new ISMSEMOASolution[lambda + populationSize];
116
117      // Mainloop
118      while (evaluatedSolutions < maximumEvaluatedSolutions && !cancellationToken.IsCancellationRequested) {
119
120        int indexOffspring = 0;
121
122        // Generate one offspring:
123        var mates = MatingSelection(rand, 2); // select parents
124
125
126        // Get the selected individuals
127        // int variable mate[i] --> index population --> extract "Individual" --> Clone it.
128        var s1 = (IScope)population[mates[0]].Individual.Clone();
129        var s2 = (IScope)population[mates[1]].Individual.Clone();
130
131        // URGENT: What is global scope?
132        s1.Parent = s2.Parent = globalScope;
133
134        IScope childScope = null;
135
136        // crossover
137        if (rand.NextDouble() < crossoverProbability) {
138          childScope = new Scope($"{mates[0]}+{mates[1]}") { Parent = executionContext.Scope };
139          childScope.SubScopes.Add(s1);
140          childScope.SubScopes.Add(s2);
141          // The crossover is executed by using SubScope information.
142          var opCrossover = executionContext.CreateChildOperation(crossover, childScope);
143          ExecuteOperation(executionContext, innerToken, opCrossover);
144          // Clear the SubScopes for the next useage in the next iteration.
145          childScope.SubScopes.Clear(); // <<-- VERY IMPORTANT!
146        }
147        else {
148          // mutation
149          childScope = childScope ?? s1;
150          var opMutation = executionContext.CreateChildOperation(mutator, childScope);
151          ExecuteOperation(executionContext, innerToken, opMutation);
152        }
153
154        // evaluation
155        if (childScope != null) { // Evaluate the childScope
156          var opEvaluation = executionContext.CreateChildOperation(evaluator, childScope);
157          ExecuteOperation(executionContext, innerToken, opEvaluation);
158
159          // childScope
160          var qualities = (DoubleArray)childScope.Variables["Qualities"].Value;
161          var childSolution = new SMSEMOASolution(childScope, maximization.Length, 0);
162          // set child qualities
163          for (int j = 0; j < maximization.Length; ++j) {
164            childSolution.Qualities[j] = maximization[j] ? 1 - qualities[j] : qualities[j];
165          }
166          IdealPoint.UpdateIdeal(childSolution.Qualities);
167          NadirPoint.UpdateNadir(childSolution.Qualities);
168
169          // TODO, KF -- For later usage when $lambda > 1$
170          childSolution.HypervolumeContribution = null;
171          childSolution.NondominanceRanking = null;
172
173          offspringPopulation[indexOffspring] = childSolution;
174
175          ++evaluatedSolutions;
176        }
177        else {
178          // no crossover or mutation were applied, a child was not produced, do nothing
179        }
180
181        if (evaluatedSolutions >= maximumEvaluatedSolutions) {
182          break;
183        }
184
185        // Update jointPopulation
186        population.CopyTo(jointPopulation, 0);
187        offspringPopulation.CopyTo(jointPopulation, populationSize);
188
189        // Update the population according to the S-metric selection.
190        // TODO:
191        //    See the details of TODO list at the beginning for this file ....
192        SmetricSelection(lambda);
193
194        // run analyzer
195        var analyze = executionContext.CreateChildOperation(analyzer, globalScope);
196        ExecuteOperation(executionContext, innerToken, analyze);
197        // update Pareto-front approximation sets
198        UpdateParetoFronts();
199        // Show some results in the GUI.
200        Results.AddOrUpdateResult("IdealPoint", new DoubleArray(IdealPoint));
201        Results.AddOrUpdateResult("NadirPoint", new DoubleArray(NadirPoint));
202        Results.AddOrUpdateResult("Evaluated Solutions", new IntValue(evaluatedSolutions));
203
204        // Update globalScope
205        globalScope.SubScopes.Replace(population.Select(x => (IScope)x.Individual));
206      }
207    }
208  }
209}
Note: See TracBrowser for help on using the repository browser.