Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimizer/3.3/CreateExperimentDialog.cs @ 7949

Last change on this file since 7949 was 7908, checked in by abeham, 13 years ago

#1851: Added possibility to create simple parameter variation experiments

File size: 32.6 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.ComponentModel;
25using System.Globalization;
26using System.Linq;
27using System.Text;
28using System.Threading;
29using System.Windows.Forms;
30using HeuristicLab.Core;
31using HeuristicLab.Data;
32using HeuristicLab.Optimization;
33using HeuristicLab.Parameters;
34using HeuristicLab.Problems.Instances;
35
36namespace HeuristicLab.Optimizer {
37  public partial class CreateExperimentDialog : Form {
38    private enum DialogMode { Normal = 1, DiscoveringInstances = 2, CreatingExperiment = 3 };
39
40    private IOptimizer optimizer;
41    public IOptimizer Optimizer {
42      get { return optimizer; }
43      set {
44        optimizer = value;
45        Experiment = null;
46        okButton.Enabled = optimizer != null;
47        SetTabControlVisibility();
48        FillInstanceListViewAsync();
49        FillParametersListView();
50      }
51    }
52
53    public Experiment Experiment { get; private set; }
54
55    private bool createBatchRun;
56    private int repetitions;
57    private Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>> instances;
58    private Dictionary<IValueParameter, Tuple<int, int, int>> intParameters;
59    private Dictionary<IValueParameter, Tuple<double, double, double>> doubleParameters;
60    private HashSet<IValueParameter> boolParameters;
61    private Dictionary<IValueParameter, HashSet<INamedItem>> multipleChoiceParameters;
62
63    private StringBuilder failedInstances;
64    private EventWaitHandle backgroundWorkerWaitHandle = new ManualResetEvent(false);
65    private bool suppressListViewEventHandling;
66
67    public CreateExperimentDialog() : this(null) { }
68    public CreateExperimentDialog(IOptimizer optimizer) {
69      InitializeComponent();
70      createBatchRun = createBatchRunCheckBox.Checked;
71      repetitions = (int)repetitionsNumericUpDown.Value;
72      // do not set the Optimizer property here, because we want to delay instance discovery to the time when the form loads
73      this.optimizer = optimizer;
74      Experiment = null;
75      okButton.Enabled = optimizer != null;
76
77      instances = new Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>>();
78      intParameters = new Dictionary<IValueParameter, Tuple<int, int, int>>();
79      doubleParameters = new Dictionary<IValueParameter, Tuple<double, double, double>>();
80      boolParameters = new HashSet<IValueParameter>();
81      multipleChoiceParameters = new Dictionary<IValueParameter, HashSet<INamedItem>>();
82    }
83
84    #region Event handlers
85    private void CreateExperimentDialog_Load(object sender, EventArgs e) {
86      SetTabControlVisibility();
87      FillInstanceListViewAsync();
88      FillParametersListView();
89    }
90
91    private void CreateExperimentDialog_FormClosing(object sender, FormClosingEventArgs e) {
92      if (experimentCreationBackgroundWorker.IsBusy) {
93        if (DialogResult != System.Windows.Forms.DialogResult.OK) {
94          if (experimentCreationBackgroundWorker.IsBusy) experimentCreationBackgroundWorker.CancelAsync();
95          if (instanceDiscoveryBackgroundWorker.IsBusy) instanceDiscoveryBackgroundWorker.CancelAsync();
96        }
97        e.Cancel = true;
98      }
99    }
100
101    private void okButton_Click(object sender, EventArgs e) {
102      SetMode(DialogMode.CreatingExperiment);
103      experimentCreationBackgroundWorker.RunWorkerAsync();
104      backgroundWorkerWaitHandle.WaitOne(); // make sure the background worker has started before exiting
105    }
106
107    #region Parameters variation
108    private void parametersListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
109      var parameter = (IValueParameter)e.Item.Tag;
110      var isConstrainedValueParameter = typeof(OptionalConstrainedValueParameter<>).Equals(parameter.GetType().GetGenericTypeDefinition())
111        || typeof(ConstrainedValueParameter<>).Equals(parameter.GetType().GetGenericTypeDefinition());
112
113      if (!isConstrainedValueParameter && parameter.Value == null) {
114        if (e.Item.Checked) e.Item.Checked = false;
115        return;
116      }
117
118      if (isConstrainedValueParameter) {
119        if (e.Item.Checked) {
120          multipleChoiceParameters.Add(parameter, new HashSet<INamedItem>());
121        } else multipleChoiceParameters.Remove(parameter);
122      }
123
124      var intValue = parameter.Value as ValueTypeValue<int>;
125      if (intValue != null) {
126        if (e.Item.Checked) {
127          int minimum = intValue.Value;
128          int maximum = intValue.Value;
129          int step = 1;
130          intParameters.Add(parameter, new Tuple<int, int, int>(minimum, maximum, step));
131        } else intParameters.Remove(parameter);
132      }
133
134      var doubleValue = parameter.Value as ValueTypeValue<double>;
135      if (doubleValue != null) {
136        if (e.Item.Checked) {
137          double minimum = doubleValue.Value;
138          double maximum = doubleValue.Value;
139          double step = 1;
140          doubleParameters.Add(parameter, new Tuple<double, double, double>(minimum, maximum, step));
141        } else doubleParameters.Remove(parameter);
142      }
143
144      var boolValue = parameter.Value as ValueTypeValue<bool>;
145      if (boolValue != null) {
146        if (e.Item.Checked) boolParameters.Add(parameter);
147        else boolParameters.Remove(parameter);
148      }
149
150      if (e.Item.Selected) UpdateDetailsView(parameter);
151      else e.Item.Selected = true;
152    }
153
154    private void parametersListView_SelectedIndexChanged(object sender, EventArgs e) {
155      if (parametersListView.SelectedItems.Count == 0) {
156        ClearDetailsView();
157      } else {
158        var parameter = parametersListView.SelectedItems[0].Tag as IValueParameter;
159        UpdateDetailsView(parameter);
160      }
161    }
162
163    private void UpdateDetailsView(IValueParameter parameter) {
164      ClearDetailsView();
165
166      var isConstrainedValueParameter =
167        typeof(OptionalConstrainedValueParameter<>).IsAssignableFrom(parameter.GetType().GetGenericTypeDefinition())
168        || typeof(ConstrainedValueParameter<>).Equals(parameter.GetType().GetGenericTypeDefinition());
169
170      if (isConstrainedValueParameter) {
171        choicesLabel.Visible = true;
172        choicesListView.Enabled = true;
173        choicesListView.Visible = true;
174        choicesListView.Tag = parameter;
175
176        if (!multipleChoiceParameters.ContainsKey(parameter)) return;
177        dynamic constrainedValuedParameter = parameter;
178        dynamic validValues = constrainedValuedParameter.ValidValues;
179        foreach (var choice in validValues) {
180          choicesListView.Items.Add(new ListViewItem(choice.ToString()) {
181            Tag = choice,
182            Checked = multipleChoiceParameters[parameter].Contains((INamedItem)choice)
183          });
184        }
185        return;
186      }
187
188      minimumLabel.Visible = true; minimumTextBox.Visible = true;
189      maximumLabel.Visible = true; maximumTextBox.Visible = true;
190      stepSizeLabel.Visible = true; stepSizeTextBox.Visible = true;
191
192      var intValue = parameter.Value as ValueTypeValue<int>;
193      if (intValue != null) {
194        if (!intParameters.ContainsKey(parameter)) return;
195        string min = intParameters[parameter].Item1.ToString();
196        string max = intParameters[parameter].Item2.ToString();
197        string step = intParameters[parameter].Item3.ToString();
198        UpdateMinMaxStepSize(parameter, min, max, step);
199        return;
200      }
201
202      var doubleValue = parameter.Value as ValueTypeValue<double>;
203      if (doubleValue != null) {
204        if (!doubleParameters.ContainsKey(parameter)) return;
205        string min = doubleParameters[parameter].Item1.ToString();
206        string max = doubleParameters[parameter].Item2.ToString();
207        string step = doubleParameters[parameter].Item3.ToString();
208        UpdateMinMaxStepSize(parameter, min, max, step);
209        return;
210      }
211    }
212
213    #region Detail controls
214    private void choiceListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
215      var parameter = (IValueParameter)choicesListView.Tag;
216      if (e.Item.Checked) {
217        multipleChoiceParameters[parameter].Add((INamedItem)e.Item.Tag);
218      } else multipleChoiceParameters[parameter].Remove((INamedItem)e.Item.Tag);
219
220      experimentsLabel.Text = GetNumberOfVariations().ToString();
221    }
222
223    private void detailsTextBox_Validating(object sender, CancelEventArgs e) {
224      var parameter = (IValueParameter)((TextBox)sender).Tag;
225      errorProvider.Clear();
226
227      var intValue = parameter.Value as ValueTypeValue<int>;
228      if (intValue != null) {
229        int value;
230        if (!int.TryParse(((TextBox)sender).Text, out value)) {
231          errorProvider.SetError(((TextBox)sender), "Please enter a valid integer number.");
232          e.Cancel = true;
233        } else {
234          var before = intParameters[parameter];
235          var after = default(Tuple<int, int, int>);
236          if (sender == minimumTextBox) after = new Tuple<int, int, int>(value, before.Item2, before.Item3);
237          else if (sender == maximumTextBox) after = new Tuple<int, int, int>(before.Item1, value, before.Item3);
238          else if (sender == stepSizeTextBox) after = new Tuple<int, int, int>(before.Item1, before.Item2, value);
239          intParameters[parameter] = after;
240        }
241      }
242
243      var doubleValue = parameter.Value as ValueTypeValue<double>;
244      if (doubleValue != null) {
245        double value;
246        if (!double.TryParse(((TextBox)sender).Text, NumberStyles.Float, CultureInfo.CurrentCulture.NumberFormat, out value)) {
247          errorProvider.SetError(((TextBox)sender), "Please enter a valid number.");
248          e.Cancel = true;
249        } else {
250          var before = doubleParameters[parameter];
251          var after = default(Tuple<double, double, double>);
252          if (sender == minimumTextBox) after = new Tuple<double, double, double>(value, before.Item2, before.Item3);
253          else if (sender == maximumTextBox) after = new Tuple<double, double, double>(before.Item1, value, before.Item3);
254          else if (sender == stepSizeTextBox) after = new Tuple<double, double, double>(before.Item1, before.Item2, value);
255          doubleParameters[parameter] = after;
256        }
257      }
258
259      experimentsLabel.Text = GetNumberOfVariations().ToString();
260    }
261    #endregion
262    #endregion
263
264    #region Instances
265    private void instancesListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
266      if (!suppressListViewEventHandling) {
267        selectAllCheckBox.Checked = instancesListView.Items.Count == instancesListView.CheckedItems.Count;
268        selectNoneCheckBox.Checked = instancesListView.CheckedItems.Count == 0;
269      }
270      var provider = (IProblemInstanceProvider)e.Item.Group.Tag;
271      var descriptor = (IDataDescriptor)e.Item.Tag;
272      if (e.Item.Checked) {
273        if (!instances.ContainsKey(provider))
274          instances.Add(provider, new HashSet<IDataDescriptor>());
275        instances[provider].Add(descriptor);
276      } else {
277        if (instances.ContainsKey(provider)) {
278          instances[provider].Remove(descriptor);
279          if (instances[provider].Count == 0)
280            instances.Remove(provider);
281        }
282      }
283      experimentsLabel.Text = GetNumberOfVariations().ToString();
284    }
285
286    private void selectAllCheckBox_CheckedChanged(object sender, EventArgs e) {
287      if (selectAllCheckBox.Checked) {
288        selectNoneCheckBox.Checked = false;
289        if (instancesListView.CheckedItems.Count == instancesListView.Items.Count) return;
290        try {
291          suppressListViewEventHandling = true;
292          foreach (var item in instancesListView.Items.OfType<ListViewItem>()) {
293            item.Checked = true;
294          }
295        } finally { suppressListViewEventHandling = false; }
296      }
297    }
298
299    private void selectNoneCheckBox_CheckedChanged(object sender, EventArgs e) {
300      if (selectNoneCheckBox.Checked) {
301        selectAllCheckBox.Checked = false;
302        if (instancesListView.CheckedItems.Count == 0) return;
303        try {
304          suppressListViewEventHandling = true;
305          foreach (var item in instancesListView.Items.OfType<ListViewItem>()) {
306            item.Checked = false;
307          }
308        } finally { suppressListViewEventHandling = false; }
309      }
310    }
311    #endregion
312
313    private void createBatchRunCheckBox_CheckedChanged(object sender, EventArgs e) {
314      repetitionsNumericUpDown.Enabled = createBatchRunCheckBox.Checked;
315      createBatchRun = createBatchRunCheckBox.Checked;
316    }
317
318    private void repetitionsNumericUpDown_Validated(object sender, EventArgs e) {
319      if (repetitionsNumericUpDown.Text == string.Empty)
320        repetitionsNumericUpDown.Text = repetitionsNumericUpDown.Value.ToString();
321      repetitions = (int)repetitionsNumericUpDown.Value;
322    }
323    #endregion
324
325    #region Helpers
326    private void SetTabControlVisibility() {
327      bool isAlgorithm = optimizer != null && optimizer is IAlgorithm;
328      bool instancesAvailable = isAlgorithm
329        && ((IAlgorithm)optimizer).Problem != null
330        && ProblemInstanceManager.GetProviders(((IAlgorithm)optimizer).Problem).Any();
331      if (instancesAvailable && tabControl.TabCount == 1)
332        tabControl.TabPages.Add(instancesTabPage);
333      else if (!instancesAvailable && tabControl.TabCount == 2)
334        tabControl.TabPages.Remove(instancesTabPage);
335      tabControl.Visible = isAlgorithm;
336      if (isAlgorithm) {
337        experimentsLabel.Visible = true;
338        experimentsToCreateDescriptionLabel.Visible = true;
339        Height = 430;
340      } else {
341        experimentsLabel.Visible = false;
342        experimentsToCreateDescriptionLabel.Visible = false;
343        Height = 130;
344      }
345    }
346
347    private void FillParametersListView() {
348      parametersListView.Items.Clear();
349      intParameters.Clear();
350      doubleParameters.Clear();
351      boolParameters.Clear();
352      multipleChoiceParameters.Clear();
353
354      if (Optimizer is IAlgorithm) {
355        var parameters = ((IAlgorithm)optimizer).Parameters;
356        foreach (var param in parameters) {
357          var valueParam = param as IValueParameter;
358          if (valueParam != null && (valueParam.Value is ValueTypeValue<bool>
359              || valueParam.Value is ValueTypeValue<int>
360              || valueParam.Value is ValueTypeValue<double>)
361            || typeof(OptionalConstrainedValueParameter<>).IsAssignableFrom(param.GetType().GetGenericTypeDefinition())
362            || typeof(ConstrainedValueParameter<>).IsAssignableFrom(param.GetType().GetGenericTypeDefinition()))
363            parametersListView.Items.Add(new ListViewItem(param.Name) { Tag = param });
364        }
365      }
366    }
367
368    private void FillInstanceListViewAsync() {
369      instances.Clear();
370      instancesListView.Items.Clear();
371      instancesListView.Groups.Clear();
372
373      if (Optimizer is IAlgorithm) {
374        SetMode(DialogMode.DiscoveringInstances);
375        var instanceProviders = ProblemInstanceManager.GetProviders(((IAlgorithm)Optimizer).Problem);
376        instanceDiscoveryBackgroundWorker.RunWorkerAsync(instanceProviders);
377      }
378    }
379
380    private void AddOptimizer(IOptimizer optimizer, Experiment experiment) {
381      if (createBatchRun) {
382        var batchRun = new BatchRun();
383        batchRun.Repetitions = repetitions;
384        batchRun.Optimizer = optimizer;
385        experiment.Optimizers.Add(batchRun);
386      } else {
387        experiment.Optimizers.Add(optimizer);
388      }
389    }
390
391    private int GetNumberOfVariations() {
392      int instancesCount = 1;
393      if (instances.Values.Any())
394        instancesCount = Math.Max(instances.Values.SelectMany(x => x).Count(), 1);
395
396      int intParameterVariations = 1;
397      foreach (var intParam in intParameters.Values) {
398        if (intParam.Item3 == 0) continue;
399        intParameterVariations *= (intParam.Item2 - intParam.Item1) / intParam.Item3 + 1;
400      }
401      int doubleParameterVariations = 1;
402      foreach (var doubleParam in doubleParameters.Values) {
403        if (doubleParam.Item3 == 0) continue;
404        doubleParameterVariations *= (int)Math.Floor((doubleParam.Item2 - doubleParam.Item1) / doubleParam.Item3) + 1;
405      }
406      int boolParameterVariations = 1;
407      foreach (var boolParam in boolParameters) {
408        boolParameterVariations *= 2;
409      }
410      int choiceParameterVariations = 1;
411      foreach (var choiceParam in multipleChoiceParameters.Values) {
412        choiceParameterVariations *= Math.Max(choiceParam.Count, 1);
413      }
414
415      return (instancesCount * intParameterVariations * doubleParameterVariations * boolParameterVariations * choiceParameterVariations);
416    }
417
418    private void SetMode(DialogMode mode) {
419      createBatchRunCheckBox.Enabled = mode == DialogMode.Normal;
420      repetitionsNumericUpDown.Enabled = mode == DialogMode.Normal;
421      selectAllCheckBox.Enabled = mode == DialogMode.Normal;
422      selectNoneCheckBox.Enabled = mode == DialogMode.Normal;
423      instancesListView.Enabled = mode == DialogMode.Normal;
424      instancesListView.Visible = mode == DialogMode.Normal || mode == DialogMode.CreatingExperiment;
425      okButton.Enabled = mode == DialogMode.Normal;
426      okButton.Visible = mode == DialogMode.Normal;
427      instanceDiscoveryProgressLabel.Visible = mode == DialogMode.DiscoveringInstances;
428      instanceDiscoveryProgressBar.Visible = mode == DialogMode.DiscoveringInstances;
429      experimentCreationProgressBar.Visible = mode == DialogMode.CreatingExperiment;
430    }
431
432    private void ClearDetailsView() {
433      minimumLabel.Visible = false;
434      minimumTextBox.Text = string.Empty;
435      minimumTextBox.Enabled = false;
436      minimumTextBox.Visible = false;
437      maximumLabel.Visible = false;
438      maximumTextBox.Text = string.Empty;
439      maximumTextBox.Enabled = false;
440      maximumTextBox.Visible = false;
441      stepSizeLabel.Visible = false;
442      stepSizeTextBox.Text = string.Empty;
443      stepSizeTextBox.Enabled = false;
444      stepSizeTextBox.Visible = false;
445      choicesLabel.Visible = false;
446      choicesListView.Items.Clear();
447      choicesListView.Enabled = false;
448      choicesListView.Visible = false;
449    }
450
451    private void UpdateMinMaxStepSize(IValueParameter parameter, string min, string max, string step) {
452      minimumLabel.Visible = true;
453      minimumTextBox.Text = min;
454      minimumTextBox.Enabled = true;
455      minimumTextBox.Visible = true;
456      minimumTextBox.Tag = parameter;
457      maximumLabel.Visible = true;
458      maximumTextBox.Text = max;
459      maximumTextBox.Enabled = true;
460      maximumTextBox.Visible = true;
461      maximumTextBox.Tag = parameter;
462      stepSizeLabel.Visible = true;
463      stepSizeTextBox.Text = step;
464      stepSizeTextBox.Enabled = true;
465      stepSizeTextBox.Visible = true;
466      stepSizeTextBox.Tag = parameter;
467    }
468
469    #region Retrieve parameter combinations
470    private IEnumerable<Dictionary<IValueParameter, int>> GetIntParameterConfigurations() {
471      var configuration = new Dictionary<IValueParameter, int>();
472      var indices = new Dictionary<IValueParameter, int>();
473      bool finished;
474      do {
475        foreach (var p in intParameters) {
476          if (!indices.ContainsKey(p.Key)) indices.Add(p.Key, 0);
477          var value = p.Value.Item1 + p.Value.Item3 * indices[p.Key];
478          configuration[p.Key] = value;
479        }
480        yield return configuration;
481
482        finished = true;
483        foreach (var p in intParameters.Keys) {
484          var newValue = intParameters[p].Item1 + intParameters[p].Item3 * (indices[p] + 1);
485          if (newValue > intParameters[p].Item2 || intParameters[p].Item3 == 0)
486            indices[p] = 0;
487          else {
488            indices[p]++;
489            finished = false;
490            break;
491          }
492        }
493      } while (!finished);
494    }
495
496    private IEnumerable<Dictionary<IValueParameter, double>> GetDoubleParameterConfigurations() {
497      var configuration = new Dictionary<IValueParameter, double>();
498      var indices = new Dictionary<IValueParameter, int>();
499      bool finished;
500      do {
501        foreach (var p in doubleParameters) {
502          if (!indices.ContainsKey(p.Key)) indices.Add(p.Key, 0);
503          var value = p.Value.Item1 + p.Value.Item3 * indices[p.Key];
504          configuration[p.Key] = value;
505        }
506        yield return configuration;
507
508        finished = true;
509        foreach (var p in doubleParameters.Keys) {
510          var newValue = doubleParameters[p].Item1 + doubleParameters[p].Item3 * (indices[p] + 1);
511          if (newValue > doubleParameters[p].Item2 || doubleParameters[p].Item3 == 0)
512            indices[p] = 0;
513          else {
514            indices[p]++;
515            finished = false;
516            break;
517          }
518        }
519      } while (!finished);
520    }
521
522    private IEnumerable<Dictionary<IValueParameter, bool>> GetBoolParameterConfigurations() {
523      var configuration = new Dictionary<IValueParameter, bool>();
524      bool finished;
525      do {
526        finished = true;
527        foreach (var p in boolParameters) {
528          if (!configuration.ContainsKey(p)) configuration.Add(p, false);
529          else {
530            if (configuration[p]) {
531              configuration[p] = false;
532            } else {
533              configuration[p] = true;
534              finished = false;
535              break;
536            }
537          }
538        }
539        yield return configuration;
540      } while (!finished);
541    }
542
543    private IEnumerable<Dictionary<IValueParameter, INamedItem>> GetMultipleChoiceConfigurations() {
544      var configuration = new Dictionary<IValueParameter, INamedItem>();
545      var enumerators = new Dictionary<IValueParameter, IEnumerator<INamedItem>>();
546      bool finished;
547      do {
548        foreach (var p in multipleChoiceParameters.Keys.ToArray()) {
549          if (!enumerators.ContainsKey(p)) {
550            enumerators.Add(p, multipleChoiceParameters[p].GetEnumerator());
551            if (!enumerators[p].MoveNext()) {
552              multipleChoiceParameters.Remove(p);
553              continue;
554            }
555          }
556          configuration[p] = enumerators[p].Current;
557        }
558
559        finished = true;
560        foreach (var p in multipleChoiceParameters.Keys) {
561          if (!enumerators[p].MoveNext()) {
562            enumerators[p] = multipleChoiceParameters[p].GetEnumerator();
563          } else {
564            finished = false;
565            break;
566          }
567        }
568        yield return configuration;
569      } while (!finished);
570    }
571    #endregion
572    #endregion
573
574    #region Background workers
575    #region Instance discovery
576    private void instanceDiscoveryBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
577      var instanceProviders = ((IEnumerable<IProblemInstanceProvider>)e.Argument).ToArray();
578      var groups = new ListViewGroup[instanceProviders.Length];
579      for (int i = 0; i < instanceProviders.Length; i++) {
580        var provider = instanceProviders[i];
581        groups[i] = new ListViewGroup(provider.Name, provider.Name) { Tag = provider };
582      }
583      e.Result = groups;
584      for (int i = 0; i < groups.Length; i++) {
585        var group = groups[i];
586        var provider = group.Tag as IProblemInstanceProvider;
587        double progress = (100.0 * i) / groups.Length;
588        instanceDiscoveryBackgroundWorker.ReportProgress((int)progress, provider.Name);
589        var descriptors = ProblemInstanceManager.GetDataDescriptors(provider).ToArray();
590        for (int j = 0; j < descriptors.Length; j++) {
591          #region Check cancellation request
592          if (instanceDiscoveryBackgroundWorker.CancellationPending) {
593            e.Cancel = true;
594            return;
595          }
596          #endregion
597          var d = descriptors[j];
598          progress += 1.0 / (descriptors.Length * groups.Length);
599          instanceDiscoveryBackgroundWorker.ReportProgress((int)progress, d.Name);
600          var item = new ListViewItem(d.Name, group) { Tag = d };
601        }
602      }
603      instanceDiscoveryBackgroundWorker.ReportProgress(100, string.Empty);
604    }
605
606    private void instanceDiscoveryBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
607      instanceDiscoveryProgressBar.Value = e.ProgressPercentage;
608      instanceDiscoveryProgressLabel.Text = (string)e.UserState;
609    }
610
611    private void instanceDiscoveryBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
612      try {
613        // unfortunately it's not enough to just add the groups, the items need to be added separately
614        foreach (var group in (ListViewGroup[])e.Result) {
615          instancesListView.Groups.Add(group);
616          instancesListView.Items.AddRange(group.Items);
617        }
618        instancesListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
619        selectNoneCheckBox.Checked = true;
620      } catch { }
621      try {
622        SetMode(DialogMode.Normal);
623        if (e.Error != null) MessageBox.Show(e.Error.Message, "Error occurred", MessageBoxButtons.OK, MessageBoxIcon.Error);
624      } catch { }
625    }
626    #endregion
627
628    #region Experiment creation
629    private void experimentCreationBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
630      backgroundWorkerWaitHandle.Set(); // notify the ok button that we're busy now
631      failedInstances = new StringBuilder();
632      var localExperiment = new Experiment();
633
634      if (instances.Count == 0) {
635        var variations = experimentCreationBackgroundWorker_CalculateParameterVariations(optimizer);
636        foreach (var v in variations)
637          AddOptimizer(v, localExperiment);
638        experimentCreationBackgroundWorker.ReportProgress(100, string.Empty);
639
640      } else {
641        int counter = 0, totalInstances = instances.SelectMany(x => x.Value).Count(), totalVariations = GetNumberOfVariations();
642        foreach (var provider in instances.Keys) {
643          foreach (var descriptor in instances[provider]) {
644            #region Check cancellation request
645            if (experimentCreationBackgroundWorker.CancellationPending) {
646              e.Cancel = true;
647              localExperiment = null;
648              return;
649            }
650            #endregion
651            var algorithm = (IAlgorithm)Optimizer.Clone();
652            bool failed = false;
653            try {
654              ProblemInstanceManager.LoadData(provider, descriptor, (IProblemInstanceConsumer)algorithm.Problem);
655            } catch (Exception ex) {
656              failedInstances.AppendLine(descriptor.Name + ": " + ex.Message);
657              failed = true;
658            }
659            if (!failed) {
660              var variations = experimentCreationBackgroundWorker_CalculateParameterVariations(algorithm);
661              foreach (var v in variations) {
662                AddOptimizer(v, localExperiment);
663                counter++;
664              }
665              experimentCreationBackgroundWorker.ReportProgress((int)Math.Round(100.0 * counter / (totalInstances * totalVariations)), descriptor.Name);
666            } else experimentCreationBackgroundWorker.ReportProgress((int)Math.Round(100.0 * counter / (totalInstances * totalVariations)), "Loading failed (" + descriptor.Name + ")");
667          }
668        }
669      }
670      if (localExperiment != null) localExperiment.Prepare(true);
671      Experiment = localExperiment;
672    }
673
674    private IEnumerable<IOptimizer> experimentCreationBackgroundWorker_CalculateParameterVariations(IOptimizer optimizer) {
675      if (!boolParameters.Any() && !intParameters.Any() && !doubleParameters.Any() && !multipleChoiceParameters.Any()) {
676        yield return (IOptimizer)optimizer.Clone();
677        yield break;
678      }
679      bool finished;
680      var mcEnumerator = GetMultipleChoiceConfigurations().GetEnumerator();
681      var boolEnumerator = GetBoolParameterConfigurations().GetEnumerator();
682      var intEnumerator = GetIntParameterConfigurations().GetEnumerator();
683      var doubleEnumerator = GetDoubleParameterConfigurations().GetEnumerator();
684      mcEnumerator.MoveNext(); boolEnumerator.MoveNext(); intEnumerator.MoveNext(); doubleEnumerator.MoveNext();
685      do {
686        var variant = (IAlgorithm)optimizer.Clone();
687        variant.Name += " {";
688        finished = true;
689        if (doubleParameters.Any()) {
690          foreach (var d in doubleEnumerator.Current) {
691            var value = (ValueTypeValue<double>)((IValueParameter)variant.Parameters[d.Key.Name]).Value;
692            value.Value = d.Value;
693            variant.Name += d.Key.Name + "=" + d.Value.ToString() + ", ";
694          }
695          if (finished) {
696            if (doubleEnumerator.MoveNext()) {
697              finished = false;
698            } else {
699              doubleEnumerator = GetDoubleParameterConfigurations().GetEnumerator();
700              doubleEnumerator.MoveNext();
701            }
702          }
703        }
704        if (intParameters.Any()) {
705          foreach (var i in intEnumerator.Current) {
706            var value = (ValueTypeValue<int>)((IValueParameter)variant.Parameters[i.Key.Name]).Value;
707            value.Value = i.Value;
708            variant.Name += i.Key.Name + "=" + i.Value.ToString() + ", ";
709          }
710          if (finished) {
711            if (intEnumerator.MoveNext()) {
712              finished = false;
713            } else {
714              intEnumerator = GetIntParameterConfigurations().GetEnumerator();
715              intEnumerator.MoveNext();
716            }
717          }
718        }
719        if (boolParameters.Any()) {
720          foreach (var b in boolEnumerator.Current) {
721            var value = (ValueTypeValue<bool>)((IValueParameter)variant.Parameters[b.Key.Name]).Value;
722            value.Value = b.Value;
723            variant.Name += b.Key.Name + "=" + b.Value.ToString() + ", ";
724          }
725          if (finished) {
726            if (boolEnumerator.MoveNext()) {
727              finished = false;
728            } else {
729              boolEnumerator = GetBoolParameterConfigurations().GetEnumerator();
730              boolEnumerator.MoveNext();
731            }
732          }
733        }
734        if (multipleChoiceParameters.Any()) {
735          foreach (var m in mcEnumerator.Current) {
736            dynamic variantParam = variant.Parameters[m.Key.Name];
737            var variantEnumerator = ((IEnumerable<object>)variantParam.ValidValues).GetEnumerator();
738            var originalEnumerator = ((IEnumerable<object>)((dynamic)m.Key).ValidValues).GetEnumerator();
739            while (variantEnumerator.MoveNext() && originalEnumerator.MoveNext()) {
740              if (m.Value == (INamedItem)originalEnumerator.Current) {
741                variantParam.Value = (dynamic)variantEnumerator.Current;
742                variant.Name += m.Key.Name + "=" + m.Value.Name + ", ";
743                break;
744              }
745            }
746          }
747          if (finished) {
748            if (mcEnumerator.MoveNext()) {
749              finished = false;
750            } else {
751              mcEnumerator = GetMultipleChoiceConfigurations().GetEnumerator();
752              mcEnumerator.MoveNext();
753            }
754          }
755        }
756        variant.Name = variant.Name.Substring(0, variant.Name.Length - 2) + "}";
757        yield return variant;
758      } while (!finished);
759    }
760
761    private void experimentCreationBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
762      experimentCreationProgressBar.Value = e.ProgressPercentage;
763    }
764
765    private void experimentCreationBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
766      try {
767        SetMode(DialogMode.Normal);
768        if (e.Error != null) MessageBox.Show(e.Error.Message, "Error occurred", MessageBoxButtons.OK, MessageBoxIcon.Error);
769        if (failedInstances.Length > 0) MessageBox.Show("Some instances could not be loaded: " + Environment.NewLine + failedInstances.ToString(), "Some instances failed to load", MessageBoxButtons.OK, MessageBoxIcon.Error);
770        if (!e.Cancelled && e.Error == null) {
771          DialogResult = System.Windows.Forms.DialogResult.OK;
772          Close();
773        }
774      } catch { }
775    }
776    #endregion
777    #endregion
778  }
779}
Note: See TracBrowser for help on using the repository browser.