source: branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionECDFView.cs @ 12771

Last change on this file since 12771 was 12771, checked in by abeham, 6 years ago

#2431:

  • Added run collection view
  • Changed name of analyzers
  • Modified algorithms to include Execution Time as a result
File size: 10.5 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.Collections.Generic;
24using System.ComponentModel;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Analysis;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32
33namespace HeuristicLab.Optimization.Views {
34  [View("ECDF Performance Comparison")]
35  [Content(typeof(RunCollection), false)]
36  public partial class RunCollectionECDFView : ItemView {
37    private const string AllRuns = "All Runs";
38
39    public new RunCollection Content {
40      get { return (RunCollection)base.Content; }
41      set { base.Content = value; }
42    }
43
44    private bool suppressUpdates;
45    private readonly IndexedDataTable<double> combinedDataTable;
46    public IndexedDataTable<double> CombinedDataTable {
47      get { return combinedDataTable; }
48    }
49
50    public RunCollectionECDFView() {
51      InitializeComponent();
52      combinedDataTable = new IndexedDataTable<double>("Combined DataTable", "A data table containing the ECDF of each of a number of groups.") {
53        VisualProperties = { YAxisTitle = "Proportion of reached targets" }
54      };
55      viewHost.Content = combinedDataTable;
56      suppressUpdates = false;
57    }
58
59    #region Content events
60    protected override void RegisterContentEvents() {
61      base.RegisterContentEvents();
62      Content.ItemsAdded += Content_ItemsAdded;
63      Content.ItemsRemoved += Content_ItemsRemoved;
64      Content.CollectionReset += Content_CollectionReset;
65      Content.UpdateOfRunsInProgressChanged += Content_UpdateOfRunsInProgressChanged;
66      Content.OptimizerNameChanged += Content_AlgorithmNameChanged;
67    }
68    protected override void DeregisterContentEvents() {
69      Content.ItemsAdded -= Content_ItemsAdded;
70      Content.ItemsRemoved -= Content_ItemsRemoved;
71      Content.CollectionReset -= Content_CollectionReset;
72      Content.UpdateOfRunsInProgressChanged -= Content_UpdateOfRunsInProgressChanged;
73      Content.OptimizerNameChanged -= Content_AlgorithmNameChanged;
74      base.DeregisterContentEvents();
75    }
76
77    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
78      if (suppressUpdates) return;
79      if (InvokeRequired) {
80        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
81        return;
82      }
83      UpdateGroupComboBox();
84      UpdateDataTableComboBox();
85      foreach (var run in e.Items)
86        RegisterRunEvents(run);
87    }
88    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
89      if (suppressUpdates) return;
90      if (InvokeRequired) {
91        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
92        return;
93      }
94      UpdateGroupComboBox();
95      UpdateDataTableComboBox();
96      foreach (var run in e.Items)
97        DeregisterRunEvents(run);
98    }
99    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
100      if (suppressUpdates) return;
101      if (InvokeRequired) {
102        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
103        return;
104      }
105      UpdateGroupComboBox();
106      UpdateDataTableComboBox();
107      foreach (var run in e.OldItems)
108        DeregisterRunEvents(run);
109    }
110    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
111      if (InvokeRequired)
112        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
113      else UpdateCaption();
114    }
115    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
116      if (InvokeRequired) {
117        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
118        return;
119      }
120      suppressUpdates = Content.UpdateOfRunsInProgress;
121      if (!suppressUpdates) {
122        UpdateDataTableComboBox();
123        UpdateGroupComboBox();
124        UpdateRuns();
125      }
126    }
127
128    private void RegisterRunEvents(IRun run) {
129      run.PropertyChanged += run_PropertyChanged;
130    }
131    private void DeregisterRunEvents(IRun run) {
132      run.PropertyChanged -= run_PropertyChanged;
133    }
134    private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
135      if (suppressUpdates) return;
136      if (InvokeRequired) {
137        Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e);
138      } else {
139        if (e.PropertyName == "Visible")
140          UpdateRuns();
141      }
142    }
143    #endregion
144
145    protected override void OnContentChanged() {
146      base.OnContentChanged();
147      dataTableComboBox.Items.Clear();
148      groupComboBox.Items.Clear();
149      combinedDataTable.Rows.Clear();
150
151      UpdateCaption();
152      if (Content != null) {
153        UpdateGroupComboBox();
154        UpdateDataTableComboBox();
155      }
156    }
157
158    private void UpdateRuns() {
159      if (InvokeRequired) {
160        Invoke((Action)UpdateRuns);
161        return;
162      }
163      SuspendRepaint();
164      try {
165        combinedDataTable.Rows.Clear();
166        var table = (string)dataTableComboBox.SelectedItem;
167        if (string.IsNullOrEmpty(table)) return;
168        var maximum = Content.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item2)).Max();
169        var minimum = Content.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item2)).Min();
170        var levels = Enumerable.Range(0, 51).Select(x => maximum - (x / 50.0) * (maximum - minimum)).ToArray();
171        var selectedGroup = (string)groupComboBox.SelectedItem;
172        if (string.IsNullOrEmpty(selectedGroup)) return;
173        List<Tuple<string, List<IRun>>> groupedRuns;
174        if (selectedGroup == AllRuns)
175          groupedRuns = new List<Tuple<string, List<IRun>>> { Tuple.Create(AllRuns, Content.ToList()) };
176        else groupedRuns = (from r in Content
177                            group r by r.Parameters[selectedGroup].ToString() into g
178                            select Tuple.Create(g.Key, g.ToList())).ToList();
179        var xAxisTitles = new HashSet<string>();
180        foreach (var group in groupedRuns) {
181          var hits = new SortedList<double, int>();
182          foreach (var run in group.Item2) {
183            var resultsTable = (IndexedDataTable<double>)run.Results[table];
184            xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
185            var graph = new LinkedList<Tuple<double, double>>(resultsTable.Rows.First().Values);
186            var current = graph.First.Next;
187            // prune convergence graph to obtain first hit times only
188            while (current != null) {
189              if (current.Value.Item2.IsAlmost(current.Previous.Value.Item2)) {
190                var h = current;
191                current = current.Previous;
192                graph.Remove(h);
193              }
194              current = current.Next;
195            }
196            var i = 0;
197            current = graph.First;
198            while (i < levels.Length && current != null) {
199              if (current.Value.Item2 < levels[i]) {
200                if (hits.ContainsKey(current.Value.Item1))
201                  hits[current.Value.Item1]++;
202                else hits[current.Value.Item1] = 1;
203                i++;
204              } else {
205                current = current.Next;
206              }
207            }
208          }
209          var row = new IndexedDataRow<double>(group.Item1) { VisualProperties = { ChartType = DataRowVisualProperties.DataRowChartType.StepLine } };
210          var total = 0.0;
211          foreach (var h in hits) {
212            total += h.Value;
213            row.Values.Add(Tuple.Create(Math.Max(1, h.Key), total / (group.Item2.Count * levels.Length)));
214          }
215          combinedDataTable.Rows.Add(row);
216        }
217        combinedDataTable.VisualProperties.XAxisTitle = string.Join(" / ", xAxisTitles);
218      } finally { ResumeRepaint(true); }
219    }
220
221    private void UpdateGroupComboBox() {
222      string selectedItem = (string)groupComboBox.SelectedItem;
223
224      var groupings = Content.ParameterNames.ToArray();
225      groupComboBox.Items.Clear();
226      groupComboBox.Items.Add(AllRuns);
227      groupComboBox.Items.AddRange(groupings);
228      if (selectedItem != null && groupComboBox.Items.Contains(selectedItem)) {
229        groupComboBox.SelectedItem = selectedItem;
230      } else if (groupComboBox.Items.Count > 0) {
231        groupComboBox.SelectedItem = groupComboBox.Items[0];
232      }
233    }
234
235    private void UpdateDataTableComboBox() {
236      string selectedItem = (string)dataTableComboBox.SelectedItem;
237
238      dataTableComboBox.Items.Clear();
239      var dataTables = (from run in Content
240                        from result in run.Results
241                        where result.Value is IndexedDataTable<double>
242                        select result.Key).Distinct().ToArray();
243
244      dataTableComboBox.Items.AddRange(dataTables);
245      if (selectedItem != null && dataTableComboBox.Items.Contains(selectedItem)) {
246        dataTableComboBox.SelectedItem = selectedItem;
247      } else if (dataTableComboBox.Items.Count > 0) {
248        dataTableComboBox.SelectedItem = dataTableComboBox.Items[0];
249      }
250    }
251
252    private void UpdateCaption() {
253      Caption = Content != null ? Content.OptimizerName + " ECDF Comparison" : ViewAttribute.GetViewName(GetType());
254    }
255
256    private void groupComboBox_SelectedIndexChanged(object sender, EventArgs e) {
257      UpdateRuns();
258    }
259    private void dataTableComboBox_SelectedIndexChanged(object sender, EventArgs e) {
260      UpdateRuns();
261    }
262
263    private void logScalingCheckBox_CheckedChanged(object sender, EventArgs e) {
264      combinedDataTable.VisualProperties.XAxisLogScale = logScalingCheckBox.Checked;
265    }
266  }
267}
Note: See TracBrowser for help on using the repository browser.