Free cookie consent management tool by TermsFeed Policy Generator

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

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

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

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