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

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

#2987: Implement better uniform weight generation, objective scaling, algorithm Pause support.

File size: 4.7 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      if (previousExecutionState != ExecutionState.Paused) {
27        InitializeAlgorithm(cancellationToken);
28      }
29
30      var populationSize = PopulationSize.Value;
31      bool[] maximization = ((BoolArray)Problem.MaximizationParameter.ActualValue).CloneAsArray();
32      var maximumEvaluatedSolutions = MaximumEvaluatedSolutions.Value;
33      var crossover = Crossover;
34      var crossoverProbability = CrossoverProbability.Value;
35      var mutator = Mutator;
36      var mutationProbability = MutationProbability.Value;
37      var evaluator = Problem.Evaluator;
38      var analyzer = Analyzer;
39      var neighbourhoodSelectionProbability = NeighbourhoodSelectionProbability;
40      var rand = RandomParameter.Value;
41
42      // cancellation token for the inner operations which should not be immediately cancelled
43      var innerToken = new CancellationToken();
44
45      while (evaluatedSolutions < maximumEvaluatedSolutions && !cancellationToken.IsCancellationRequested) {
46        foreach (var subProblemId in Enumerable.Range(0, populationSize).Shuffle(rand)) {
47          var neighbourType = ChooseNeighborType(rand, neighbourhoodSelectionProbability);
48          var mates = MatingSelection(rand, subProblemId, 2, neighbourType); // select parents
49          var s1 = (IScope)population[mates[0]].Individual.Clone();
50          var s2 = (IScope)population[mates[1]].Individual.Clone();
51          s1.Parent = s2.Parent = globalScope;
52
53          IScope childScope = null;
54          // crossover
55          if (rand.NextDouble() < crossoverProbability) {
56            childScope = new Scope($"{mates[0]}+{mates[1]}") { Parent = executionContext.Scope };
57            childScope.SubScopes.Add(s1);
58            childScope.SubScopes.Add(s2);
59            var op = executionContext.CreateChildOperation(crossover, childScope);
60            ExecuteOperation(executionContext, innerToken, op);
61            childScope.SubScopes.Clear();
62          }
63
64          // mutation
65          if (rand.NextDouble() < mutationProbability) {
66            childScope = childScope ?? s1;
67            var op = executionContext.CreateChildOperation(mutator, childScope);
68            ExecuteOperation(executionContext, innerToken, op);
69          }
70
71          // evaluation
72          if (childScope != null) {
73            var op = executionContext.CreateChildOperation(evaluator, childScope);
74            ExecuteOperation(executionContext, innerToken, op);
75            var qualities = (DoubleArray)childScope.Variables["Qualities"].Value;
76            var childSolution = new MOEADSolution(childScope, maximization.Length, 0);
77            // set child qualities
78            for (int j = 0; j < maximization.Length; ++j) {
79              childSolution.Qualities[j] = maximization[j] ? 1 - qualities[j] : qualities[j];
80            }
81            IdealPoint.UpdateIdeal(childSolution.Qualities);
82            NadirPoint.UpdateNadir(childSolution.Qualities);
83            // update neighbourhood will insert the child into the population
84            UpdateNeighbourHood(rand, childSolution, subProblemId, neighbourType);
85
86            ++evaluatedSolutions;
87          } else {
88            // no crossover or mutation were applied, a child was not produced, do nothing
89          }
90
91          if (evaluatedSolutions >= maximumEvaluatedSolutions) {
92            break;
93          }
94        }
95        // run analyzer
96        var analyze = executionContext.CreateChildOperation(analyzer, globalScope);
97        ExecuteOperation(executionContext, innerToken, analyze);
98
99        UpdateParetoFronts();
100        Results.AddOrUpdateResult("Evaluated Solutions", new IntValue(evaluatedSolutions));
101
102        globalScope.SubScopes.Replace(population.Select(x => (IScope)x.Individual));
103      }
104    }
105  }
106}
Note: See TracBrowser for help on using the repository browser.