Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.MetaOptimization (trunk integration)/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmRunsAnalyzer.cs @ 16724

Last change on this file since 16724 was 8589, checked in by jkarder, 12 years ago

#1727:

  • set the number of evaluated solutions to zero if the result is missing in the run
  • improved result lookup
File size: 16.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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 HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.ParameterConfigurationEncoding;
29using HeuristicLab.Operators;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33
34namespace HeuristicLab.Problems.MetaOptimization {
35  /// <summary>
36  /// TODO
37  /// </summary>
38  [Item("AlgorithmRunsAnalyzer", "TODO")]
39  [StorableClass]
40  public class AlgorithmRunsAnalyzer : SingleSuccessorOperator {
41    #region Parameter properties
42    public ILookupParameter<DoubleValue> QualityParameter {
43      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
44    }
45    public LookupParameter<IntValue> GenerationsParameter {
46      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
47    }
48    public LookupParameter<IntValue> RepetitionsParameter {
49      get { return (LookupParameter<IntValue>)Parameters[MetaOptimizationProblem.RepetitionsParameterName]; }
50    }
51    public ILookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
52      get { return (ILookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
53    }
54    public ILookupParameter<IItemList<IProblem>> ProblemsParameter {
55      get { return (ILookupParameter<IItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
56    }
57    public LookupParameter<DoubleArray> ReferenceQualityAveragesParameter {
58      get { return (LookupParameter<DoubleArray>)Parameters["ReferenceQualityAverages"]; }
59    }
60    public LookupParameter<DoubleArray> ReferenceQualityDeviationsParameter {
61      get { return (LookupParameter<DoubleArray>)Parameters["ReferenceQualityDeviations"]; }
62    }
63    public LookupParameter<DoubleArray> ReferenceEvaluatedSolutionAveragesParameter {
64      get { return (LookupParameter<DoubleArray>)Parameters["ReferenceEvaluatedSolutionAverages"]; }
65    }
66    public LookupParameter<ResultCollection> ResultsParameter {
67      get { return (LookupParameter<ResultCollection>)Parameters["Results"]; }
68    }
69    public ScopeTreeLookupParameter<IAlgorithm> AlgorithmParameter {
70      get { return (ScopeTreeLookupParameter<IAlgorithm>)Parameters["Algorithm"]; }
71    }
72    public ScopeTreeLookupParameter<IntValue> ProblemIndexParameter {
73      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["ProblemIndex"]; }
74    }
75    public ScopeTreeLookupParameter<IntValue> RepetitionIndexParameter {
76      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["RepetitionIndex"]; }
77    }
78    public LookupParameter<BoolValue> MaximizationParameter {
79      get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
80    }
81    public LookupParameter<DoubleValue> QualityWeightParameter {
82      get { return (LookupParameter<DoubleValue>)Parameters[MetaOptimizationProblem.QualityWeightParameterName]; }
83    }
84    public LookupParameter<DoubleValue> StandardDeviationWeightParameter {
85      get { return (LookupParameter<DoubleValue>)Parameters[MetaOptimizationProblem.StandardDeviationWeightParameterName]; }
86    }
87    public LookupParameter<DoubleValue> EvaluatedSolutionsWeightParameter {
88      get { return (LookupParameter<DoubleValue>)Parameters[MetaOptimizationProblem.EvaluatedSolutionsWeightParameterName]; }
89    }
90    private ScopeParameter CurrentScopeParameter {
91      get { return (ScopeParameter)Parameters["CurrentScope"]; }
92    }
93    public IScope CurrentScope {
94      get { return CurrentScopeParameter.ActualValue; }
95    }
96    public LookupParameter<StringValue> QualityMeasureNameParameter {
97      get { return (LookupParameter<StringValue>)Parameters[MetaOptimizationProblem.QualityMeasureNameName]; }
98    }
99    #endregion
100
101    #region Constructors and Cloning
102    public AlgorithmRunsAnalyzer()
103      : base() {
104      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used to initialize the new random permutation."));
105      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The evaluated quality of the ParameterVector."));
106      Parameters.Add(new LookupParameter<IntValue>("Generations", ""));
107      Parameters.Add(new LookupParameter<IntValue>(MetaOptimizationProblem.RepetitionsParameterName, "Number of evaluations on one problem."));
108      Parameters.Add(new LookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
109      Parameters.Add(new LookupParameter<IItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName, ""));
110      Parameters.Add(new LookupParameter<DoubleArray>("ReferenceQualityAverages", ""));
111      Parameters.Add(new LookupParameter<DoubleArray>("ReferenceQualityDeviations", ""));
112      Parameters.Add(new LookupParameter<DoubleArray>("ReferenceEvaluatedSolutionAverages", ""));
113      Parameters.Add(new LookupParameter<ResultCollection>("Results", ""));
114      Parameters.Add(new ScopeTreeLookupParameter<IAlgorithm>("Algorithm", "The finished algorithms containing Runs."));
115      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("ProblemIndex", "The index of the problem an algorithm was executed with."));
116      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("RepetitionIndex", "The index of the repetition"));
117      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Set to false if the problem should be minimized."));
118      Parameters.Add(new LookupParameter<DoubleValue>(MetaOptimizationProblem.QualityWeightParameterName));
119      Parameters.Add(new LookupParameter<DoubleValue>(MetaOptimizationProblem.StandardDeviationWeightParameterName));
120      Parameters.Add(new LookupParameter<DoubleValue>(MetaOptimizationProblem.EvaluatedSolutionsWeightParameterName));
121      Parameters.Add(new LookupParameter<StringValue>(MetaOptimizationProblem.QualityMeasureNameName));
122      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes represent the parents."));
123    }
124
125    [StorableConstructor]
126    protected AlgorithmRunsAnalyzer(bool deserializing) : base(deserializing) { }
127    protected AlgorithmRunsAnalyzer(AlgorithmRunsAnalyzer original, Cloner cloner) : base(original, cloner) { }
128    public override IDeepCloneable Clone(Cloner cloner) {
129      return new AlgorithmRunsAnalyzer(this, cloner);
130    }
131    [StorableHook(HookType.AfterDeserialization)]
132    private void AfterDeserialization() {
133      if (!Parameters.ContainsKey("CurrentScope")) Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes represent the parents.")); // backwards compatibility
134      if (!Parameters.ContainsKey(MetaOptimizationProblem.QualityMeasureNameName)) Parameters.Add(new LookupParameter<StringValue>(MetaOptimizationProblem.QualityMeasureNameName)); // backwards compatibility
135    }
136    #endregion
137
138    public override IOperation Apply() {
139      ParameterConfigurationTree parameterConfiguration = ParameterConfigurationParameter.ActualValue;
140      ItemArray<IAlgorithm> algorithms = AlgorithmParameter.ActualValue;
141      ItemArray<IntValue> problemIndices = ProblemIndexParameter.ActualValue;
142      ItemArray<IntValue> repetitionIndices = RepetitionIndexParameter.ActualValue;
143      IEnumerable<string> parameterNames = parameterConfiguration.GetOptimizedParameterNames();
144      IItemList<IProblem> problems = ProblemsParameter.ActualValue;
145      bool maximization = MaximizationParameter.ActualValue.Value;
146      int repetitions = RepetitionsParameter.ActualValue.Value;
147      double qualityWeight = QualityWeightParameter.ActualValue.Value;
148      double standardDeviationWeight = StandardDeviationWeightParameter.ActualValue.Value;
149      double evaluatedSolutionsWeight = EvaluatedSolutionsWeightParameter.ActualValue.Value;
150      string qualityMeasureName = QualityMeasureNameParameter.ActualValue.Value;
151      var resultNames = new List<string> { qualityMeasureName, "Execution Time", "EvaluatedSolutions" };
152      int currentGeneration = GenerationsParameter.ActualValue != null ? GenerationsParameter.ActualValue.Value : 0;
153      double[] referenceQualityAverages;
154      double[] referenceQualityDeviations;
155      double[] referenceEvaluatedSolutionAverages;
156      GetReferenceValues(problems.Count, out referenceQualityAverages, out referenceQualityDeviations, out referenceEvaluatedSolutionAverages);
157
158      ResultCollection results = ResultsParameter.ActualValue;
159
160      if (algorithms.All(x => x.Runs.Count == 1)) {
161        var runs = new RunCollection();
162        var qualities = new double[problems.Count][];
163        var executionTimes = new TimeSpan[problems.Count][];
164        var evaluatedSolutions = new int[problems.Count][];
165
166        for (int i = 0; i < problems.Count; i++) {
167          qualities[i] = new double[repetitions];
168          evaluatedSolutions[i] = new int[repetitions];
169          executionTimes[i] = new TimeSpan[repetitions];
170        }
171
172        for (int i = 0; i < algorithms.Length; i++) {
173          int problemIndex = problemIndices[i].Value;
174          int repetitionIndex = repetitionIndices[i].Value;
175
176          IRun run = (IRun)algorithms[i].Runs.Single().Clone();
177          MetaOptimizationUtil.ClearResults(run, resultNames);
178          MetaOptimizationUtil.ClearParameters(run, parameterNames);
179          run.Results.Add("Meta-FromCache", new BoolValue(false));
180          run.Results.Add("Meta-Generation", new IntValue(currentGeneration));
181          run.Results.Add("Meta-ProblemIndex", new IntValue(problemIndex));
182          run.Name = string.Format("{0} Problem {1} Run {2}", parameterConfiguration.ParameterInfoString, problemIndex, repetitionIndex);
183
184          DoubleValue quality;
185          if (TryGetResultValue(run.Results, qualityMeasureName, out quality))
186            qualities[problemIndex][repetitionIndex] = quality.Value;
187
188          TimeSpanValue execTime;
189          if (TryGetResultValue(run.Results, "Execution Time", out execTime))
190            executionTimes[problemIndex][repetitionIndex] = execTime.Value;
191
192          IntValue evalSolutions;
193          if (TryGetResultValue(run.Results, "EvaluatedSolutions", out evalSolutions))
194            evaluatedSolutions[problemIndex][repetitionIndex] = evalSolutions.Value;
195
196          runs.Add(run);
197        }
198
199        parameterConfiguration.AverageExecutionTimes = new ItemList<TimeSpanValue>(executionTimes.Select(t => new TimeSpanValue(TimeSpan.FromMilliseconds(t.Average(ts => ts.TotalMilliseconds)))));
200        parameterConfiguration.AverageEvaluatedSolutions = new DoubleArray(evaluatedSolutions.Select(x => x.Average()).ToArray());
201        parameterConfiguration.Repetitions = new IntValue(repetitions);
202        parameterConfiguration.AverageQualities = new DoubleArray(qualities.Select(q => q.Average()).ToArray());
203
204        if (maximization)
205          parameterConfiguration.BestQualities = new DoubleArray(qualities.Select(q => q.Max()).ToArray());
206        else
207          parameterConfiguration.BestQualities = new DoubleArray(qualities.Select(q => q.Min()).ToArray());
208
209        if (maximization)
210          parameterConfiguration.WorstQualities = new DoubleArray(qualities.Select(q => q.Min()).ToArray());
211        else
212          parameterConfiguration.WorstQualities = new DoubleArray(qualities.Select(q => q.Max()).ToArray());
213
214        parameterConfiguration.QualityVariances = new DoubleArray(qualities.Select(q => q.Variance()).ToArray());
215        parameterConfiguration.QualityStandardDeviations = new DoubleArray(qualities.Select(q => q.StandardDeviation()).ToArray());
216        parameterConfiguration.Runs = runs;
217
218        this.QualityParameter.ActualValue = new DoubleValue(MetaOptimizationUtil.Normalize(parameterConfiguration, referenceQualityAverages, referenceQualityDeviations, referenceEvaluatedSolutionAverages, qualityWeight, standardDeviationWeight, evaluatedSolutionsWeight, maximization));
219      } else {
220        // something terrible happened -> most probably due to invalid parameters.
221        // penalty with worst quality from latest generation!
222        double penaltyValue;
223        if (maximization)
224          penaltyValue = results.ContainsKey("CurrentWorstQuality") ? ((DoubleValue)results["CurrentWorstQuality"].Value).Value : referenceQualityAverages.Min();
225        else
226          penaltyValue = results.ContainsKey("CurrentWorstQuality") ? ((DoubleValue)results["CurrentWorstQuality"].Value).Value : referenceQualityAverages.Max();
227
228        this.QualityParameter.ActualValue = new DoubleValue(penaltyValue);
229        parameterConfiguration.Quality = new DoubleValue(penaltyValue);
230
231        parameterConfiguration.AverageExecutionTimes = new ItemList<TimeSpanValue>(Enumerable.Repeat(new TimeSpanValue(TimeSpan.Zero), problems.Count));
232        parameterConfiguration.AverageEvaluatedSolutions = new DoubleArray(Enumerable.Repeat(0.0, problems.Count).ToArray());
233        parameterConfiguration.Repetitions = new IntValue(repetitions);
234        parameterConfiguration.AverageQualities = new DoubleArray(Enumerable.Repeat(0.0, problems.Count).ToArray());
235        parameterConfiguration.BestQualities = new DoubleArray(Enumerable.Repeat(0.0, problems.Count).ToArray());
236        parameterConfiguration.WorstQualities = new DoubleArray(Enumerable.Repeat(0.0, problems.Count).ToArray());
237        parameterConfiguration.QualityVariances = new DoubleArray(Enumerable.Repeat(0.0, problems.Count).ToArray());
238        parameterConfiguration.QualityStandardDeviations = new DoubleArray(Enumerable.Repeat(0.0, problems.Count).ToArray());
239        parameterConfiguration.Runs = null;
240      }
241
242      // in OSGA there are more subscopes, so be careful which to delete
243      CurrentScope.SubScopes.RemoveAll(x => x.Variables.Count(v => (v.Name == "RepetitionCount")) == 1);
244
245      return base.Apply();
246    }
247
248    private bool TryGetResultValue<T>(IDictionary<string, IItem> results, string resultName, out T resultValue) {
249      IDictionary<string, IItem> currentResults = results;
250      string[] tokens = resultName.Split('.');
251      T currentResultValue = default(T);
252      bool found = true;
253
254      foreach (var token in tokens) {
255        if (currentResults != null && currentResults.ContainsKey(token)) {
256          currentResultValue = (T)currentResults[token];
257          currentResults = currentResultValue as IDictionary<string, IItem>;
258        } else {
259          found = false;
260          break;
261        }
262      }
263
264      resultValue = found ? currentResultValue : default(T);
265      return found;
266    }
267
268    private void GetReferenceValues(int problemsCount, out double[] referenceQualityAverages, out double[] referenceQualityDeviations, out double[] referenceEvaluatedSolutionAverages) {
269      if (ReferenceQualityAveragesParameter.ActualValue == null) {
270        // this is generation zero. no reference qualities for normalization have been calculated yet. in this special case the ReferenceQualityAnalyzer will do the normalization
271        referenceQualityAverages = new double[problemsCount];
272        referenceQualityDeviations = new double[problemsCount];
273        referenceEvaluatedSolutionAverages = new double[problemsCount];
274        for (int i = 0; i < referenceQualityAverages.Length; i++) {
275          referenceQualityAverages[i] = 1;
276          referenceQualityDeviations[i] = 1;
277          referenceEvaluatedSolutionAverages[i] = 1;
278        }
279      } else {
280        referenceQualityAverages = ReferenceQualityAveragesParameter.ActualValue.ToArray();
281        referenceQualityDeviations = ReferenceQualityDeviationsParameter.ActualValue.ToArray();
282        referenceEvaluatedSolutionAverages = ReferenceEvaluatedSolutionAveragesParameter.ActualValue.ToArray();
283      }
284    }
285  }
286}
Note: See TracBrowser for help on using the repository browser.