Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1853:

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