Free cookie consent management tool by TermsFeed Policy Generator

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

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

#3055: Added the first version of SMS-EMOA

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      //int indexOffspring = 0;    // the index of offspring to be generated
107
108      // cancellation token for the inner operations which should not be immediately cancelled
109      var innerToken = new CancellationToken();
110
111
112      // initilize the offspring population.
113      offspringPopulation = new ISMSEMOASolution[lambda];
114      jointPopulation = new ISMSEMOASolution[lambda + populationSize];
115
116      // Mainloop
117      while (evaluatedSolutions < maximumEvaluatedSolutions && !cancellationToken.IsCancellationRequested) {
118
119        int indexOffspring = 0;
120
121        // Generate one offspring:
122        var mates = MatingSelection(rand, 2); // select parents
123
124
125        // Get the selected individuals
126        // int variable mate[i] --> index population --> extract "Individual" --> Clone it.
127        var s1 = (IScope)population[mates[0]].Individual.Clone();
128        var s2 = (IScope)population[mates[1]].Individual.Clone();
129
130        // URGENT: What is global scope?
131        s1.Parent = s2.Parent = globalScope;
132
133        IScope childScope = null;
134
135        // crossover
136        if (rand.NextDouble() < crossoverProbability) {
137          childScope = new Scope($"{mates[0]}+{mates[1]}") { Parent = executionContext.Scope };
138          childScope.SubScopes.Add(s1);
139          childScope.SubScopes.Add(s2);
140          // The crossover is executed by using SubScope information.
141          var opCrossover = executionContext.CreateChildOperation(crossover, childScope);
142          ExecuteOperation(executionContext, innerToken, opCrossover);
143          // Clear the SubScopes for the next useage in the next iteration.
144          childScope.SubScopes.Clear(); // <<-- VERY IMPORTANT!
145        }
146        else {
147          // mutation
148          childScope = childScope ?? s1;
149          var opMutation = executionContext.CreateChildOperation(mutator, childScope);
150          ExecuteOperation(executionContext, innerToken, opMutation);
151        }
152
153        // evaluation
154        if (childScope != null) { // Evaluate the childScope
155          var opEvaluation = executionContext.CreateChildOperation(evaluator, childScope);
156          ExecuteOperation(executionContext, innerToken, opEvaluation);
157
158          // childScope
159          var qualities = (DoubleArray)childScope.Variables["Qualities"].Value;
160          var childSolution = new SMSEMOASolution(childScope, maximization.Length, 0);
161          // set child qualities
162          for (int j = 0; j < maximization.Length; ++j) {
163            childSolution.Qualities[j] = maximization[j] ? 1 - qualities[j] : qualities[j];
164          }
165          IdealPoint.UpdateIdeal(childSolution.Qualities);
166          NadirPoint.UpdateNadir(childSolution.Qualities);
167
168          // TODO, KF -- For later usage when $lambda > 1$
169          childSolution.HypervolumeContribution = null;
170          childSolution.NondominanceRanking = null;
171
172          offspringPopulation[indexOffspring] = childSolution;
173
174          ++evaluatedSolutions;
175        }
176        else {
177          // no crossover or mutation were applied, a child was not produced, do nothing
178        }
179
180        if (evaluatedSolutions >= maximumEvaluatedSolutions) {
181          break;
182        }
183
184        // Update jointPopulation
185        population.CopyTo(jointPopulation, 0);
186        offspringPopulation.CopyTo(jointPopulation, populationSize);
187
188        // Update the population according to the S-metric selection.
189        // TODO:
190        //    See the details of TODO list at the beginning for this file ....
191        SmetricSelection(lambda);
192
193        // run analyzer
194        var analyze = executionContext.CreateChildOperation(analyzer, globalScope);
195        ExecuteOperation(executionContext, innerToken, analyze);
196        // update Pareto-front approximation sets
197        UpdateParetoFronts();
198        // Show some results in the GUI.
199        Results.AddOrUpdateResult("IdealPoint", new DoubleArray(IdealPoint));
200        Results.AddOrUpdateResult("NadirPoint", new DoubleArray(NadirPoint));
201        Results.AddOrUpdateResult("Evaluated Solutions", new IntValue(evaluatedSolutions));
202
203        // Update globalScope
204        globalScope.SubScopes.Replace(population.Select(x => (IScope)x.Individual));
205      }
206    }
207  }
208}
Note: See TracBrowser for help on using the repository browser.