source: branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs @ 12804

Last change on this file since 12804 was 12804, checked in by abeham, 5 years ago

#2431:

  • worked on IRRRun (early abort still troublesome)
  • Updated RLD view to allow defining targets
  • Attempting to handle maximization/minimization
File size: 11.7 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("Run-length Distribution View")]
35  [Content(typeof(RunCollection), false)]
36  public partial class RunCollectionRLDView : 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 double[] levels;
45
46    private bool suppressUpdates;
47    private readonly IndexedDataTable<double> combinedDataTable;
48    public IndexedDataTable<double> CombinedDataTable {
49      get { return combinedDataTable; }
50    }
51
52    public RunCollectionRLDView() {
53      InitializeComponent();
54      combinedDataTable = new IndexedDataTable<double>("Combined DataTable", "A data table containing the ECDF of each of a number of groups.") {
55        VisualProperties = { YAxisTitle = "Proportion of reached targets" }
56      };
57      viewHost.Content = combinedDataTable;
58      suppressUpdates = false;
59    }
60
61    #region Content events
62    protected override void RegisterContentEvents() {
63      base.RegisterContentEvents();
64      Content.ItemsAdded += Content_ItemsAdded;
65      Content.ItemsRemoved += Content_ItemsRemoved;
66      Content.CollectionReset += Content_CollectionReset;
67      Content.UpdateOfRunsInProgressChanged += Content_UpdateOfRunsInProgressChanged;
68      Content.OptimizerNameChanged += Content_AlgorithmNameChanged;
69    }
70    protected override void DeregisterContentEvents() {
71      Content.ItemsAdded -= Content_ItemsAdded;
72      Content.ItemsRemoved -= Content_ItemsRemoved;
73      Content.CollectionReset -= Content_CollectionReset;
74      Content.UpdateOfRunsInProgressChanged -= Content_UpdateOfRunsInProgressChanged;
75      Content.OptimizerNameChanged -= Content_AlgorithmNameChanged;
76      base.DeregisterContentEvents();
77    }
78
79    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
80      if (suppressUpdates) return;
81      if (InvokeRequired) {
82        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
83        return;
84      }
85      UpdateGroupComboBox();
86      UpdateDataTableComboBox();
87      foreach (var run in e.Items)
88        RegisterRunEvents(run);
89    }
90    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
91      if (suppressUpdates) return;
92      if (InvokeRequired) {
93        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
94        return;
95      }
96      UpdateGroupComboBox();
97      UpdateDataTableComboBox();
98      foreach (var run in e.Items)
99        DeregisterRunEvents(run);
100    }
101    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
102      if (suppressUpdates) return;
103      if (InvokeRequired) {
104        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
105        return;
106      }
107      UpdateGroupComboBox();
108      UpdateDataTableComboBox();
109      foreach (var run in e.OldItems)
110        DeregisterRunEvents(run);
111    }
112    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
113      if (InvokeRequired)
114        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
115      else UpdateCaption();
116    }
117    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
118      if (InvokeRequired) {
119        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
120        return;
121      }
122      suppressUpdates = Content.UpdateOfRunsInProgress;
123      if (!suppressUpdates) {
124        UpdateDataTableComboBox();
125        UpdateGroupComboBox();
126        UpdateRuns();
127      }
128    }
129
130    private void RegisterRunEvents(IRun run) {
131      run.PropertyChanged += run_PropertyChanged;
132    }
133    private void DeregisterRunEvents(IRun run) {
134      run.PropertyChanged -= run_PropertyChanged;
135    }
136    private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
137      if (suppressUpdates) return;
138      if (InvokeRequired) {
139        Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e);
140      } else {
141        if (e.PropertyName == "Visible")
142          UpdateRuns();
143      }
144    }
145    #endregion
146
147    protected override void OnContentChanged() {
148      base.OnContentChanged();
149      dataTableComboBox.Items.Clear();
150      groupComboBox.Items.Clear();
151      combinedDataTable.Rows.Clear();
152
153      UpdateCaption();
154      if (Content != null) {
155        UpdateGroupComboBox();
156        UpdateDataTableComboBox();
157      }
158    }
159
160    private void UpdateRuns() {
161      if (InvokeRequired) {
162        Invoke((Action)UpdateRuns);
163        return;
164      }
165      SuspendRepaint();
166      try {
167        combinedDataTable.VisualProperties.XAxisLogScale = false;
168        combinedDataTable.Rows.Clear();
169        var table = (string)dataTableComboBox.SelectedItem;
170        if (string.IsNullOrEmpty(table)) return;
171        if (levels == null) {
172          var worst = Content.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item2)).First();
173          var best = Content.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item2)).Last();
174          levels = Enumerable.Range(0, 51).Select(x => worst + (x / 50.0) * (best - worst)).ToArray();
175          suppressTargetsEvents = true;
176          targetsTextBox.Text = string.Join(" ; ", levels);
177          suppressTargetsEvents = false;
178        }
179        var selectedGroup = (string)groupComboBox.SelectedItem;
180        if (string.IsNullOrEmpty(selectedGroup)) return;
181        List<Tuple<string, List<IRun>>> groupedRuns;
182        if (selectedGroup == AllRuns)
183          groupedRuns = new List<Tuple<string, List<IRun>>> { Tuple.Create(AllRuns, Content.ToList()) };
184        else groupedRuns = (from r in Content
185                            group r by r.Parameters[selectedGroup].ToString() into g
186                            select Tuple.Create(g.Key, g.ToList())).ToList();
187        var xAxisTitles = new HashSet<string>();
188        foreach (var group in groupedRuns) {
189          var hits = new SortedList<double, int>();
190          foreach (var run in group.Item2) {
191            var resultsTable = (IndexedDataTable<double>)run.Results[table];
192            xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
193            var values = resultsTable.Rows.First().Values;
194            var maximization = values.First().Item2 < values.Last().Item2;
195            var i = 0;
196            var j = 0;
197            var current = values[j];
198            var prev = Tuple.Create(-1.0, double.NaN);
199            while (i < levels.Length) {
200              if ((double.IsNaN(prev.Item2) || prev.Item2 != current.Item2)
201                  && (maximization && current.Item2 >= levels[i]
202                  || !maximization && current.Item2 <= levels[i])) {
203                if (hits.ContainsKey(current.Item1))
204                  hits[current.Item1]++;
205                else hits[current.Item1] = 1;
206                i++;
207              } else {
208                j++;
209                if (j >= values.Count) break;
210                prev = current;
211                current = values[j];
212              }
213            }
214          }
215          var row = new IndexedDataRow<double>(group.Item1) { VisualProperties = { ChartType = DataRowVisualProperties.DataRowChartType.StepLine } };
216          var total = 0.0;
217          foreach (var h in hits) {
218            total += h.Value;
219            row.Values.Add(Tuple.Create(h.Key, total / (group.Item2.Count * levels.Length)));
220          }
221          combinedDataTable.Rows.Add(row);
222        }
223        combinedDataTable.VisualProperties.XAxisTitle = string.Join(" / ", xAxisTitles);
224        combinedDataTable.VisualProperties.XAxisLogScale = logScalingCheckBox.Checked;
225      } finally { ResumeRepaint(true); }
226    }
227
228    private void UpdateGroupComboBox() {
229      string selectedItem = (string)groupComboBox.SelectedItem;
230
231      var groupings = Content.ParameterNames.OrderBy(x => x).ToArray();
232      groupComboBox.Items.Clear();
233      groupComboBox.Items.Add(AllRuns);
234      groupComboBox.Items.AddRange(groupings);
235      if (selectedItem != null && groupComboBox.Items.Contains(selectedItem)) {
236        groupComboBox.SelectedItem = selectedItem;
237      } else if (groupComboBox.Items.Count > 0) {
238        groupComboBox.SelectedItem = groupComboBox.Items[0];
239      }
240    }
241
242    private void UpdateDataTableComboBox() {
243      string selectedItem = (string)dataTableComboBox.SelectedItem;
244
245      dataTableComboBox.Items.Clear();
246      var dataTables = (from run in Content
247                        from result in run.Results
248                        where result.Value is IndexedDataTable<double>
249                        select result.Key).Distinct().ToArray();
250
251      dataTableComboBox.Items.AddRange(dataTables);
252      if (selectedItem != null && dataTableComboBox.Items.Contains(selectedItem)) {
253        dataTableComboBox.SelectedItem = selectedItem;
254      } else if (dataTableComboBox.Items.Count > 0) {
255        dataTableComboBox.SelectedItem = dataTableComboBox.Items[0];
256      }
257    }
258
259    private void UpdateCaption() {
260      Caption = Content != null ? Content.OptimizerName + " RLD View" : ViewAttribute.GetViewName(GetType());
261    }
262
263    private void groupComboBox_SelectedIndexChanged(object sender, EventArgs e) {
264      UpdateRuns();
265    }
266    private void dataTableComboBox_SelectedIndexChanged(object sender, EventArgs e) {
267      UpdateRuns();
268    }
269
270    private void logScalingCheckBox_CheckedChanged(object sender, EventArgs e) {
271      combinedDataTable.VisualProperties.XAxisLogScale = logScalingCheckBox.Checked;
272    }
273
274    private bool suppressTargetsEvents;
275    private void targetsTextBox_Validating(object sender, CancelEventArgs e) {
276      if (suppressTargetsEvents) return;
277      var targetStrings = targetsTextBox.Text.Split(new[] { ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
278      var targetList = new List<double>();
279      foreach (var ts in targetStrings) {
280        double t;
281        if (!double.TryParse(ts, out t)) {
282          errorProvider.SetError(targetsTextBox, "Not all targets can be parsed: " + ts);
283          e.Cancel = true;
284          return;
285        }
286        targetList.Add(t);
287      }
288      if (targetList.Count == 0) {
289        errorProvider.SetError(targetsTextBox, "Give at least one target value!");
290        e.Cancel = true;
291        return;
292      }
293      e.Cancel = false;
294      errorProvider.SetError(targetsTextBox, null);
295      levels = targetList.ToArray();
296    }
297  }
298}
Note: See TracBrowser for help on using the repository browser.