Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file was 17745, checked in by mkommend, 4 years ago

#2971: Added first draft of results implementation and problem adaptation.

File size: 10.2 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>
[17699]38    where TEncoding : class, IEncoding
[16751]39    where TEncodedSolution : class, IEncodedSolution {
[11990]40
[17356]41    [Storable] protected IValueParameter<DoubleValue> BestKnownQualityParameter { get; private set; }
42    [Storable] protected IValueParameter<BoolValue> MaximizationParameter { get; private set; }
[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;
[17567]63        MaximizationParameter.Value = new BoolValue(value, @readonly: true);
[17270]64      }
65    }
66
[10753]67    [StorableConstructor]
[16723]68    protected SingleObjectiveProblem(StorableConstructorFlag _) : base(_) { }
[10753]69
[16751]70    protected SingleObjectiveProblem(SingleObjectiveProblem<TEncoding, TEncodedSolution> original, Cloner cloner)
[10753]71      : base(original, cloner) {
[17270]72      BestKnownQualityParameter = cloner.Clone(original.BestKnownQualityParameter);
73      MaximizationParameter = cloner.Clone(original.MaximizationParameter);
[17570]74      Parameterize();
[17546]75      RegisterEventHandlers();
[10753]76    }
[17279]77
[16806]78    protected SingleObjectiveProblem(TEncoding encoding) : base(encoding) {
[17270]79      Parameters.Add(MaximizationParameter = new ValueParameter<BoolValue>("Maximization", "Set to false if the problem should be minimized.", new BoolValue(false).AsReadOnly()) { Hidden = true, ReadOnly = true });
80      Parameters.Add(BestKnownQualityParameter = new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
[13396]81
82      Operators.Add(Evaluator);
[16751]83      Operators.Add(new SingleObjectiveAnalyzer<TEncodedSolution>());
84      Operators.Add(new SingleObjectiveImprover<TEncodedSolution>());
85      Operators.Add(new SingleObjectiveMoveEvaluator<TEncodedSolution>());
86      Operators.Add(new SingleObjectiveMoveGenerator<TEncodedSolution>());
[17699]87      Operators.Add(new SingleObjectiveMoveMaker());
[13396]88
[17570]89      Parameterize();
[17546]90      RegisterEventHandlers();
[13396]91    }
92
[10753]93    [StorableHook(HookType.AfterDeserialization)]
94    private void AfterDeserialization() {
[17570]95      Parameterize();
[17546]96      RegisterEventHandlers();
[10753]97    }
98
[17382]99    public ISingleObjectiveEvaluationResult Evaluate(TEncodedSolution solution, IRandom random) {
[17320]100      return Evaluate(solution, random, CancellationToken.None);
101    }
[17382]102    public abstract ISingleObjectiveEvaluationResult Evaluate(TEncodedSolution solution, IRandom random, CancellationToken cancellationToken);
[17363]103
[17366]104    public void Evaluate(ISingleObjectiveSolutionContext<TEncodedSolution> solutionContext, IRandom random) {
[17363]105      Evaluate(solutionContext, random, CancellationToken.None);
106    }
107    public virtual void Evaluate(ISingleObjectiveSolutionContext<TEncodedSolution> solutionContext, IRandom random, CancellationToken cancellationToken) {
[17382]108      var evaluationResult = Evaluate(solutionContext.EncodedSolution, random, cancellationToken);
109      solutionContext.EvaluationResult = evaluationResult;
[17363]110    }
111
[17745]112    public virtual void Analyze(ISingleObjectiveSolutionContext<TEncodedSolution>[] solutionContexts, IRandom random) { }
[17363]113
114    public virtual IEnumerable<TEncodedSolution> GetNeighbors(TEncodedSolution solutions, IRandom random) {
[16751]115      return Enumerable.Empty<TEncodedSolution>();
[11786]116    }
[17363]117    public virtual IEnumerable<ISingleObjectiveSolutionContext<TEncodedSolution>> GetNeighbors(ISingleObjectiveSolutionContext<TEncodedSolution> solutionContext, IRandom random) {
118      return GetNeighbors(solutionContext.EncodedSolution, random).Select(n => new SingleObjectiveSolutionContext<TEncodedSolution>(n));
119    }
[10753]120
[17279]121    public static bool IsBetter(bool maximization, double quality, double bestQuality) {
122      return (maximization && quality > bestQuality || !maximization && quality < bestQuality);
123    }
124
[13336]125    public virtual bool IsBetter(double quality, double bestQuality) {
[17279]126      return IsBetter(Maximization, quality, bestQuality);
[11970]127    }
128
[17612]129    public virtual bool IsBetter(ISingleObjectiveSolutionContext<TEncodedSolution> solution, ISingleObjectiveSolutionContext<TEncodedSolution> otherSolution) {
130      return IsBetter(Maximization, solution.EvaluationResult.Quality, otherSolution.EvaluationResult.Quality);
131    }
132
[17363]133    //TODO refactor to solution contexts
[17522]134    protected ISingleObjectiveSolutionContext<TEncodedSolution> GetBest(ISingleObjectiveSolutionContext<TEncodedSolution>[] solutionContexts) {
135      return Maximization ? solutionContexts.MaxItems(x => x.EvaluationResult.Quality).First()
136        : solutionContexts.MinItems(x => x.EvaluationResult.Quality).First();
137    }
[16751]138    protected Tuple<TEncodedSolution, double> GetBestSolution(TEncodedSolution[] solutions, double[] qualities) {
[16692]139      return GetBestSolution(solutions, qualities, Maximization);
140    }
[16751]141    public static Tuple<TEncodedSolution, double> GetBestSolution(TEncodedSolution[] solutions, double[] qualities, bool maximization) {
[16692]142      var zipped = solutions.Zip(qualities, (s, q) => new { Solution = s, Quality = q });
143      var best = (maximization ? zipped.OrderByDescending(z => z.Quality) : zipped.OrderBy(z => z.Quality)).First();
144      return Tuple.Create(best.Solution, best.Quality);
145    }
146
147    protected override void OnOperatorsChanged() {
148      if (Encoding != null) {
149        PruneMultiObjectiveOperators(Encoding);
150        var combinedEncoding = Encoding as CombinedEncoding;
151        if (combinedEncoding != null) {
152          foreach (var encoding in combinedEncoding.Encodings.ToList()) {
153            PruneMultiObjectiveOperators(encoding);
154          }
155        }
156      }
[16801]157      base.OnOperatorsChanged();
[16692]158    }
159
160    private void PruneMultiObjectiveOperators(IEncoding encoding) {
161      if (encoding.Operators.Any(x => x is IMultiObjectiveOperator && !(x is ISingleObjectiveOperator)))
162        encoding.Operators = encoding.Operators.Where(x => !(x is IMultiObjectiveOperator) || x is ISingleObjectiveOperator).ToList();
163
164      foreach (var multiOp in Encoding.Operators.OfType<IMultiOperator>()) {
165        foreach (var moOp in multiOp.Operators.Where(x => x is IMultiObjectiveOperator).ToList()) {
166          multiOp.RemoveOperator(moOp);
167        }
168      }
169    }
170
[11396]171    protected override void OnEvaluatorChanged() {
172      base.OnEvaluatorChanged();
[17570]173      Evaluator.QualityParameter.ActualNameChanged += QualityParameterOnActualNameChanged;
174    }
175
176    protected virtual void QualityParameterOnActualNameChanged(object sender, EventArgs e) {
[11739]177      ParameterizeOperators();
[11396]178    }
179
[17570]180    protected override void ParameterizeOperators() {
181      base.ParameterizeOperators();
182      Parameterize();
183    }
184
185    private void Parameterize() {
[16751]186      foreach (var op in Operators.OfType<ISingleObjectiveEvaluationOperator<TEncodedSolution>>())
[17363]187        op.Evaluate = Evaluate;
[16751]188      foreach (var op in Operators.OfType<ISingleObjectiveAnalysisOperator<TEncodedSolution>>())
[17363]189        op.Analyze = Analyze;
[16751]190      foreach (var op in Operators.OfType<INeighborBasedOperator<TEncodedSolution>>())
[17363]191        op.GetNeighbors = GetNeighbors;
[17570]192      foreach (var op in Operators.OfType<ISolutionSimilarityCalculator>()) {
193        op.SolutionVariableName = Encoding.Name;
194        op.QualityVariableName = Evaluator.QualityParameter.ActualName;
195      }
[17697]196      foreach (var op in Operators.OfType<ISingleObjectiveImprovementOperator>()) {
197        op.SolutionParameter.ActualName = Encoding.Name;
198        op.SolutionParameter.Hidden = true;
199      }
200      foreach (var op in Operators.OfType<ISingleObjectivePathRelinker>()) {
201        op.ParentsParameter.ActualName = Encoding.Name;
202        op.ParentsParameter.Hidden = true;
203      }
[11393]204    }
205
[17546]206    private void RegisterEventHandlers() {
207      BoolValueParameterChangeHandler.Create(MaximizationParameter, OnMaximizationChanged);
208    }
209
[11753]210    #region ISingleObjectiveHeuristicOptimizationProblem Members
211    IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter {
212      get { return Parameters["Maximization"]; }
213    }
214    IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter {
215      get { return Parameters["BestKnownQuality"]; }
216    }
217    ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator {
218      get { return Evaluator; }
219    }
220    #endregion
[17317]221
222    public event EventHandler MaximizationChanged;
223    protected void OnMaximizationChanged() {
224      MaximizationChanged?.Invoke(this, EventArgs.Empty);
225    }
[10753]226  }
227}
Note: See TracBrowser for help on using the repository browser.