Ignore:
Timestamp:
05/18/12 14:08:11 (7 years ago)
Author:
abeham
Message:

#1851:

  • Moved common methods from problem instance management into a ProblemInstanceManager
  • Made experiment creation asynchronous by using a BackgroundWorker
  • Added a progress bar to display the progress as well as the instance that is currently processed
  • Added "select all" and "select none" options which are updated to the state of the listview
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Optimizer/3.3/CreateExperimentDialog.cs

    r7841 r7846  
    2222using System;
    2323using System.Collections.Generic;
     24using System.ComponentModel;
    2425using System.Linq;
     26using System.Threading;
    2527using System.Windows.Forms;
    2628using HeuristicLab.Optimization;
    27 using HeuristicLab.PluginInfrastructure;
    2829using HeuristicLab.Problems.Instances;
    2930
     
    3738        experiment = null;
    3839        okButton.Enabled = optimizer != null;
     40        FillOrHideInstanceListView();
    3941      }
    4042    }
     
    4547    }
    4648
     49    private bool createBatchRun;
     50    private int repetitions;
     51    private EventWaitHandle backgroundWorkerWaitHandle = new ManualResetEvent(false);
     52    private bool suppressListViewEventHandling;
     53
    4754    public CreateExperimentDialog() : this(null) { }
    4855    public CreateExperimentDialog(IOptimizer optimizer) {
    4956      InitializeComponent();
     57      createBatchRun = createBatchRunCheckBox.Checked;
     58      repetitions = (int)repetitionsNumericUpDown.Value;
    5059      Optimizer = optimizer;
    51       experiment = null;
    52       instancesListView.Items.Clear();
    53       instancesListView.Groups.Clear();
    54       FillOrHideInstanceListView();
    5560    }
    5661
    5762    private void FillOrHideInstanceListView() {
    58       if (Optimizer != null && optimizer is IAlgorithm) {
     63      if (optimizer != null && optimizer is IAlgorithm) {
    5964        var algorithm = (IAlgorithm)Optimizer;
    6065        if (algorithm.Problem != null) {
    61           var instanceProviders = GetProblemInstanceProviders(algorithm.Problem);
     66          var instanceProviders = ProblemInstanceManager.GetProviders(algorithm.Problem);
    6267          if (instanceProviders.Any()) {
    63             foreach (var provider in instanceProviders) {
    64               var group = new ListViewGroup(provider.Name, provider.Name);
    65               group.Tag = provider;
    66               instancesListView.Groups.Add(group);
    67               IEnumerable<IDataDescriptor> descriptors = ((dynamic)provider).GetDataDescriptors();
    68               foreach (var d in descriptors) {
    69                 var item = new ListViewItem(d.Name, group);
    70                 item.Checked = true;
    71                 item.Tag = d;
    72                 instancesListView.Items.Add(item);
    73               }
     68            FillInstanceListView(instanceProviders);
     69            if (instancesListView.Items.Count > 0) {
     70              selectAllCheckBox.Visible = true;
     71              selectNoneCheckBox.Visible = true;
     72              instancesLabel.Visible = true;
     73              instancesListView.Visible = true;
     74              Height = 330;
     75              return;
    7476            }
    75             instancesListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
    76             if (instancesListView.Items.Count > 0) return;
    7777          }
    7878        }
    7979      }
     80      selectAllCheckBox.Visible = false;
     81      selectNoneCheckBox.Visible = false;
    8082      instancesLabel.Visible = false;
    8183      instancesListView.Visible = false;
     
    8385    }
    8486
    85     private IEnumerable<IProblemInstanceProvider> GetProblemInstanceProviders(IProblem problem) {
    86       var consumerTypes = problem.GetType().GetInterfaces()
    87         .Where(x => x.IsGenericType
    88           && x.GetGenericTypeDefinition() == typeof(IProblemInstanceConsumer<>));
    89 
    90       if (consumerTypes.Any()) {
    91         var instanceTypes = consumerTypes
    92           .Select(x => x.GetGenericArguments().First())
    93           .Select(x => typeof(IProblemInstanceProvider<>).MakeGenericType(x));
    94 
    95         foreach (var type in instanceTypes) {
    96           foreach (var provider in ApplicationManager.Manager.GetInstances(type))
    97             yield return (IProblemInstanceProvider)provider;
     87    private void FillInstanceListView(IEnumerable<IProblemInstanceProvider> instanceProviders) {
     88      foreach (var provider in instanceProviders) {
     89        var group = new ListViewGroup(provider.Name, provider.Name);
     90        group.Tag = provider;
     91        instancesListView.Groups.Add(group);
     92        foreach (var d in ProblemInstanceManager.GetDataDescriptors(provider)) {
     93          var item = new ListViewItem(d.Name, group);
     94          item.Tag = d;
     95          instancesListView.Items.Add(item);
    9896        }
    9997      }
     98      instancesListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
     99      selectAllCheckBox.Checked = true;
    100100    }
    101101
    102102    private void createBatchRunCheckBox_CheckedChanged(object sender, EventArgs e) {
    103103      repetitionsNumericUpDown.Enabled = createBatchRunCheckBox.Checked;
     104      createBatchRun = createBatchRunCheckBox.Checked;
    104105    }
    105106    private void repetitionsNumericUpDown_Validated(object sender, EventArgs e) {
    106107      if (repetitionsNumericUpDown.Text == string.Empty)
    107108        repetitionsNumericUpDown.Text = repetitionsNumericUpDown.Value.ToString();
     109      repetitions = (int)repetitionsNumericUpDown.Value;
     110    }
     111    private void selectAllCheckBox_CheckedChanged(object sender, EventArgs e) {
     112      if (selectAllCheckBox.Checked) {
     113        selectNoneCheckBox.Checked = false;
     114        if (instancesListView.CheckedItems.Count == instancesListView.Items.Count) return;
     115        try {
     116          suppressListViewEventHandling = true;
     117          foreach (var item in instancesListView.Items.OfType<ListViewItem>()) {
     118            item.Checked = true;
     119          }
     120        } finally { suppressListViewEventHandling = false; }
     121      }
     122    }
     123    private void selectNoneCheckBox_CheckedChanged(object sender, EventArgs e) {
     124      if (selectNoneCheckBox.Checked) {
     125        selectAllCheckBox.Checked = false;
     126        if (instancesListView.CheckedItems.Count == 0) return;
     127        try {
     128          suppressListViewEventHandling = true;
     129          foreach (var item in instancesListView.Items.OfType<ListViewItem>()) {
     130            item.Checked = false;
     131          }
     132        } finally { suppressListViewEventHandling = false; }
     133      }
     134    }
     135    private void instancesListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
     136      if (!suppressListViewEventHandling) {
     137        selectAllCheckBox.Checked = instancesListView.Items.Count == instancesListView.CheckedItems.Count;
     138        selectNoneCheckBox.Checked = instancesListView.CheckedItems.Count == 0;
     139      }
    108140    }
    109141    private void okButton_Click(object sender, EventArgs e) {
    110       experiment = new Experiment();
    111       if (instancesListView.CheckedItems.Count == 0) {
    112         AddOptimizer((IOptimizer)Optimizer.Clone());
     142      SetMode(createExperiment: true);
     143      experimentCreationBackgroundWorker.RunWorkerAsync(GetSelectedInstances());
     144      backgroundWorkerWaitHandle.WaitOne();
     145    }
     146    private void experimentCreationBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
     147      backgroundWorkerWaitHandle.Set();
     148      experimentCreationBackgroundWorker.ReportProgress(0, string.Empty);
     149      var items = (Dictionary<IProblemInstanceProvider, List<IDataDescriptor>>)e.Argument;
     150      var localExperiment = new Experiment();
     151      if (items.Count == 0) {
     152        AddOptimizer((IOptimizer)Optimizer.Clone(), localExperiment);
     153        experimentCreationBackgroundWorker.ReportProgress(100, string.Empty);
    113154      } else {
    114         foreach (var item in instancesListView.CheckedItems.OfType<ListViewItem>()) {
    115           var descriptor = (IDataDescriptor)item.Tag;
    116           var provider = (IProblemInstanceProvider)item.Group.Tag;
    117           var algorithm = (IAlgorithm)Optimizer.Clone();
    118           ((dynamic)algorithm.Problem).Load(((dynamic)provider).LoadData(descriptor));
    119           AddOptimizer(algorithm);
     155        int counter = 0, total = items.SelectMany(x => x.Value).Count();
     156        foreach (var provider in items.Keys) {
     157          foreach (var descriptor in items[provider]) {
     158            var algorithm = (IAlgorithm)Optimizer.Clone();
     159            ProblemInstanceManager.LoadData(provider, descriptor, (IProblemInstanceConsumer)algorithm.Problem);
     160            AddOptimizer(algorithm, localExperiment);
     161            counter++;
     162            experimentCreationBackgroundWorker.ReportProgress((int)Math.Round(100.0 * counter / total), descriptor.Name);
     163            if (experimentCreationBackgroundWorker.CancellationPending) {
     164              e.Cancel = true;
     165              localExperiment = null;
     166              break;
     167            }
     168          }
    120169        }
    121170      }
    122       Experiment.Prepare(true);
    123     }
    124 
    125     private void AddOptimizer(IOptimizer optimizer) {
    126       if (createBatchRunCheckBox.Checked) {
     171      if (localExperiment != null) localExperiment.Prepare(true);
     172      e.Result = localExperiment;
     173    }
     174    private void experimentCreationBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
     175      experimentCreationProgressBar.Value = e.ProgressPercentage;
     176      progressLabel.Text = (string)e.UserState;
     177    }
     178    private void experimentCreationBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
     179      SetMode(createExperiment: false);
     180      if (e.Error != null) MessageBox.Show(e.Error.Message, "Error occurred", MessageBoxButtons.OK, MessageBoxIcon.Error);
     181      if (!e.Cancelled && e.Error == null) {
     182        experiment = (Experiment)e.Result;
     183        DialogResult = System.Windows.Forms.DialogResult.OK;
     184        Close();
     185      }
     186    }
     187    private void CreateExperimentDialog_FormClosing(object sender, FormClosingEventArgs e) {
     188      if (experimentCreationBackgroundWorker.IsBusy) {
     189        if (DialogResult != System.Windows.Forms.DialogResult.OK)
     190          experimentCreationBackgroundWorker.CancelAsync();
     191        e.Cancel = true;
     192      }
     193    }
     194
     195    private void AddOptimizer(IOptimizer optimizer, Experiment experiment) {
     196      if (createBatchRun) {
    127197        var batchRun = new BatchRun();
    128         batchRun.Repetitions = (int)repetitionsNumericUpDown.Value;
     198        batchRun.Repetitions = repetitions;
    129199        batchRun.Optimizer = optimizer;
    130200        experiment.Optimizers.Add(batchRun);
     
    133203      }
    134204    }
     205
     206    private void SetMode(bool createExperiment) {
     207      createBatchRunCheckBox.Enabled = !createExperiment;
     208      repetitionsNumericUpDown.Enabled = !createExperiment;
     209      selectAllCheckBox.Enabled = !createExperiment;
     210      selectNoneCheckBox.Enabled = !createExperiment;
     211      instancesListView.Enabled = !createExperiment;
     212      okButton.Enabled = !createExperiment;
     213      okButton.Visible = !createExperiment;
     214      progressLabel.Visible = createExperiment;
     215      experimentCreationProgressBar.Visible = createExperiment;
     216    }
     217
     218    private Dictionary<IProblemInstanceProvider, List<IDataDescriptor>> GetSelectedInstances() {
     219      var selectedInstances = new Dictionary<IProblemInstanceProvider, List<IDataDescriptor>>();
     220      foreach (var checkedItem in instancesListView.CheckedItems.OfType<ListViewItem>()) {
     221        if (!selectedInstances.ContainsKey((IProblemInstanceProvider)checkedItem.Group.Tag))
     222          selectedInstances.Add((IProblemInstanceProvider)checkedItem.Group.Tag, new List<IDataDescriptor>());
     223        selectedInstances[(IProblemInstanceProvider)checkedItem.Group.Tag].Add((IDataDescriptor)checkedItem.Tag);
     224      }
     225      return selectedInstances;
     226    }
    135227  }
    136228}
Note: See TracChangeset for help on using the changeset viewer.