Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1853:

  • added problem instance selection to CreateExperimentDialog
  • adopted experiment creation
  • minor code improvements
File size: 11.3 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 Progress progress;
39    private readonly IAlgorithm algorithm;
40    private ParameterConfigurationTree parameterConfigurationTree;
41    private bool createBatchRun;
42    private int repetitions;
43    private IEngine engine;
44    private Task generation;
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        new ProgressView(parameterConfigurationTreeView, progress) { CancelTimeoutMs = 10000 };
96      } else {
97        configurationTabControl.TabPages.Remove(problemInstancesTabPage);
98        SetEnabledStateOfControls(false);
99      }
100    }
101
102    private void CreateExperimentDialogV2_FormClosing(object sender, FormClosingEventArgs e) {
103      if (generation != null) e.Cancel = true;
104    }
105
106    private void createBatchRunCheckBox_CheckedChanged(object sender, System.EventArgs e) {
107      repetitionsNumericUpDown.Enabled = createBatchRun = createBatchRunCheckBox.Checked;
108    }
109
110    private void repetitionsNumericUpDown_Validated(object sender, System.EventArgs e) {
111      if (repetitionsNumericUpDown.Text == string.Empty)
112        repetitionsNumericUpDown.Text = repetitionsNumericUpDown.Value.ToString();
113      repetitions = (int)repetitionsNumericUpDown.Value;
114    }
115
116    private void engineComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
117      engine = (IEngine)engineComboBox.SelectedItem;
118    }
119
120    private void configurationTabControl_SelectedIndexChanged(object sender, EventArgs e) {
121      if (configurationTabControl.SelectedTab == problemInstancesTabPage && problemInstanceProviders == null) {
122        libraryComboBox.Enabled = false;
123        instanceDiscoveryBackgroundWorker.RunWorkerAsync();
124      }
125    }
126
127    private void libraryComboBox_SelectedIndexChanged(object sender, EventArgs e) {
128      UpdateTreeView((IProblemInstanceProvider)libraryComboBox.SelectedItem);
129    }
130
131    private void instanceTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
132      if (e.Action != TreeViewAction.Unknown) {
133        var provider = e.Node.Tag as IProblemInstanceProvider;
134        if (provider != null) {
135          if (e.Node.Checked) {
136            if (!selectedProblemInstanceProviders.ContainsKey(provider))
137              selectedProblemInstanceProviders[provider] = new HashSet<IDataDescriptor>();
138            foreach (TreeNode node in e.Node.Nodes) {
139              selectedProblemInstanceProviders[provider].Add((IDataDescriptor)node.Tag);
140              node.Checked = e.Node.Checked;
141            }
142          } else {
143            selectedProblemInstanceProviders[provider].Clear();
144            foreach (TreeNode node in e.Node.Nodes) {
145              node.Checked = e.Node.Checked;
146            }
147          }
148        } else {
149          provider = (IProblemInstanceProvider)e.Node.Parent.Tag;
150          if (!selectedProblemInstanceProviders.ContainsKey(provider))
151            selectedProblemInstanceProviders[provider] = new HashSet<IDataDescriptor>();
152          if (e.Node.Checked) {
153            selectedProblemInstanceProviders[provider].Add((IDataDescriptor)e.Node.Tag);
154            var instances = new TreeNode[e.Node.Parent.Nodes.Count];
155            e.Node.Parent.Nodes.CopyTo(instances, 0);
156            e.Node.Parent.Checked = instances.All(x => x.Checked);
157          } else {
158            selectedProblemInstanceProviders[provider].Remove((IDataDescriptor)e.Node.Tag);
159            e.Node.Parent.Checked = e.Node.Checked;
160          }
161        }
162      }
163    }
164
165    private void calculateCombinationsButton_Click(object sender, EventArgs e) {
166      long parameterConfigurationsCnt = parameterConfigurationTree.GetCombinationCount(0);
167      int problemInstanceCnt = 1 + selectedProblemInstanceProviders.Values.Sum(x => x.Count);
168      combinationsTextBox.Text = (parameterConfigurationsCnt * problemInstanceCnt).ToString();
169    }
170
171    private void okButton_Click(object sender, System.EventArgs e) {
172      configurationTabControl.SelectedTab = parameterConfigurationTabPage;
173      generation = Task.Factory.StartNew(() => {
174        StartProgressView();
175        var engineAlgorithm = algorithm as EngineAlgorithm;
176        if (engineAlgorithm != null) engineAlgorithm.Engine = engine;
177        try {
178          Experiment = createBatchRun ? parameterConfigurationTree.GenerateExperiment(engineAlgorithm, true, repetitions, selectedProblemInstanceProviders, cts.Token)
179                                      : parameterConfigurationTree.GenerateExperiment(engineAlgorithm, false, 0, selectedProblemInstanceProviders, cts.Token);
180        }
181        finally { FinishProgressView(); }
182      }, cts.Token);
183      generation.ContinueWith(t => {
184        generation = null;
185        CloseDialog();
186      }, TaskContinuationOptions.OnlyOnRanToCompletion);
187      generation.ContinueWith(t => {
188        generation = null;
189        if (t.IsCanceled) cts = new CancellationTokenSource();
190        if (t.IsFaulted) {
191          ReportError(t.Exception.Flatten());
192          t.Exception.Flatten().Handle(ex => true);
193        }
194      }, TaskContinuationOptions.NotOnRanToCompletion);
195    }
196    #endregion
197
198    #region Helpers
199    private void SetEnabledStateOfControls(bool state) {
200      createBatchRunCheckBox.Enabled = state;
201      repetitionsNumericUpDown.Enabled = state;
202      engineComboBox.Enabled = state;
203      calculateCombinationsButton.Enabled = state;
204      okButton.Enabled = state;
205      cancelButton.Enabled = state;
206    }
207
208    private void UpdateTreeView(IProblemInstanceProvider provider) {
209      instanceTreeView.Nodes.Clear();
210      var rootNode = new TreeNode("All") { Tag = provider };
211      TreeNode[] instances = problemInstanceProviders[provider]
212                              .Select(x => new TreeNode(x.Name) {
213                                Tag = x,
214                                Checked = selectedProblemInstanceProviders.ContainsKey(provider)
215                                          && selectedProblemInstanceProviders[provider].Contains(x)
216                              })
217                              .ToArray();
218      rootNode.Checked = instances.All(x => x.Checked);
219      rootNode.Nodes.AddRange(instances);
220      rootNode.ExpandAll();
221      instanceTreeView.Nodes.Add(rootNode);
222    }
223
224    private void StartProgressView() {
225      if (InvokeRequired) {
226        Invoke(new Action(StartProgressView));
227      } else {
228        SetEnabledStateOfControls(false);
229        problemInstancesTabPage.Enabled = false;
230        progress.ProgressValue = 0;
231        progress.ProgressState = ProgressState.Started;
232      }
233    }
234
235    private void FinishProgressView() {
236      if (InvokeRequired) {
237        Invoke(new Action(FinishProgressView));
238      } else {
239        progress.Finish();
240        problemInstancesTabPage.Enabled = true;
241        SetEnabledStateOfControls(true);
242      }
243    }
244
245    private void ReportError(Exception e) {
246      if (InvokeRequired) {
247        Invoke(new Action<Exception>(ReportError), e);
248      } else {
249        ErrorHandling.ShowErrorDialog(this, "An error occurred generating the experiment.", e);
250      }
251    }
252
253    private void CloseDialog() {
254      if (InvokeRequired) {
255        Invoke(new Action(CloseDialog));
256      } else {
257        this.DialogResult = DialogResult.OK;
258        this.Close();
259      }
260    }
261    #endregion
262  }
263}
Note: See TracBrowser for help on using the repository browser.