Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/SingleObjectiveProblem.cs @ 17317

Last change on this file since 17317 was 17317, checked in by abeham, 4 years ago

#2521: refactored multi-objective problems' maximization

  • Add ForceValue method to IValueParameter to perform changes even when it is read-only
  • Add MaximizationChanged event handler
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 HEAL.Attic;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Parameters;
30
31namespace HeuristicLab.Optimization {
32  [StorableType("2697320D-0259-44BB-BD71-7EE1B10F664C")]
33  public abstract class SingleObjectiveProblem<TEncoding, TEncodedSolution> :
34    Problem<TEncoding, TEncodedSolution, SingleObjectiveEvaluator<TEncodedSolution>>,
35    ISingleObjectiveProblem<TEncoding, TEncodedSolution>,
36    ISingleObjectiveProblemDefinition<TEncoding, TEncodedSolution>
37    where TEncoding : class, IEncoding<TEncodedSolution>
38    where TEncodedSolution : class, IEncodedSolution {
39
40    [Storable] protected IValueParameter<DoubleValue> BestKnownQualityParameter { get; }
41    [Storable] protected IValueParameter<BoolValue> MaximizationParameter { get; }
42
43    public double BestKnownQuality {
44      get {
45        if (BestKnownQualityParameter.Value == null) return double.NaN;
46        return BestKnownQualityParameter.Value.Value;
47      }
48      set {
49        if (double.IsNaN(value)) {
50          BestKnownQualityParameter.Value = null;
51          return;
52        }
53        if (BestKnownQualityParameter.Value == null) BestKnownQualityParameter.Value = new DoubleValue(value);
54        else BestKnownQualityParameter.Value.Value = value;
55      }
56    }
57
58    public bool Maximization {
59      get { return MaximizationParameter.Value.Value; }
60      protected set {
61        if (Maximization == value) return;
62        MaximizationParameter.ForceValue(new BoolValue(value, @readonly: true));
63        OnMaximizationChanged();
64      }
65    }
66
67    [StorableConstructor]
68    protected SingleObjectiveProblem(StorableConstructorFlag _) : base(_) { }
69
70    protected SingleObjectiveProblem(SingleObjectiveProblem<TEncoding, TEncodedSolution> original, Cloner cloner)
71      : base(original, cloner) {
72      BestKnownQualityParameter = cloner.Clone(original.BestKnownQualityParameter);
73      MaximizationParameter = cloner.Clone(original.MaximizationParameter);
74      ParameterizeOperators();
75    }
76
77    protected SingleObjectiveProblem() : base() {
78
79      MaximizationParameter = new ValueParameter<BoolValue>("Maximization", "Whether the problem should be maximized (True) or minimized (False).", new BoolValue(false).AsReadOnly()) { Hidden = true, ReadOnly = true };
80      BestKnownQualityParameter = new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem.");
81
82      Parameters.Add(MaximizationParameter);
83      Parameters.Add(BestKnownQualityParameter);
84
85      Operators.Add(Evaluator);
86      Operators.Add(new SingleObjectiveAnalyzer<TEncodedSolution>());
87      Operators.Add(new SingleObjectiveImprover<TEncodedSolution>());
88      Operators.Add(new SingleObjectiveMoveEvaluator<TEncodedSolution>());
89      Operators.Add(new SingleObjectiveMoveGenerator<TEncodedSolution>());
90      Operators.Add(new SingleObjectiveMoveMaker<TEncodedSolution>());
91
92      ParameterizeOperators();
93    }
94
95    protected SingleObjectiveProblem(TEncoding encoding) : base(encoding) {
96      Parameters.Add(MaximizationParameter = new ValueParameter<BoolValue>("Maximization", "Set to false if the problem should be minimized.", new BoolValue(false).AsReadOnly()) { Hidden = true, ReadOnly = true });
97      Parameters.Add(BestKnownQualityParameter = new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
98
99      Operators.Add(Evaluator);
100      Operators.Add(new SingleObjectiveAnalyzer<TEncodedSolution>());
101      Operators.Add(new SingleObjectiveImprover<TEncodedSolution>());
102      Operators.Add(new SingleObjectiveMoveEvaluator<TEncodedSolution>());
103      Operators.Add(new SingleObjectiveMoveGenerator<TEncodedSolution>());
104      Operators.Add(new SingleObjectiveMoveMaker<TEncodedSolution>());
105
106      ParameterizeOperators();
107    }
108
109    [StorableHook(HookType.AfterDeserialization)]
110    private void AfterDeserialization() {
111      ParameterizeOperators();
112    }
113
114    public abstract double Evaluate(TEncodedSolution solution, IRandom random);
115    public virtual void Analyze(TEncodedSolution[] solutions, double[] qualities, ResultCollection results, IRandom random) { }
116    public virtual IEnumerable<TEncodedSolution> GetNeighbors(TEncodedSolution solution, IRandom random) {
117      return Enumerable.Empty<TEncodedSolution>();
118    }
119
120    public static bool IsBetter(bool maximization, double quality, double bestQuality) {
121      return (maximization && quality > bestQuality || !maximization && quality < bestQuality);
122    }
123
124    public virtual bool IsBetter(double quality, double bestQuality) {
125      return IsBetter(Maximization, quality, bestQuality);
126    }
127
128    protected Tuple<TEncodedSolution, double> GetBestSolution(TEncodedSolution[] solutions, double[] qualities) {
129      return GetBestSolution(solutions, qualities, Maximization);
130    }
131    public static Tuple<TEncodedSolution, double> GetBestSolution(TEncodedSolution[] solutions, double[] qualities, bool maximization) {
132      var zipped = solutions.Zip(qualities, (s, q) => new { Solution = s, Quality = q });
133      var best = (maximization ? zipped.OrderByDescending(z => z.Quality) : zipped.OrderBy(z => z.Quality)).First();
134      return Tuple.Create(best.Solution, best.Quality);
135    }
136
137    protected override void OnOperatorsChanged() {
138      if (Encoding != null) {
139        PruneMultiObjectiveOperators(Encoding);
140        var combinedEncoding = Encoding as CombinedEncoding;
141        if (combinedEncoding != null) {
142          foreach (var encoding in combinedEncoding.Encodings.ToList()) {
143            PruneMultiObjectiveOperators(encoding);
144          }
145        }
146      }
147      base.OnOperatorsChanged();
148    }
149
150    private void PruneMultiObjectiveOperators(IEncoding encoding) {
151      if (encoding.Operators.Any(x => x is IMultiObjectiveOperator && !(x is ISingleObjectiveOperator)))
152        encoding.Operators = encoding.Operators.Where(x => !(x is IMultiObjectiveOperator) || x is ISingleObjectiveOperator).ToList();
153
154      foreach (var multiOp in Encoding.Operators.OfType<IMultiOperator>()) {
155        foreach (var moOp in multiOp.Operators.Where(x => x is IMultiObjectiveOperator).ToList()) {
156          multiOp.RemoveOperator(moOp);
157        }
158      }
159    }
160
161    protected override void OnEvaluatorChanged() {
162      base.OnEvaluatorChanged();
163      ParameterizeOperators();
164    }
165
166    private void ParameterizeOperators() {
167      foreach (var op in Operators.OfType<ISingleObjectiveEvaluationOperator<TEncodedSolution>>())
168        op.EvaluateFunc = Evaluate;
169      foreach (var op in Operators.OfType<ISingleObjectiveAnalysisOperator<TEncodedSolution>>())
170        op.AnalyzeAction = Analyze;
171      foreach (var op in Operators.OfType<INeighborBasedOperator<TEncodedSolution>>())
172        op.GetNeighborsFunc = GetNeighbors;
173    }
174
175    #region ISingleObjectiveHeuristicOptimizationProblem Members
176    IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter {
177      get { return Parameters["Maximization"]; }
178    }
179    IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter {
180      get { return Parameters["BestKnownQuality"]; }
181    }
182    ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator {
183      get { return Evaluator; }
184    }
185    #endregion
186
187    public event EventHandler MaximizationChanged;
188    protected void OnMaximizationChanged() {
189      MaximizationChanged?.Invoke(this, EventArgs.Empty);
190    }
191  }
192}
Note: See TracBrowser for help on using the repository browser.