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

Last change on this file since 16560 was 16560, checked in by bburlacu, 4 months ago

#2987: Create separate plugin for MOEA/D

File size: 4.6 KB
Line 
1using HeuristicLab.Common;
2using HeuristicLab.Core;
3using HeuristicLab.Data;
4using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
5using HeuristicLab.Random;
6using System.Linq;
7using CancellationToken = System.Threading.CancellationToken;
8
9namespace HeuristicLab.Algorithms.MOEAD {
10  [Item("Multi-objective Evolutionary Algorithm based on Decomposition (MOEA/D)", "MOEA/D implementation adapted from jMetal.")]
11  [StorableClass]
12  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 125)]
13  public class MOEADAlgorithm : MOEADAlgorithmBase {
14    public MOEADAlgorithm() { }
15
16    protected MOEADAlgorithm(MOEADAlgorithm original, Cloner cloner) : base(original, cloner) { }
17
18    public override IDeepCloneable Clone(Cloner cloner) {
19      return new MOEADAlgorithm(this, cloner);
20    }
21
22    [StorableConstructor]
23    protected MOEADAlgorithm(bool deserializing) : base(deserializing) { }
24
25    protected override void Run(CancellationToken cancellationToken) {
26      var populationSize = PopulationSize.Value;
27      bool[] maximization = ((BoolArray)Problem.MaximizationParameter.ActualValue).CloneAsArray();
28      var maximumEvaluatedSolutions = MaximumEvaluatedSolutions.Value;
29      var crossover = Crossover;
30      var crossoverProbability = CrossoverProbability.Value;
31      var mutator = Mutator;
32      var mutationProbability = MutationProbability.Value;
33      var evaluator = Problem.Evaluator;
34      var analyzer = Analyzer;
35      var neighbourhoodSelectionProbability = NeighbourhoodSelectionProbability;
36      var rand = RandomParameter.Value;
37
38      // cancellation token for the inner operations which should not be immediately cancelled
39      var innerToken = new CancellationToken();
40
41      while (evaluatedSolutions < maximumEvaluatedSolutions && !cancellationToken.IsCancellationRequested) {
42        foreach (var subProblemId in Enumerable.Range(0, populationSize).Shuffle(rand)) {
43          var neighbourType = ChooseNeighborType(rand, neighbourhoodSelectionProbability);
44          var mates = MatingSelection(rand, subProblemId, 2, neighbourType); // select parents
45          var s1 = (IScope)population[mates[0]].Individual.Clone();
46          var s2 = (IScope)population[mates[1]].Individual.Clone();
47          s1.Parent = s2.Parent = globalScope;
48
49          IScope childScope = null;
50          // crossover
51          if (rand.NextDouble() < crossoverProbability) {
52            childScope = new Scope($"{mates[0]}+{mates[1]}") { Parent = executionContext.Scope };
53            childScope.SubScopes.Add(s1);
54            childScope.SubScopes.Add(s2);
55            var op = executionContext.CreateChildOperation(crossover, childScope);
56            ExecuteOperation(executionContext, innerToken, op);
57            childScope.SubScopes.Clear();
58          }
59
60          // mutation
61          if (rand.NextDouble() < mutationProbability) {
62            childScope = childScope ?? s1;
63            var op = executionContext.CreateChildOperation(mutator, childScope);
64            ExecuteOperation(executionContext, innerToken, op);
65          }
66
67          // evaluation
68          if (childScope != null) {
69            var op = executionContext.CreateChildOperation(evaluator, childScope);
70            ExecuteOperation(executionContext, innerToken, op);
71            var qualities = (DoubleArray)childScope.Variables["Qualities"].Value;
72            var childSolution = new MOEADSolution(childScope, maximization.Length, 0);
73            // set child qualities
74            for (int j = 0; j < maximization.Length; ++j) {
75              childSolution.Qualities[j] = maximization[j] ? 1 - qualities[j] : qualities[j];
76            }
77            IdealPoint.UpdateIdeal(childSolution.Qualities);
78            NadirPoint.UpdateNadir(childSolution.Qualities);
79            // update neighbourhood will insert the child into the population
80            UpdateNeighbourHood(rand, childSolution, subProblemId, neighbourType);
81
82            ++evaluatedSolutions;
83          } else {
84            // no crossover or mutation were applied, a child was not produced, do nothing
85          }
86
87          if (evaluatedSolutions >= maximumEvaluatedSolutions) {
88            break;
89          }
90        }
91        // run analyzer
92        var analyze = executionContext.CreateChildOperation(analyzer, globalScope);
93        ExecuteOperation(executionContext, innerToken, analyze);
94
95        UpdateParetoFronts();
96        Results.AddOrUpdateResult("Evaluated Solutions", new IntValue(evaluatedSolutions));
97
98        globalScope.SubScopes.Replace(population.Select(x => (IScope)x.Individual));
99      }
100    }
101  }
102}
Note: See TracBrowser for help on using the repository browser.