Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3057_DynamicALPS/backup/17032020/HeuristicLab.Algorithms.DynamicALPS/3.4/DynamicALPSAlgorithm.cs @ 17709

Last change on this file since 17709 was 17479, checked in by kyang, 5 years ago

#3057

  1. upload the latest version of ALPS with SMS-EMOA
  2. upload the related dynamic test problems (dynamic, single-objective symbolic regression), written by David Daninel.
File size: 11.6 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;
39using HeuristicLab.Analysis;
40using HeuristicLab.Problems.TestFunctions.MultiObjective;
41using HeuristicLab.Optimization;
42using System.Collections.Generic;
43
44
45/*  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)$.
46 * 
47 *  This algorithm assumes:
48 *    1. minimization problems. For maximization problems, it is better to add "-" symbol.
49 * 
50 *  This algorithm works on:
51 *    1. continuous, discrete, mixed-integer MOO problems. For different types of problems, the operators should be adjusted accordingly.
52 *    2. both multi-objective and many-objective problems. For many-objective problems, the bottleneck is the computational complexity of HV.
53 *
54 * This algorithm is the basic implementation of SMS-EMOA, proposed by Michael Emmerich et. al. Some potential improvements can be:
55 *    1. Dynamic reference point strategy
56 *    2. Normalized fitness value strategy ---- desirability function. See, Yali, Longmei, Kaifeng, Michael Emmerich CEC paper.
57 *    3. HVC calculation should definitely be improved, at least in the 2D and 3D cases.
58 *    4. multiple point strategy when $\lambda>1$
59 *    5. multiple reference points strategy, in ICNC 2016, Zhiwei Yang et. al.
60 *    6. HVC approximation by R2 for MANY OBJECTIVE cases, by Ishibushi 2019, IEEE TEC 
61 *    7. Maybe: See maps
62 *
63 * Global parameters:
64 *    1. population 
65 *   
66 * Many thanks for Bogdan Burlacu and Johannes Karder, especially Bogdan for his explanation, help, and supports.
67 */
68
69namespace HeuristicLab.Algorithms.DynamicALPS {
70  // Format:
71  // The indexed name of the algorithm/item, Description of the algorithm/item in HL 
72  [Item("DynamicALPS-MainLoop", "DynamicALPS-MainLoop implementation adapted from SMS-EMOA in HL.")]
73
74  // Call "HeuristicLab.Core"
75  // Define the category of this class.
76  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 125)]
77
78  // Call "HEAL.Attic"
79  // Define GUID for this Class
80  [StorableType("A7F33D16-3495-43E8-943C-8A919123F541")]
81
82  public class DynamicALPSAlgorithm : DynamicALPSAlgorithmBase {
83    public DynamicALPSAlgorithm() { }
84
85    protected DynamicALPSAlgorithm(DynamicALPSAlgorithm original, Cloner cloner) : base(original, cloner) { }
86
87    public override IDeepCloneable Clone(Cloner cloner) {
88      return new DynamicALPSAlgorithm(this, cloner);
89    }
90
91    [StorableConstructor]
92    protected DynamicALPSAlgorithm(StorableConstructorFlag deserializing) : base(deserializing) { }
93
94    protected override void Run(CancellationToken cancellationToken) {
95      if (previousExecutionState != ExecutionState.Paused) { // Call "base" class, DynamicALPSAlgorithmBase
96        InitializeAlgorithm(cancellationToken);
97      }
98
99
100      var populationSize = PopulationSize.Value;
101      bool[] maximization = ((BoolArray)Problem.MaximizationParameter.ActualValue).CloneAsArray();
102
103      var crossover = Crossover;
104      var crossoverProbability = CrossoverProbability.Value;
105      var mutator = Mutator;
106      var mutationProbability = MutationProbability.Value;
107      var evaluator = Problem.Evaluator;
108      var analyzer = Analyzer;
109      var rand = RandomParameter.Value;
110
111
112      var maximumEvaluatedSolutions = MaximumEvaluatedSolutions.Value;
113
114
115      int lambda = 1;            // the size of offspring
116
117
118      int nLayerALPS = ALPSLayers.Value;
119      int counterLayerALPS = 0;
120
121      // IMPROVE: ........
122      int[] ageGapArray = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
123      int[] numberDiscard = new int[10];
124
125
126
127      activeLayer = new bool[nLayerALPS];
128      int[][] ageMatrix = new int[nLayerALPS][];      // layer * population size
129
130
131
132      // cancellation token for the inner operations which should not be immediately cancelled
133      var innerToken = new CancellationToken();
134
135
136      // run some analyzer on each layer (for now calculate scatter plots )
137      List<Tuple<int, ScatterPlotAnalyzer>> layerAnalyzers;
138
139
140      // 12022020
141      layerPopulation = new IDynamicALPSSolution[nLayerALPS][];
142      layerOffspringPopulation = new IDynamicALPSSolution[nLayerALPS][];
143      layerJointPopulation = new IDynamicALPSSolution[nLayerALPS][];
144      layerDiscardPopulation = new IDynamicALPSSolution[nLayerALPS][];
145
146
147      layerPopulation[counterLayerALPS] = new IDynamicALPSSolution[populationSize];
148      // BUG: The size of offspring should vary in different layers!!!!
149      layerOffspringPopulation[counterLayerALPS] = new IDynamicALPSSolution[lambda];
150      layerDiscardPopulation[counterLayerALPS] = new IDynamicALPSSolution[populationSize];
151      population.CopyTo(layerPopulation[counterLayerALPS], 0);
152
153      activeLayer[counterLayerALPS] = true;
154      for (int i = 0; i < nLayerALPS; i++) {
155        if (i == 0) {
156          activeLayer[i] = true;
157        }
158        else { activeLayer[i] = false; }
159        numberDiscard[i] = 0;
160      }
161
162      // Mainloop
163      while (evaluatedSolutions < maximumEvaluatedSolutions && !cancellationToken.IsCancellationRequested) {
164        for (int i = 0; i < nLayerALPS; i++) {            // loop for every layer
165          int discardedIndividualIndex = 0;
166          if (activeLayer[i] == true) {                   // check the layer is active or not.
167            evaluatedSolutions = SMSEMOA(populationSize, lambda, i);
168            if (evaluatedSolutions >= maximumEvaluatedSolutions) { break; }           // check evaluation budget
169            ageMatrix[i] = layerJointPopulation[i].Select(x => x.Age).ToArray();      // get age info of the current layer joint population
170            if (ageMatrix[i].Max() > ageGapArray[i]) {    // mature: moving
171              discardedIndividualIndex = ageMatrix[i].ToList().IndexOf(ageMatrix[i].Max());   // BUG when two individual has the same maximal age???? NOT POSSBILE IN SMS-EMOA
172              layerDiscardPopulation[i][numberDiscard[i]] = layerJointPopulation[i][discardedIndividualIndex];                    // move the individual to the next layer
173              layerJointPopulation[i].Where((x, idx) => idx != discardedIndividualIndex).ToArray().CopyTo(layerPopulation[i], 0); // discard the indivudal in the current layer 
174              numberDiscard[i] += 1;
175              if (activeLayer[i + 1] == false) {   // next layer is not active  // bug, if i == number of layer,  out of range .
176                if (numberDiscard[i] == populationSize) {
177                  InitializeLayer(i + 1, populationSize, lambda);  // initilizae the layerPopulation for the next layer && ACTIVE FLAGE
178                  layerDiscardPopulation[i].CopyTo(layerPopulation[i + 1], 0);
179                  numberDiscard[i] = 0;
180                }
181                else {
182                  // number of matured individuals < population size in the next layer
183                }
184              }
185              else {  // next layer is active
186                layerPopulation[i+1].CopyTo(layerJointPopulation[i + 1], 0);
187                layerJointPopulation[i].Where((x, idx) => idx == discardedIndividualIndex).ToArray().CopyTo(layerJointPopulation[i + 1], populationSize);
188                SmetricSelection(lambda, i + 1); // AGE and HVC
189                numberDiscard[i] = 0;
190              }
191            }
192            layerPopulation[i].CopyTo(population, 0);  // BUG: should copy all the active layers to population.
193          }
194          else {
195            // Some thing wrong? lol nothing wrong here ^_^
196          }
197        }
198
199
200
201        // run analyzer
202        var analyze = executionContext.CreateChildOperation(analyzer, globalScope);
203        ExecuteOperation(executionContext, innerToken, analyze);
204        // update Pareto-front approximation sets
205        UpdateParetoFronts();
206        // Show some results in the GUI.
207        Results.AddOrUpdateResult("IdealPoint", new DoubleArray(IdealPoint));
208        Results.AddOrUpdateResult("NadirPoint", new DoubleArray(NadirPoint));
209        Results.AddOrUpdateResult("Evaluated Solutions", new IntValue(evaluatedSolutions));
210
211        var allLayerResults = new ResultCollection();
212        Results.AddOrUpdateResult("LayerResults", allLayerResults);
213       
214        // run layer analyzers
215        for (int i = 0; i < activeLayer.Length; ++i) {
216          if (!activeLayer[i]) continue;
217          var scope = new Scope($"Layer {i}");
218          var layer = layerPopulation[i];
219          var layerResults = new ResultCollection();
220          allLayerResults.Add(new Result(scope.Name, layerResults));
221
222          var problem = (MultiObjectiveTestFunctionProblem)Problem;
223          //scope.Variables.Add(new Variable("Individuals", new ItemArray<IScope>(layer.Select(x => (IScope)x.Individual))));
224          //scope.Variables.Add(new Variable("Qualities", new ItemArray<DoubleArray>(layer.Select(x => new DoubleArray(x.Qualities)))));
225          scope.SubScopes.AddRange(layer.Select(x => (IScope)x.Individual));
226          scope.Variables.Add(new Variable("Results", layerResults));
227          scope.Variables.Add(new Variable("TestFunction", problem.TestFunction));
228          var scatterPlotAnalyzer = new ScatterPlotAnalyzer();
229          scatterPlotAnalyzer.IndividualsParameter.ActualName = "RealVector";
230          var scattetPlotAnalyzerContext = executionContext.CreateChildOperation(scatterPlotAnalyzer, scope);
231          ExecuteOperation(executionContext, CancellationToken.None, scattetPlotAnalyzerContext);
232          scope.SubScopes.Clear();
233          scope.Variables.Clear();
234        }
235
236        // Update globalScope
237        globalScope.SubScopes.Replace(population.Select(x => (IScope)x.Individual));
238
239
240        //// intilize the population for the next layer
241        //counterLayerALPS += 1;
242        //layerPopulation[counterLayerALPS] = new IDynamicALPSSolution[populationSize];
243        //layerPopulation[counterLayerALPS-1].CopyTo(layerPopulation[counterLayerALPS], 0); // DETELTE DUBGU
244        //// BUG lambda should be different~~~~!!!!
245        //layerOffspringPopulation[counterLayerALPS] = new IDynamicALPSSolution[lambda];
246      }
247    }
248  }
249}
Note: See TracBrowser for help on using the repository browser.