source: branches/2987_MOEAD_Algorithm/HeuristicLab.Algorithms.MOEAD/3.4/MOEADAlgorithm.cs @ 16630

Last change on this file since 16630 was 16630, checked in by bburlacu, 6 months ago

#2987: Migrate to new persistence. Add support for objective scaling.

File size: 5.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using HEAL.Attic;
23using HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Random;
27using System.Linq;
28using CancellationToken = System.Threading.CancellationToken;
29
30namespace HeuristicLab.Algorithms.MOEAD {
31  [Item("Multi-objective Evolutionary Algorithm based on Decomposition (MOEA/D)", "MOEA/D implementation adapted from jMetal.")]
32  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 125)]
33  [StorableType("FE39AD23-B3BF-4368-BB79-FE5BF4C36272")]
34  public class MOEADAlgorithm : MOEADAlgorithmBase {
35    public MOEADAlgorithm() { }
36
37    protected MOEADAlgorithm(MOEADAlgorithm original, Cloner cloner) : base(original, cloner) { }
38
39    public override IDeepCloneable Clone(Cloner cloner) {
40      return new MOEADAlgorithm(this, cloner);
41    }
42
43    [StorableConstructor]
44    protected MOEADAlgorithm(StorableConstructorFlag deserializing) : base(deserializing) { }
45
46    protected override void Run(CancellationToken cancellationToken) {
47      if (previousExecutionState != ExecutionState.Paused) {
48        InitializeAlgorithm(cancellationToken);
49      }
50
51      var populationSize = PopulationSize.Value;
52      bool[] maximization = ((BoolArray)Problem.MaximizationParameter.ActualValue).CloneAsArray();
53      var maximumEvaluatedSolutions = MaximumEvaluatedSolutions.Value;
54      var crossover = Crossover;
55      var crossoverProbability = CrossoverProbability.Value;
56      var mutator = Mutator;
57      var mutationProbability = MutationProbability.Value;
58      var evaluator = Problem.Evaluator;
59      var analyzer = Analyzer;
60      var neighbourhoodSelectionProbability = NeighbourhoodSelectionProbability;
61      var rand = RandomParameter.Value;
62
63      // cancellation token for the inner operations which should not be immediately cancelled
64      var innerToken = new CancellationToken();
65
66      while (evaluatedSolutions < maximumEvaluatedSolutions && !cancellationToken.IsCancellationRequested) {
67        foreach (var subProblemId in Enumerable.Range(0, populationSize).Shuffle(rand)) {
68          var neighbourType = ChooseNeighborType(rand, neighbourhoodSelectionProbability);
69          var mates = MatingSelection(rand, subProblemId, 2, neighbourType); // select parents
70          var s1 = (IScope)population[mates[0]].Individual.Clone();
71          var s2 = (IScope)population[mates[1]].Individual.Clone();
72          s1.Parent = s2.Parent = globalScope;
73
74          IScope childScope = null;
75          // crossover
76          if (rand.NextDouble() < crossoverProbability) {
77            childScope = new Scope($"{mates[0]}+{mates[1]}") { Parent = executionContext.Scope };
78            childScope.SubScopes.Add(s1);
79            childScope.SubScopes.Add(s2);
80            var op = executionContext.CreateChildOperation(crossover, childScope);
81            ExecuteOperation(executionContext, innerToken, op);
82            childScope.SubScopes.Clear();
83          }
84
85          // mutation
86          if (rand.NextDouble() < mutationProbability) {
87            childScope = childScope ?? s1;
88            var op = executionContext.CreateChildOperation(mutator, childScope);
89            ExecuteOperation(executionContext, innerToken, op);
90          }
91
92          // evaluation
93          if (childScope != null) {
94            var op = executionContext.CreateChildOperation(evaluator, childScope);
95            ExecuteOperation(executionContext, innerToken, op);
96            var qualities = (DoubleArray)childScope.Variables["Qualities"].Value;
97            var childSolution = new MOEADSolution(childScope, maximization.Length, 0);
98            // set child qualities
99            for (int j = 0; j < maximization.Length; ++j) {
100              childSolution.Qualities[j] = maximization[j] ? 1 - qualities[j] : qualities[j];
101            }
102            IdealPoint.UpdateIdeal(childSolution.Qualities);
103            NadirPoint.UpdateNadir(childSolution.Qualities);
104            // update neighbourhood will insert the child into the population
105            UpdateNeighbourHood(rand, childSolution, subProblemId, neighbourType);
106
107            ++evaluatedSolutions;
108          } else {
109            // no crossover or mutation were applied, a child was not produced, do nothing
110          }
111
112          if (evaluatedSolutions >= maximumEvaluatedSolutions) {
113            break;
114          }
115        }
116        // run analyzer
117        var analyze = executionContext.CreateChildOperation(analyzer, globalScope);
118        ExecuteOperation(executionContext, innerToken, analyze);
119
120        UpdateParetoFronts();
121
122        Results.AddOrUpdateResult("IdealPoint", new DoubleArray(IdealPoint));
123        Results.AddOrUpdateResult("NadirPoint", new DoubleArray(NadirPoint));
124        Results.AddOrUpdateResult("Evaluated Solutions", new IntValue(evaluatedSolutions));
125
126        globalScope.SubScopes.Replace(population.Select(x => (IScope)x.Individual));
127      }
128    }
129  }
130}
Note: See TracBrowser for help on using the repository browser.