Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ParameterConfigurationEncoding/HeuristicLab.Encodings.ParameterConfigurationEncoding.Views/3.3/CreateExperimentDialogV2.cs @ 8544

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

#1853:

  • enhanced combinations count calculation
  • restructured code
  • minor code improvements
  • added license information
File size: 11.4 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.Linq;
26using System.Threading;
27using System.Threading.Tasks;
28using System.Windows.Forms;
29using HeuristicLab.Core;
30using HeuristicLab.MainForm;
31using HeuristicLab.MainForm.WindowsForms;
32using HeuristicLab.Optimization;
33using HeuristicLab.PluginInfrastructure;
34using HeuristicLab.Problems.Instances;
35
36namespace HeuristicLab.Encodings.ParameterConfigurationEncoding.Views {
37  public partial class CreateExperimentDialogV2 : Form {
38    private readonly IAlgorithm algorithm;
39    private readonly Progress progress;
40    private ParameterConfigurationTree parameterConfigurationTree;
41    private bool createBatchRun;
42    private int repetitions;
43    private IEngine engine;
44    private Task experimentGenerator;
45    private CancellationTokenSource cts;
46    private Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>> problemInstanceProviders;
47    private Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>> selectedProblemInstanceProviders;
48
49    public Experiment Experiment { get; private set; }
50
51    public CreateExperimentDialogV2() : this(null, null) { }
52    public CreateExperimentDialogV2(IAlgorithm algorithm, IEnumerable<IEngine> engines) {
53      InitializeComponent();
54      if (algorithm != null && engines != null) {
55        this.algorithm = (IAlgorithm)algorithm.Clone();
56        foreach (var engine in engines) engineComboBox.Items.Add(engine);
57        if (engineComboBox.SelectedItem == null) {
58          engineComboBox.SelectedIndex = 0;
59          engine = (IEngine)engineComboBox.SelectedItem;
60        }
61      }
62      createBatchRun = createBatchRunCheckBox.Checked;
63      repetitions = (int)repetitionsNumericUpDown.Value;
64      selectedProblemInstanceProviders = new Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>>();
65      progress = new Progress {
66        CanBeCanceled = true,
67        ProgressState = ProgressState.Finished
68      };
69      progress.CancelRequested += (sender, args) => cts.Cancel();
70      progress.ProgressValueChanged += (sender, args) => progress.Status = string.Format("Generating experiment. Please be patient. ({0} %)", (int)(progress.ProgressValue * 100));
71      cts = new CancellationTokenSource();
72    }
73
74    #region Background worker
75    private void instanceDiscoveryBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
76      var instanceProviders = new Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>>();
77      foreach (var provider in ProblemInstanceManager.GetProviders(algorithm.Problem))
78        instanceProviders[provider] = new HashSet<IDataDescriptor>(ProblemInstanceManager.GetDataDescriptors(provider));
79      e.Result = instanceProviders;
80    }
81
82    private void instanceDiscoveryBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
83      problemInstanceProviders = (Dictionary<IProblemInstanceProvider, HashSet<IDataDescriptor>>)e.Result;
84      libraryComboBox.DisplayMember = "Name";
85      libraryComboBox.DataSource = problemInstanceProviders.Keys.ToList();
86      libraryComboBox.Enabled = true;
87    }
88    #endregion
89
90    #region Events
91    private void CreateExperimentDialogV2_Load(object sender, System.EventArgs e) {
92      if (algorithm.Problem != null) {
93        parameterConfigurationTreeView.Content = parameterConfigurationTree = new ParameterConfigurationTree(algorithm, algorithm.Problem);
94        parameterConfigurationTree.ExperimentGenerationProgressChanged += (o, args) => progress.ProgressValue = parameterConfigurationTree.ExperimentGenerationProgress;
95        parameterConfigurationTree.CombinationsCountChanged += (o, args) => UpdateCombinationsCount();
96        new ProgressView(parameterConfigurationTreeView, progress) { CancelTimeoutMs = 10000 };
97      } else {
98        configurationTabControl.TabPages.Remove(problemInstancesTabPage);
99        SetEnabledStateOfControls(false);
100      }
101    }
102
103    private void CreateExperimentDialogV2_FormClosing(object sender, FormClosingEventArgs e) {
104      if (experimentGenerator != null) e.Cancel = true;
105    }
106
107    private void createBatchRunCheckBox_CheckedChanged(object sender, System.EventArgs e) {
108      repetitionsNumericUpDown.Enabled = createBatchRun = createBatchRunCheckBox.Checked;
109    }
110
111    private void repetitionsNumericUpDown_Validated(object sender, System.EventArgs e) {
112      if (repetitionsNumericUpDown.Text == string.Empty)
113        repetitionsNumericUpDown.Text = repetitionsNumericUpDown.Value.ToString();
114      repetitions = (int)repetitionsNumericUpDown.Value;
115    }
116
117    private void engineComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
118      engine = (IEngine)engineComboBox.SelectedItem;
119    }
120
121    private void configurationTabControl_SelectedIndexChanged(object sender, EventArgs e) {
122      if (configurationTabControl.SelectedTab == problemInstancesTabPage && problemInstanceProviders == null) {
123        libraryComboBox.Enabled = false;
124        instanceDiscoveryBackgroundWorker.RunWorkerAsync();
125      }
126    }
127
128    private void libraryComboBox_SelectedIndexChanged(object sender, EventArgs e) {
129      UpdateTreeView((IProblemInstanceProvider)libraryComboBox.SelectedItem);
130    }
131
132    private void instanceTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
133      if (e.Action != TreeViewAction.Unknown) {
134        var provider = e.Node.Tag as IProblemInstanceProvider;
135        if (provider != null) {
136          if (e.Node.Checked) {
137            if (!selectedProblemInstanceProviders.ContainsKey(provider))
138              selectedProblemInstanceProviders[provider] = new HashSet<IDataDescriptor>();
139            foreach (TreeNode node in e.Node.Nodes) {
140              selectedProblemInstanceProviders[provider].Add((IDataDescriptor)node.Tag);
141              node.Checked = e.Node.Checked;
142            }
143          } else {
144            selectedProblemInstanceProviders[provider].Clear();
145            foreach (TreeNode node in e.Node.Nodes) {
146              node.Checked = e.Node.Checked;
147            }
148          }
149        } else {
150          provider = (IProblemInstanceProvider)e.Node.Parent.Tag;
151          if (!selectedProblemInstanceProviders.ContainsKey(provider))
152            selectedProblemInstanceProviders[provider] = new HashSet<IDataDescriptor>();
153          if (e.Node.Checked) {
154            selectedProblemInstanceProviders[provider].Add((IDataDescriptor)e.Node.Tag);
155            var instances = new TreeNode[e.Node.Parent.Nodes.Count];
156            e.Node.Parent.Nodes.CopyTo(instances, 0);
157            e.Node.Parent.Checked = instances.All(x => x.Checked);
158          } else {
159            selectedProblemInstanceProviders[provider].Remove((IDataDescriptor)e.Node.Tag);
160            e.Node.Parent.Checked = e.Node.Checked;
161          }
162        }
163        UpdateCombinationsCount();
164      }
165    }
166
167    private void okButton_Click(object sender, System.EventArgs e) {
168      configurationTabControl.SelectedTab = parameterConfigurationTabPage;
169      experimentGenerator = Task.Factory.StartNew(() => {
170        StartProgressView();
171        var engineAlgorithm = algorithm as EngineAlgorithm;
172        if (engineAlgorithm != null) engineAlgorithm.Engine = engine;
173        try {
174          Experiment = createBatchRun ? parameterConfigurationTree.GenerateExperiment(engineAlgorithm, true, repetitions, selectedProblemInstanceProviders, cts.Token)
175                                      : parameterConfigurationTree.GenerateExperiment(engineAlgorithm, false, 0, selectedProblemInstanceProviders, cts.Token);
176        }
177        finally { FinishProgressView(); }
178      }, cts.Token);
179      experimentGenerator.ContinueWith(t => {
180        experimentGenerator = null;
181        CloseDialog();
182      }, TaskContinuationOptions.OnlyOnRanToCompletion);
183      experimentGenerator.ContinueWith(t => {
184        experimentGenerator = null;
185        if (t.IsCanceled) cts = new CancellationTokenSource();
186        if (t.IsFaulted) {
187          ReportError(t.Exception.Flatten());
188          t.Exception.Flatten().Handle(ex => true);
189        }
190      }, TaskContinuationOptions.NotOnRanToCompletion);
191    }
192    #endregion
193
194    #region Helpers
195    private void SetEnabledStateOfControls(bool state) {
196      createBatchRunCheckBox.Enabled = state;
197      repetitionsNumericUpDown.Enabled = state;
198      engineComboBox.Enabled = state;
199      okButton.Enabled = state;
200      cancelButton.Enabled = state;
201    }
202
203    private void UpdateTreeView(IProblemInstanceProvider provider) {
204      instanceTreeView.Nodes.Clear();
205      var rootNode = new TreeNode("All") { Tag = provider };
206      TreeNode[] instances = problemInstanceProviders[provider]
207                              .Select(x => new TreeNode(x.Name) {
208                                Tag = x,
209                                Checked = selectedProblemInstanceProviders.ContainsKey(provider)
210                                          && selectedProblemInstanceProviders[provider].Contains(x)
211                              })
212                              .ToArray();
213      rootNode.Checked = instances.All(x => x.Checked);
214      rootNode.Nodes.AddRange(instances);
215      rootNode.ExpandAll();
216      instanceTreeView.Nodes.Add(rootNode);
217    }
218
219    private void UpdateCombinationsCount() {
220      var combinationsCount = parameterConfigurationTree.CombinationsCount;
221      var instanceCount = 1 + selectedProblemInstanceProviders.Values.Sum(x => x.Count);
222      combinationsCountLabel.Text = (combinationsCount * instanceCount).ToString();
223    }
224
225    private void StartProgressView() {
226      if (InvokeRequired) {
227        Invoke(new Action(StartProgressView));
228      } else {
229        SetEnabledStateOfControls(false);
230        problemInstancesTabPage.Enabled = false;
231        progress.ProgressValue = 0;
232        progress.ProgressState = ProgressState.Started;
233      }
234    }
235
236    private void FinishProgressView() {
237      if (InvokeRequired) {
238        Invoke(new Action(FinishProgressView));
239      } else {
240        progress.Finish();
241        problemInstancesTabPage.Enabled = true;
242        SetEnabledStateOfControls(true);
243      }
244    }
245
246    private void ReportError(Exception e) {
247      if (InvokeRequired) {
248        Invoke(new Action<Exception>(ReportError), e);
249      } else {
250        ErrorHandling.ShowErrorDialog(this, "An error occurred generating the experiment.", e);
251      }
252    }
253
254    private void CloseDialog() {
255      if (InvokeRequired) {
256        Invoke(new Action(CloseDialog));
257      } else {
258        this.DialogResult = DialogResult.OK;
259        this.Close();
260      }
261    }
262    #endregion
263  }
264}
Note: See TracBrowser for help on using the repository browser.