Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveProblem.cs @ 17459

Last change on this file since 17459 was 17320, checked in by mkommend, 5 years ago

#2521: Added cancellation token to evaluate function of problems.

File size: 8.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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 System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Threading;
26using HEAL.Attic;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Parameters;
31
32namespace HeuristicLab.Optimization {
33  [StorableType("6F2EC371-0309-4848-B7B1-C9B9C7E3436F")]
34  public abstract class MultiObjectiveProblem<TEncoding, TEncodedSolution> :
35    Problem<TEncoding, TEncodedSolution, MultiObjectiveEvaluator<TEncodedSolution>>,
36    IMultiObjectiveProblem<TEncoding, TEncodedSolution>,
37    IMultiObjectiveProblemDefinition<TEncoding, TEncodedSolution>
38    where TEncoding : class, IEncoding<TEncodedSolution>
39    where TEncodedSolution : class, IEncodedSolution {
40    #region Parameternames
41    public const string BestKnownFrontParameterName = "BestKnownFront";
42    public const string ReferencePointParameterName = "ReferencePoint";
43    #endregion
44
45    #region Parameterproperties
46    [Storable] public IValueParameter<BoolArray> MaximizationParameter { get; }
47    public IValueParameter<DoubleMatrix> BestKnownFrontParameter {
48      get { return (IValueParameter<DoubleMatrix>)Parameters[BestKnownFrontParameterName]; }
49    }
50    public IValueParameter<DoubleArray> ReferencePointParameter {
51      get { return (IValueParameter<DoubleArray>)Parameters[ReferencePointParameterName]; }
52    }
53    #endregion
54
55
56    [StorableConstructor]
57    protected MultiObjectiveProblem(StorableConstructorFlag _) : base(_) { }
58
59    protected MultiObjectiveProblem(MultiObjectiveProblem<TEncoding, TEncodedSolution> original, Cloner cloner)
60      : base(original, cloner) {
61      MaximizationParameter = cloner.Clone(original.MaximizationParameter);
62      ParameterizeOperators();
63    }
64
65    protected MultiObjectiveProblem() : base() {
66      MaximizationParameter = new ValueParameter<BoolArray>("Maximization", "The dimensions correspond to the different objectives: False if the objective should be minimized, true if it should be maximized..", new BoolArray(new bool[] { }, @readonly: true));
67      Parameters.Add(MaximizationParameter);
68      Parameters.Add(new OptionalValueParameter<DoubleMatrix>(BestKnownFrontParameterName, "A double matrix representing the best known qualites for this problem (aka points on the Pareto front). Points are to be given in a row-wise fashion."));
69      Parameters.Add(new OptionalValueParameter<DoubleArray>(ReferencePointParameterName, "The refrence point for hypervolume calculations on this problem"));
70      Operators.Add(Evaluator);
71      Operators.Add(new MultiObjectiveAnalyzer<TEncodedSolution>());
72      ParameterizeOperators();
73    }
74
75    protected MultiObjectiveProblem(TEncoding encoding) : base(encoding) {
76      MaximizationParameter = new ValueParameter<BoolArray>("Maximization", "The dimensions correspond to the different objectives: False if the objective should be minimized, true if it should be maximized..", new BoolArray(new bool[] { }, @readonly: true));
77      Parameters.Add(MaximizationParameter);
78      Parameters.Add(new OptionalValueParameter<DoubleMatrix>(BestKnownFrontParameterName, "A double matrix representing the best known qualites for this problem (aka points on the Pareto front). Points are to be given in a row-wise fashion."));
79      Parameters.Add(new OptionalValueParameter<DoubleArray>(ReferencePointParameterName, "The refrence point for hypervolume calculations on this problem"));
80      Operators.Add(Evaluator);
81      Operators.Add(new MultiObjectiveAnalyzer<TEncodedSolution>());
82      ParameterizeOperators();
83    }
84
85    [StorableHook(HookType.AfterDeserialization)]
86    private void AfterDeserialization() {
87      ParameterizeOperators();
88    }
89
90    public int Objectives {
91      get { return Maximization.Length; }
92    }
93    public bool[] Maximization {
94      get { return MaximizationParameter.Value.CloneAsArray(); }
95      protected set {
96        if (MaximizationParameter.Value.SequenceEqual(value)) return;
97        MaximizationParameter.ForceValue(new BoolArray(value, @readonly: true));
98        OnMaximizationChanged();
99      }
100    }
101
102    public virtual IReadOnlyList<double[]> BestKnownFront {
103      get {
104        if (!Parameters.ContainsKey(BestKnownFrontParameterName)) return null;
105        var mat = BestKnownFrontParameter.Value;
106        if (mat == null) return null;
107        var v = new double[mat.Rows][];
108        for (var i = 0; i < mat.Rows; i++) {
109          var r = v[i] = new double[mat.Columns];
110          for (var j = 0; j < mat.Columns; j++) {
111            r[j] = mat[i, j];
112          }
113        }
114        return v;
115      }
116      set {
117        if (value == null || value.Count == 0) {
118          BestKnownFrontParameter.Value = new DoubleMatrix();
119          return;
120        }
121        var mat = new DoubleMatrix(value.Count, value[0].Length);
122        for (int i = 0; i < value.Count; i++) {
123          for (int j = 0; j < value[i].Length; j++) {
124            mat[i, j] = value[i][j];
125          }
126        }
127
128        BestKnownFrontParameter.Value = mat;
129      }
130    }
131    public virtual double[] ReferencePoint {
132      get { return ReferencePointParameter.Value != null ? ReferencePointParameter.Value.CloneAsArray() : null; }
133      set { ReferencePointParameter.Value = new DoubleArray(value); }
134    }
135
136    public virtual double[] Evaluate(TEncodedSolution solution, IRandom random) {
137      return Evaluate(solution, random, CancellationToken.None);
138    }
139
140    public abstract double[] Evaluate(TEncodedSolution solution, IRandom random, CancellationToken cancellationToken);
141    public virtual void Analyze(TEncodedSolution[] solutions, double[][] qualities, ResultCollection results, IRandom random) { }
142
143
144    protected override void OnOperatorsChanged() {
145      if (Encoding != null) {
146        PruneSingleObjectiveOperators(Encoding);
147        var combinedEncoding = Encoding as CombinedEncoding;
148        if (combinedEncoding != null) {
149          foreach (var encoding in combinedEncoding.Encodings.ToList()) {
150            PruneSingleObjectiveOperators(encoding);
151          }
152        }
153      }
154      base.OnOperatorsChanged();
155    }
156
157    private void PruneSingleObjectiveOperators(IEncoding encoding) {
158      if (encoding != null && encoding.Operators.Any(x => x is ISingleObjectiveOperator && !(x is IMultiObjectiveOperator)))
159        encoding.Operators = encoding.Operators.Where(x => !(x is ISingleObjectiveOperator) || x is IMultiObjectiveOperator).ToList();
160
161      foreach (var multiOp in Encoding.Operators.OfType<IMultiOperator>()) {
162        foreach (var soOp in multiOp.Operators.Where(x => x is ISingleObjectiveOperator).ToList()) {
163          multiOp.RemoveOperator(soOp);
164        }
165      }
166    }
167
168    protected override void OnEvaluatorChanged() {
169      base.OnEvaluatorChanged();
170      ParameterizeOperators();
171    }
172
173    private void ParameterizeOperators() {
174      foreach (var op in Operators.OfType<IMultiObjectiveEvaluationOperator<TEncodedSolution>>())
175        op.EvaluateFunc = Evaluate;
176      foreach (var op in Operators.OfType<IMultiObjectiveAnalysisOperator<TEncodedSolution>>())
177        op.AnalyzeAction = Analyze;
178    }
179
180
181    #region IMultiObjectiveHeuristicOptimizationProblem Members
182    IParameter IMultiObjectiveHeuristicOptimizationProblem.MaximizationParameter {
183      get { return MaximizationParameter; }
184    }
185    IMultiObjectiveEvaluator IMultiObjectiveHeuristicOptimizationProblem.Evaluator {
186      get { return Evaluator; }
187    }
188    #endregion
189
190    public event EventHandler MaximizationChanged;
191    protected void OnMaximizationChanged() {
192      MaximizationChanged?.Invoke(this, EventArgs.Empty);
193    }
194  }
195}
Note: See TracBrowser for help on using the repository browser.