Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ParameterConfigurationEncoding/HeuristicLab.Encodings.ParameterConfigurationEncoding/3.3/ParameterConfigurationTree.cs @ 8524

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

#1853:

  • added problem instance selection to CreateExperimentDialog
  • adopted experiment creation
  • minor code improvements
File size: 15.0 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;
24using System.Collections.Generic;
25using System.Linq;
26using System.Text;
27using System.Threading;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HeuristicLab.Optimization;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.Problems.Instances;
34
35namespace HeuristicLab.Encodings.ParameterConfigurationEncoding {
36  [Item("ParameterConfigurationTree", "Represents a parameter configuration.")]
37  [StorableClass]
38  public class ParameterConfigurationTree : ParameterizedValueConfiguration, IEnumerable {
39    [Storable]
40    private DoubleValue quality;
41    public DoubleValue Quality {
42      get { return quality; }
43      set {
44        if (quality != value) {
45          quality = value;
46          OnQualityChanged();
47        }
48      }
49    }
50
51    [Storable]
52    private DoubleArray normalizedQualityAverages;
53    public DoubleArray NormalizedQualityAverages {
54      get { return normalizedQualityAverages; }
55      set {
56        if (normalizedQualityAverages != value) {
57          normalizedQualityAverages = value;
58        }
59      }
60    }
61
62    [Storable]
63    private DoubleArray normalizedQualityDeviations;
64    public DoubleArray NormalizedQualityDeviations {
65      get { return normalizedQualityDeviations; }
66      set {
67        if (normalizedQualityDeviations != value) {
68          normalizedQualityDeviations = value;
69        }
70      }
71    }
72
73    [Storable]
74    private DoubleArray normalizedEvaluatedSolutions;
75    public DoubleArray NormalizedEvaluatedSolutions {
76      get { return normalizedEvaluatedSolutions; }
77      set {
78        if (normalizedEvaluatedSolutions != value) {
79          normalizedEvaluatedSolutions = value;
80        }
81      }
82    }
83
84    [Storable]
85    private DoubleArray bestQualities;
86    public DoubleArray BestQualities {
87      get { return bestQualities; }
88      set {
89        if (bestQualities != value) {
90          bestQualities = value;
91        }
92      }
93    }
94
95    [Storable]
96    private DoubleArray averageQualities;
97    public DoubleArray AverageQualities {
98      get { return averageQualities; }
99      set { averageQualities = value; }
100    }
101
102    [Storable]
103    private DoubleArray worstQualities;
104    public DoubleArray WorstQualities {
105      get { return worstQualities; }
106      set { worstQualities = value; }
107    }
108
109    [Storable]
110    private DoubleArray qualityVariances;
111    public DoubleArray QualityVariances {
112      get { return qualityVariances; }
113      set { qualityVariances = value; }
114    }
115
116    [Storable]
117    private DoubleArray qualityStandardDeviations;
118    public DoubleArray QualityStandardDeviations {
119      get { return qualityStandardDeviations; }
120      set { qualityStandardDeviations = value; }
121    }
122
123    [Storable]
124    private ItemList<TimeSpanValue> averageExecutionTimes;
125    public ItemList<TimeSpanValue> AverageExecutionTimes {
126      get { return averageExecutionTimes; }
127      set { averageExecutionTimes = value; }
128    }
129
130    [Storable]
131    private DoubleArray averageEvaluatedSolutions;
132    public DoubleArray AverageEvaluatedSolutions {
133      get { return averageEvaluatedSolutions; }
134      set { averageEvaluatedSolutions = value; }
135    }
136
137    [Storable]
138    private IntValue repetitions;
139    public IntValue Repetitions {
140      get { return repetitions; }
141      set { repetitions = value; }
142    }
143
144    [Storable]
145    protected RunCollection runs;
146    public RunCollection Runs {
147      get { return runs; }
148      set { runs = value; }
149    }
150
151    [Storable]
152    protected IDictionary<string, IItem> parameters;
153    public IDictionary<string, IItem> Parameters {
154      get { return parameters; }
155      set { parameters = value; }
156    }
157
158    [Storable]
159    private double experimentGenerationProgress;
160    public double ExperimentGenerationProgress {
161      get { return experimentGenerationProgress; }
162      private set {
163        if (experimentGenerationProgress != value) {
164          experimentGenerationProgress = value;
165          OnExperimentGenerationProgressChanged();
166        }
167      }
168    }
169
170    public ParameterizedValueConfiguration AlgorithmConfiguration {
171      get {
172        return this.ParameterConfigurations.ElementAt(0).ValueConfigurations.First() as ParameterizedValueConfiguration;
173      }
174    }
175
176    public ParameterizedValueConfiguration ProblemConfiguration {
177      get {
178        return this.ParameterConfigurations.ElementAt(1).ValueConfigurations.First() as ParameterizedValueConfiguration;
179      }
180    }
181
182    #region Constructors and Cloning
183    [StorableConstructor]
184    protected ParameterConfigurationTree(bool deserializing) : base(deserializing) { }
185    protected ParameterConfigurationTree(ParameterConfigurationTree original, Cloner cloner)
186      : base(original, cloner) {
187      this.quality = cloner.Clone(original.quality);
188      this.normalizedQualityAverages = cloner.Clone(original.normalizedQualityAverages);
189      this.normalizedQualityDeviations = cloner.Clone(original.normalizedQualityDeviations);
190      this.normalizedEvaluatedSolutions = cloner.Clone(original.normalizedEvaluatedSolutions);
191      this.bestQualities = cloner.Clone(original.BestQualities);
192      this.averageQualities = cloner.Clone(original.averageQualities);
193      this.worstQualities = cloner.Clone(original.worstQualities);
194      this.qualityStandardDeviations = cloner.Clone(original.qualityStandardDeviations);
195      this.qualityVariances = cloner.Clone(original.qualityVariances);
196      this.averageExecutionTimes = cloner.Clone(original.averageExecutionTimes);
197      this.averageEvaluatedSolutions = cloner.Clone(original.averageEvaluatedSolutions);
198      this.repetitions = cloner.Clone(original.repetitions);
199      this.runs = cloner.Clone(original.runs);
200      this.parameters = new Dictionary<string, IItem>();
201      if (original.parameters != null) {
202        foreach (var p in original.parameters) {
203          this.parameters.Add(p.Key, cloner.Clone(p.Value));
204        }
205      }
206    }
207    public ParameterConfigurationTree() : base() { }
208    public ParameterConfigurationTree(IAlgorithm algorithm, IProblem problem)
209      : base(null, algorithm.GetType(), false) {
210      this.Optimize = false;
211      this.IsOptimizable = false;
212      this.parameters = new Dictionary<string, IItem>();
213      this.Name = algorithm.ItemName;
214
215      var algproblemitem = new AlgorithmProblemItem();
216      algproblemitem.AlgorithmParameter.Value = algorithm;
217      algproblemitem.ProblemParameter.Value = problem;
218      this.discoverValidValues = false;
219
220      this.parameterConfigurations.Add(new SingleValuedParameterConfiguration("Algorithm", algproblemitem.AlgorithmParameter));
221      this.parameterConfigurations.Add(new SingleValuedParameterConfiguration("Problem", algproblemitem.ProblemParameter));
222
223      // problems can be modified in the list of problem instances, so the parameters which are not Optimize=true,
224      // must not be modifiable in the parameter configuration tree. otherwise the parameter values would be ambiguous
225      ProblemConfiguration.ValuesReadOnly = true;
226    }
227
228    public override IDeepCloneable Clone(Cloner cloner) {
229      return new ParameterConfigurationTree(this, cloner);
230    }
231
232    [StorableHook(HookType.AfterDeserialization)]
233    private void AfterDeserialization() {
234      if (ProblemConfiguration != null) ProblemConfiguration.ValuesReadOnly = true;
235    }
236    #endregion
237
238    public virtual void CollectResultValues(IDictionary<string, IItem> values) {
239      values.Add("RunsAverageExecutionTimes", AverageExecutionTimes);
240      values.Add("RunsAverageEvaluatedSolutions", AverageEvaluatedSolutions);
241      values.Add("Repetitions", Repetitions);
242      values.Add("RunsBestQualities", BestQualities);
243      values.Add("RunsAverageQualities", AverageQualities);
244      values.Add("RunsWorstQualities", WorstQualities);
245      values.Add("RunsQualityVariances", QualityVariances);
246      values.Add("RunsQualityStandardDeviations", QualityStandardDeviations);
247      values.Add("QualitiesNormalized", NormalizedQualityAverages);
248      values.Add("AverageQualityNormalized", Quality);
249      values.Add("Runs", Runs);
250    }
251
252    public virtual void CollectParameterValues(IDictionary<string, IItem> values) {
253      foreach (var p in parameters) {
254        values.Add(p);
255      }
256    }
257
258    #region Events
259    public event EventHandler QualityChanged;
260    private void OnQualityChanged() {
261      var handler = QualityChanged;
262      if (handler != null) handler(this, EventArgs.Empty);
263    }
264
265    private void Quality_ValueChanged(object sender, EventArgs e) {
266      OnQualityChanged();
267    }
268
269    public event EventHandler ExperimentGenerationProgressChanged;
270    private void OnExperimentGenerationProgressChanged() {
271      var handler = ExperimentGenerationProgressChanged;
272      if (handler != null) handler(this, EventArgs.Empty);
273    }
274    #endregion
275
276    public override void Parameterize(IParameterizedItem item) {
277      this.parameters.Clear();
278      var algorithm = (IAlgorithm)item;
279      var problem = algorithm.Problem;
280
281      ProblemConfiguration.Parameterize(problem);
282      AlgorithmConfiguration.Parameterize(algorithm);
283
284      algorithm.CollectParameterValues(this.Parameters);
285    }
286
287    public Experiment GenerateExperiment(IAlgorithm algorithm, bool createBatchRuns, int repetitions, Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>> problemInstances, CancellationToken ct) {
288      Experiment experiment = new Experiment();
289      var algorithms = new List<IAlgorithm>(1 + problemInstances.Values.Count) { (IAlgorithm)algorithm.Clone() };
290      foreach (var provider in problemInstances) {
291        foreach (var descriptor in provider.Value) {
292          var alg = (IAlgorithm)algorithm.Clone();
293          ProblemInstanceManager.LoadData(provider.Key, descriptor, (IProblemInstanceConsumer)alg.Problem);
294          algorithms.Add(alg);
295        }
296      }
297      ExperimentGenerationProgress = 0;
298      foreach (var alg in algorithms) {
299        foreach (ParameterizedValueConfiguration combination in this) {
300          ct.ThrowIfCancellationRequested();
301          var clonedAlg = (IAlgorithm)alg.Clone();
302          clonedAlg.Name = combination.ParameterInfoString;
303          combination.Parameterize(clonedAlg);
304          clonedAlg.StoreAlgorithmInEachRun = false;
305          if (createBatchRuns) {
306            BatchRun batchRun = new BatchRun(string.Format("BatchRun: {0}", combination.ParameterInfoString));
307            batchRun.Optimizer = clonedAlg;
308            batchRun.Repetitions = repetitions;
309            experiment.Optimizers.Add(batchRun);
310          } else {
311            experiment.Optimizers.Add(clonedAlg);
312          }
313          ExperimentGenerationProgress = (double)experiment.Optimizers.Count / (this.GetCombinationCount(0) * algorithms.Count);
314        }
315      }
316      return experiment;
317    }
318
319    public Experiment GenerateExperiment(IAlgorithm algorithm) {
320      return GenerateExperiment(algorithm, false, 0, null, CancellationToken.None);
321    }
322
323    public Experiment GenerateExperiment(IAlgorithm algorithm, bool createBatchRuns, int repetitions) {
324      return GenerateExperiment(algorithm, createBatchRuns, repetitions, null, CancellationToken.None);
325    }
326
327    public IEnumerator GetEnumerator() {
328      IEnumerator enumerator = new ParameterCombinationsEnumerator(this);
329      enumerator.Reset();
330      return enumerator;
331    }
332
333    /// <summary>
334    /// returns the number of possible parameter combinations
335    /// </summary>
336    /// <param name="max">algorithm stops counting when max is reached. zero for infinite counting</param>
337    /// <returns></returns>
338    public long GetCombinationCount(long max) {
339      long cnt = 0;
340      foreach (var c in this) {
341        cnt++;
342        if (max > 0 && cnt >= max) {
343          return cnt;
344        }
345      }
346      return cnt;
347    }
348
349    public IOptimizable GetRandomOptimizable(IRandom random) {
350      List<IOptimizable> allOptimizables = GetAllOptimizables();
351      return allOptimizables[random.Next(allOptimizables.Count)];
352    }
353
354    public override string ToString() {
355      return this.Name;
356    }
357
358    public IRun ToRun(bool clearParameters) {
359      return ToRun(this.ParameterInfoString, clearParameters);
360    }
361
362    public IRun ToRun(string name, bool clearParameters) {
363      IRun run = new Run();
364      run.Name = name;
365      this.CollectResultValues(run.Results);
366      this.CollectParameterValues(run.Parameters);
367      if (clearParameters) ClearParameters(run, this.GetOptimizedParameterNames());
368      return run;
369    }
370
371    public override string ParameterInfoString {
372      get {
373        string algorithmInfo = this.AlgorithmConfiguration.ParameterInfoString;
374        string problemInfo = this.ProblemConfiguration.ParameterInfoString;
375        var sb = new StringBuilder();
376        if (!string.IsNullOrEmpty(algorithmInfo)) {
377          sb.Append("Algorithm (");
378          sb.Append(algorithmInfo);
379          sb.Append(")");
380        }
381        if (!string.IsNullOrEmpty(problemInfo)) {
382          if (sb.Length > 0)
383            sb.Append(", ");
384          sb.Append("Problem( ");
385          sb.Append(problemInfo);
386          sb.Append(")");
387        }
388        return sb.ToString();
389      }
390    }
391
392    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
393      AlgorithmConfiguration.CollectOptimizedParameterNames(parameterNames, string.Empty);
394      ProblemConfiguration.CollectOptimizedParameterNames(parameterNames, string.Empty);
395    }
396
397    #region Helpers
398    /// <summary>
399    /// Removes those parameters from the run which are not declared in parametersToKeep
400    /// </summary>
401    private void ClearParameters(IRun run, IEnumerable<string> parametersToKeep) {
402      var parametersToRemove = new List<string>();
403      foreach (var parameter in run.Parameters) {
404        if (!parametersToKeep.Contains(parameter.Key))
405          parametersToRemove.Add(parameter.Key);
406      }
407      foreach (var parameter in parametersToRemove)
408        run.Parameters.Remove(parameter);
409    }
410    #endregion
411  }
412}
Note: See TracBrowser for help on using the repository browser.