Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystem.cs @ 12957

Last change on this file since 12957 was 12957, checked in by abeham, 9 years ago

#2457: Worked on expert system

  • using newly created ERT helper class
File size: 10.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.ComponentModel;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using HeuristicLab.Analysis;
28using HeuristicLab.Core;
29using HeuristicLab.Optimization;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Common;
32using HeuristicLab.Common.Resources;
33using HeuristicLab.Data;
34
35namespace HeuristicLab.OptimizationExpertSystem {
36  [Item("Expert-System", "Currently in experimental phase, an expert system that makes algorithm suggestions based on fitness landscape analysis features and an optimization knowledge base.")]
37  [StorableClass]
38  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 119)]
39  public sealed class ExpertSystem : NamedItem, IStorableContent, INotifyPropertyChanged {
40
41    public string Filename { get; set; }
42
43    public static new Image StaticItemImage {
44      get { return VSImageLibrary.Library; }
45    }
46
47    [Storable]
48    private int maximumEvaluations;
49    public int MaximumEvaluations {
50      get { return maximumEvaluations; }
51      set {
52        if (maximumEvaluations == value) return;
53        maximumEvaluations = value;
54        OnPropertyChanged("MaximumEvaluations");
55        UpdateSuggestions();
56      }
57    }
58
59    [Storable]
60    private RunCollection runs;
61    public RunCollection Runs {
62      get { return runs; }
63    }
64
65    [Storable]
66    private ItemList<IAlgorithm> algorithmInstances;
67    public ItemList<IAlgorithm> AlgorithmInstances {
68      get { return algorithmInstances; }
69      set {
70        if (algorithmInstances == value) return;
71        algorithmInstances = value;
72        OnPropertyChanged("AlgorithmInstances");
73      }
74    }
75
76    [Storable]
77    private ISingleObjectiveHeuristicOptimizationProblem problem;
78    public ISingleObjectiveHeuristicOptimizationProblem Problem {
79      get { return problem; }
80      set {
81        if (problem == value) return;
82        problem = value;
83        OnPropertyChanged("Problem");
84        UpdateSuggestions();
85      }
86    }
87
88    [Storable]
89    private ItemList<IAlgorithm> suggestedInstances;
90    private ReadOnlyItemList<IAlgorithm> readOnlySuggestedInstances;
91    public ReadOnlyItemList<IAlgorithm> SuggestedInstances {
92      get { return readOnlySuggestedInstances; }
93    }
94
95    [Storable]
96    private RunCollection problemInstances;
97    public RunCollection ProblemInstances {
98      get { return problemInstances; }
99      set {
100        if (problemInstances == value) return;
101        problemInstances = value;
102        OnPropertyChanged("ProblemInstances");
103      }
104    }
105
106    private bool Maximization {
107      get { return Problem != null && ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value; }
108    }
109
110    [StorableConstructor]
111    private ExpertSystem(bool deserializing) : base(deserializing) { }
112    private ExpertSystem(ExpertSystem original, Cloner cloner)
113      : base(original, cloner) {
114      runs = cloner.Clone(original.runs);
115      algorithmInstances = cloner.Clone(original.algorithmInstances);
116      problem = cloner.Clone(original.problem);
117      suggestedInstances = cloner.Clone(original.suggestedInstances);
118      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
119      problemInstances = cloner.Clone(original.problemInstances);
120      RegisterEventHandlers();
121    }
122    public ExpertSystem() {
123      Name = ItemName;
124      Description = ItemDescription;
125      runs = new RunCollection();
126      algorithmInstances = new ItemList<IAlgorithm>();
127      suggestedInstances = new ItemList<IAlgorithm>();
128      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
129      problemInstances = new RunCollection();
130      RegisterEventHandlers();
131    }
132
133    public override IDeepCloneable Clone(Cloner cloner) {
134      return new ExpertSystem(this, cloner);
135    }
136
137    [StorableHook(HookType.AfterDeserialization)]
138    private void AfterDeserialization() {
139      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
140      RegisterEventHandlers();
141    }
142
143    private void RegisterEventHandlers() {
144      runs.CollectionReset += InformationChanged;
145      runs.ItemsAdded += InformationChanged;
146      runs.ItemsRemoved += InformationChanged;
147      runs.Reset += InformationChanged;
148      runs.UpdateOfRunsInProgressChanged += InformationChanged;
149      algorithmInstances.CollectionReset += InformationChanged;
150      algorithmInstances.ItemsAdded += InformationChanged;
151      algorithmInstances.ItemsRemoved += InformationChanged;
152    }
153
154    private void InformationChanged(object sender, EventArgs e) {
155      var runCollection = sender as RunCollection;
156      if (runCollection != null && runCollection.UpdateOfRunsInProgress) return;
157      UpdateInstanceMap();
158      UpdateSuggestions();
159    }
160
161    private void UpdateInstanceMap() {
162      var flaValues = ProblemInstances.ResultNames
163                      .Where(x => x.StartsWith("Characteristic.")
164                        && ProblemInstances.All(y => y.Results.ContainsKey(x) && y.Results[x] is DoubleValue))
165                      .Select(x => x).ToList();
166      var ds = new double[ProblemInstances.Count, flaValues.Count];
167      var instanceCounter = 0;
168      foreach (var instance in ProblemInstances) {
169        for (var feature = 0; feature < flaValues.Count; feature++)
170          ds[instanceCounter, feature] = ((DoubleValue)instance.Results[flaValues[feature]]).Value;
171        instanceCounter++;
172      }
173
174      int info;
175      double[] s2;
176      double[,] v;
177      alglib.pcabuildbasis(ds, instanceCounter, flaValues.Count, out info, out s2, out v);
178
179      var algInstRunDict = AlgorithmInstances.SelectMany(x => x.Runs)
180                                             .Where(x => x.Parameters.ContainsKey("Problem Name") && x.Parameters["Problem Name"] is StringValue)
181                                             .GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value)
182                                             .ToDictionary(x => x.Key, x => x.GroupBy(y => ((StringValue)y.Parameters["Algorithm Name"]).Value)
183                                                                             .ToDictionary(y => y.Key, y => y.ToList()));
184      ProblemInstances.UpdateOfRunsInProgress = true;
185      try {
186        instanceCounter = 0;
187        foreach (var instance in ProblemInstances) {
188          IItem probNameParam;
189          if (!instance.Parameters.TryGetValue("Problem Name", out probNameParam)) continue;
190          var probInstanceName = ((StringValue)probNameParam).Value;
191
192          double x = 0, y = 0;
193          for (var feature = 0; feature < flaValues.Count; feature++) {
194            x += ds[instanceCounter, feature] * v[feature, 0];
195            y += ds[instanceCounter, feature] * v[feature, 1];
196          }
197          IItem item;
198          if (instance.Results.TryGetValue("Projection.PCA1", out item)) {
199            ((DoubleValue)item).Value = x;
200          } else instance.Results.Add("Projection.PCA1", new DoubleValue(x));
201          if (instance.Results.TryGetValue("Projection.PCA2", out item)) {
202            ((DoubleValue)item).Value = y;
203          } else instance.Results.Add("Projection.PCA2", new DoubleValue(y));
204
205          var bkQuality = ((DoubleValue)instance.Parameters["BestKnownQuality"]).Value;
206          var maximization = ((BoolValue)instance.Parameters["Maximization"]).Value;
207          foreach (var kvp in algInstRunDict[probInstanceName]) {
208            var algInstanceName = kvp.Key;
209            foreach (var run in kvp.Value) {
210              // TODO: Things needs to be configurable here (table name, targets)
211              foreach (var target in new[] { 1, 1.01, 1.05, 1.1, 1.2, 1.5 }) {
212                var result = ExpectedRuntimeHelper.CalculateErt(kvp.Value, "QualityPerEvaluations", bkQuality * target, maximization);
213                var resultName = algInstanceName + "@" + ((target - 1) * 100) + "%";
214                if (run.Results.TryGetValue(resultName, out item))
215                  ((DoubleValue)item).Value = result.ExpectedRuntime;
216                else run.Results.Add(resultName, new DoubleValue(result.ExpectedRuntime));
217              }
218            }
219          }
220        }
221      } finally { ProblemInstances.UpdateOfRunsInProgress = false; }
222    }
223
224    private void UpdateSuggestions() {
225      if (Problem == null) return;
226      var instances = new SortedList<double, IAlgorithm>();
227      foreach (var instance in algorithmInstances) {
228        var relevantRuns = instance.Runs.Where(x => ((StringValue)x.Parameters["Problem Type"]).Value == Problem.GetType().Name);
229        var avgQuality = 0.0;
230        var counter = 0;
231        foreach (var run in relevantRuns) {
232          var performanceGraph = ((IndexedDataTable<double>)run.Results["QualityPerEvaluations"]);
233          try {
234            avgQuality += performanceGraph.Rows.First().Values.TakeWhile(x => x.Item1 < MaximumEvaluations).Last().Item2;
235            counter++;
236          } catch { continue; }
237        }
238        avgQuality /= counter;
239        instances.Add(avgQuality, instance);
240      }
241
242      suggestedInstances.Clear();
243      var instanceLadder = instances.Select(x => x.Value);
244      suggestedInstances.AddRange(Maximization ? instanceLadder.Reverse() : instanceLadder);
245    }
246
247    public event PropertyChangedEventHandler PropertyChanged;
248    private void OnPropertyChanged(string propertyName) {
249      var handler = PropertyChanged;
250      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
251    }
252  }
253}
Note: See TracBrowser for help on using the repository browser.