Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/EvaluationTracker.cs @ 17382

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

#2521: Refactored single-objective problems to use EvaluationResult instead of double as return type from Evaluate.

File size: 5.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 * and the BEACON Center for the Study of Evolution in Action.
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21#endregion
22
23using System;
24using System.Collections.Generic;
25using System.Linq;
26using System.Threading;
27using HEAL.Attic;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Encodings.BinaryVectorEncoding;
31using HeuristicLab.Optimization;
32
33namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
34  // This code is based off the publication
35  // B. W. Goldman and W. F. Punch, "Parameter-less Population Pyramid," GECCO, pp. 785–792, 2014
36  // and the original source code in C++11 available from: https://github.com/brianwgoldman/Parameter-less_Population_Pyramid
37  [StorableType("D5F1358D-C100-40CF-9BA5-E95F72F64D1A")]
38  internal sealed class EvaluationTracker : Item, ISingleObjectiveProblemDefinition<BinaryVectorEncoding, BinaryVector> {
39    [Storable]
40    private SingleObjectiveProblem<BinaryVectorEncoding, BinaryVector> problem;
41    [Storable]
42    private int maxEvaluations;
43
44    #region Properties
45    [Storable]
46    public double BestQuality {
47      get;
48      private set;
49    }
50    [Storable]
51    public int Evaluations {
52      get;
53      private set;
54    }
55    [Storable]
56    public int BestFoundOnEvaluation {
57      get;
58      private set;
59    }
60    [Storable]
61    public BinaryVector BestSolution {
62      get;
63      private set;
64    }
65
66    public BinaryVectorEncoding Encoding {
67      get { return problem.Encoding; }
68    }
69    #endregion
70
71
72    [StorableConstructor]
73    private EvaluationTracker(StorableConstructorFlag _) : base(_) { }
74
75    private EvaluationTracker(EvaluationTracker original, Cloner cloner)
76      : base(original, cloner) {
77      problem = cloner.Clone(original.problem);
78      maxEvaluations = original.maxEvaluations;
79      BestQuality = original.BestQuality;
80      Evaluations = original.Evaluations;
81      BestFoundOnEvaluation = original.BestFoundOnEvaluation;
82      BestSolution = cloner.Clone(original.BestSolution);
83    }
84    public override IDeepCloneable Clone(Cloner cloner) {
85      return new EvaluationTracker(this, cloner);
86    }
87
88    public EvaluationTracker(SingleObjectiveProblem<BinaryVectorEncoding, BinaryVector> problem, int maxEvaluations) {
89      this.problem = problem;
90      this.maxEvaluations = maxEvaluations;
91      BestSolution = new BinaryVector(problem.Encoding.Length);
92      BestQuality = double.NaN;
93      Evaluations = 0;
94      BestFoundOnEvaluation = 0;
95    }
96
97    public ISingleObjectiveEvaluationResult Evaluate(BinaryVector vector, IRandom random) {
98      return Evaluate(vector, random, CancellationToken.None);
99    }
100
101    public ISingleObjectiveEvaluationResult Evaluate(BinaryVector vector, IRandom random, CancellationToken cancellationToken) {
102      if (Evaluations >= maxEvaluations) throw new OperationCanceledException("Maximum Evaluation Limit Reached");
103      Evaluations++;
104
105      var evaluationResult = problem.Evaluate(vector, random);
106      double fitness = evaluationResult.Quality;
107      if (double.IsNaN(BestQuality) || problem.IsBetter(fitness, BestQuality)) {
108        BestQuality = fitness;
109        BestSolution = (BinaryVector)vector.Clone();
110        BestFoundOnEvaluation = Evaluations;
111      }
112      return evaluationResult;
113    }
114
115    public void Evaluate(ISingleObjectiveSolutionContext<BinaryVector> solutionContext, IRandom random) {
116      Evaluate(solutionContext, random, CancellationToken.None);
117    }
118    public void Evaluate(ISingleObjectiveSolutionContext<BinaryVector> solutionContext, IRandom random, CancellationToken cancellationToken) {
119      var evaluationResult = Evaluate(solutionContext.EncodedSolution, random, cancellationToken);
120      solutionContext.EvaluationResult = evaluationResult;
121    }
122
123    public bool Maximization {
124      get {
125        if (problem == null) return false;
126        return problem.Maximization;
127      }
128    }
129
130    public bool IsBetter(double quality, double bestQuality) {
131      return problem.IsBetter(quality, bestQuality);
132    }
133
134    public void Analyze(BinaryVector[] individuals, double[] qualities, ResultCollection results, IRandom random) {
135      problem.Analyze(individuals, qualities, results, random);
136    }
137
138    public void Analyze(ISingleObjectiveSolutionContext<BinaryVector>[] solutionContexts, ResultCollection results, IRandom random) {
139      var solutions = solutionContexts.Select(c => c.EncodedSolution).ToArray();
140      var qualities = solutionContexts.Select(c => c.EvaluationResult.Quality).ToArray();
141      Analyze(solutions, qualities, results, random);
142    }
143
144    public IEnumerable<BinaryVector> GetNeighbors(BinaryVector individual, IRandom random) {
145      return problem.GetNeighbors(individual, random);
146    }
147    public IEnumerable<ISingleObjectiveSolutionContext<BinaryVector>> GetNeighbors(ISingleObjectiveSolutionContext<BinaryVector> solutionContext, IRandom random) {
148      return GetNeighbors(solutionContext.EncodedSolution, random).Select(n => new SingleObjectiveSolutionContext<BinaryVector>(n));
149    }
150  }
151}
Note: See TracBrowser for help on using the repository browser.