source: trunk/sources/HeuristicLab.Optimization/3.3/BatchRun.cs @ 7576

Last change on this file since 7576 was 7576, checked in by mkommend, 8 years ago

#1783: Removed questionable source lines in execution state handling in the BatchRun and the Experiment.

File size: 16.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.Drawing;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
32  /// <summary>
33  /// A run in which an optimizer is executed a given number of times.
34  /// </summary>
35  [Item("Batch Run", "A run in which an optimizer is executed a given number of times.")]
36  [Creatable("Testing & Analysis")]
37  [StorableClass]
38  public sealed class BatchRun : NamedItem, IOptimizer, IStorableContent {
39    public string Filename { get; set; }
40
41    public static new Image StaticItemImage {
42      get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
43    }
44    public override Image ItemImage {
45      get {
46        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPrepared;
47        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStarted;
48        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPaused;
49        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStopped;
50        else return base.ItemImage;
51      }
52    }
53
54    [Storable]
55    private ExecutionState executionState;
56    public ExecutionState ExecutionState {
57      get { return executionState; }
58      private set {
59        if (executionState != value) {
60          executionState = value;
61          OnExecutionStateChanged();
62          OnItemImageChanged();
63        }
64      }
65    }
66
67    [Storable]
68    private TimeSpan executionTime;
69    public TimeSpan ExecutionTime {
70      get {
71        if ((Optimizer != null) && (Optimizer.ExecutionState != ExecutionState.Stopped))
72          return executionTime + Optimizer.ExecutionTime;
73        else
74          return executionTime;
75      }
76      private set {
77        executionTime = value;
78        OnExecutionTimeChanged();
79      }
80    }
81
82    [Storable]
83    private IOptimizer optimizer;
84    public IOptimizer Optimizer {
85      get { return optimizer; }
86      set {
87        if (optimizer != value) {
88          if (optimizer != null) {
89            DeregisterOptimizerEvents();
90            IEnumerable<IRun> runs = optimizer.Runs;
91            optimizer = null; //necessary to avoid removing the runs from the old optimizer
92            Runs.RemoveRange(runs);
93          }
94          optimizer = value;
95          if (optimizer != null) {
96            RegisterOptimizerEvents();
97            Runs.AddRange(optimizer.Runs);
98          }
99          OnOptimizerChanged();
100          Prepare();
101        }
102      }
103    }
104    // BackwardsCompatibility3.3
105    #region Backwards compatible code (remove with 3.4)
106    [Storable(AllowOneWay = true)]
107    private IAlgorithm algorithm {
108      set { optimizer = value; }
109    }
110    #endregion
111
112    [Storable]
113    private int repetitions;
114    public int Repetitions {
115      get { return repetitions; }
116      set {
117        if (repetitions != value) {
118          repetitions = value;
119          OnRepetitionsChanged();
120          if ((Optimizer != null) && (Optimizer.ExecutionState == ExecutionState.Stopped))
121            Prepare();
122        }
123      }
124    }
125    [Storable]
126    private int repetitionsCounter;
127
128    [Storable]
129    private RunCollection runs;
130    public RunCollection Runs {
131      get { return runs; }
132      private set {
133        if (value == null) throw new ArgumentNullException();
134        if (runs != value) {
135          if (runs != null) DeregisterRunsEvents();
136          runs = value;
137          if (runs != null) RegisterRunsEvents();
138        }
139      }
140    }
141
142    public IEnumerable<IOptimizer> NestedOptimizers {
143      get {
144        if (Optimizer == null) yield break;
145
146        yield return Optimizer;
147        foreach (IOptimizer opt in Optimizer.NestedOptimizers)
148          yield return opt;
149      }
150    }
151
152    private bool batchRunStarted = false;
153    private bool batchRunPaused = false;
154    private bool batchRunStopped = false;
155
156    public BatchRun()
157      : base() {
158      name = ItemName;
159      description = ItemDescription;
160      executionState = ExecutionState.Stopped;
161      executionTime = TimeSpan.Zero;
162      repetitions = 10;
163      repetitionsCounter = 0;
164      Runs = new RunCollection();
165    }
166    public BatchRun(string name)
167      : base(name) {
168      description = ItemDescription;
169      executionState = ExecutionState.Stopped;
170      executionTime = TimeSpan.Zero;
171      repetitions = 10;
172      repetitionsCounter = 0;
173      Runs = new RunCollection();
174    }
175    public BatchRun(string name, string description)
176      : base(name, description) {
177      executionState = ExecutionState.Stopped;
178      executionTime = TimeSpan.Zero;
179      repetitions = 10;
180      repetitionsCounter = 0;
181      Runs = new RunCollection();
182    }
183    [StorableConstructor]
184    private BatchRun(bool deserializing) : base(deserializing) { }
185    [StorableHook(HookType.AfterDeserialization)]
186    private void AfterDeserialization() {
187      Initialize();
188    }
189
190    private BatchRun(BatchRun original, Cloner cloner)
191      : base(original, cloner) {
192      executionState = original.executionState;
193      executionTime = original.executionTime;
194      optimizer = cloner.Clone(original.optimizer);
195      repetitions = original.repetitions;
196      repetitionsCounter = original.repetitionsCounter;
197      runs = cloner.Clone(original.runs);
198      batchRunStarted = original.batchRunStarted;
199      batchRunPaused = original.batchRunPaused;
200      batchRunStopped = original.batchRunStopped;
201      Initialize();
202    }
203    public override IDeepCloneable Clone(Cloner cloner) {
204      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
205      return new BatchRun(this, cloner);
206    }
207
208    private void Initialize() {
209      if (optimizer != null) RegisterOptimizerEvents();
210      if (runs != null) RegisterRunsEvents();
211    }
212
213    public void Prepare() {
214      Prepare(false);
215    }
216    public void Prepare(bool clearRuns) {
217      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
218        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
219      if (Optimizer != null) {
220        repetitionsCounter = 0;
221        if (clearRuns) runs.Clear();
222        Optimizer.Prepare(clearRuns);
223      } else {
224        ExecutionState = ExecutionState.Stopped;
225      }
226    }
227    public void Start() {
228      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
229        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
230      if (Optimizer == null) return;
231
232      batchRunStarted = true;
233      batchRunPaused = false;
234      batchRunStopped = false;
235      if (Optimizer.ExecutionState == ExecutionState.Stopped) Optimizer.Prepare();
236      Optimizer.Start();
237    }
238    public void Pause() {
239      if (ExecutionState != ExecutionState.Started)
240        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
241      if (Optimizer == null) return;
242      if (Optimizer.ExecutionState != ExecutionState.Started) return;
243
244      batchRunStarted = false;
245      batchRunPaused = true;
246      batchRunStopped = false;
247      Optimizer.Pause();
248    }
249    public void Stop() {
250      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
251        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
252      if (Optimizer == null) return;
253      if (Optimizer.ExecutionState != ExecutionState.Started && Optimizer.ExecutionState != ExecutionState.Paused) return;
254      batchRunStarted = false;
255      batchRunPaused = false;
256      batchRunStopped = true;
257      Optimizer.Stop();
258    }
259
260    #region Events
261    public event EventHandler ExecutionStateChanged;
262    private void OnExecutionStateChanged() {
263      EventHandler handler = ExecutionStateChanged;
264      if (handler != null) handler(this, EventArgs.Empty);
265    }
266    public event EventHandler ExecutionTimeChanged;
267    private void OnExecutionTimeChanged() {
268      EventHandler handler = ExecutionTimeChanged;
269      if (handler != null) handler(this, EventArgs.Empty);
270    }
271    public event EventHandler OptimizerChanged;
272    private void OnOptimizerChanged() {
273      EventHandler handler = OptimizerChanged;
274      if (handler != null) handler(this, EventArgs.Empty);
275    }
276    public event EventHandler RepetitionsChanged;
277    private void OnRepetitionsChanged() {
278      EventHandler handler = RepetitionsChanged;
279      if (handler != null) handler(this, EventArgs.Empty);
280    }
281    public event EventHandler Prepared;
282    private void OnPrepared() {
283      ExecutionState = ExecutionState.Prepared;
284      EventHandler handler = Prepared;
285      if (handler != null) handler(this, EventArgs.Empty);
286    }
287    public event EventHandler Started;
288    private void OnStarted() {
289      ExecutionState = ExecutionState.Started;
290      EventHandler handler = Started;
291      if (handler != null) handler(this, EventArgs.Empty);
292    }
293    public event EventHandler Paused;
294    private void OnPaused() {
295      ExecutionState = ExecutionState.Paused;
296      EventHandler handler = Paused;
297      if (handler != null) handler(this, EventArgs.Empty);
298    }
299    public event EventHandler Stopped;
300    private void OnStopped() {
301      ExecutionState = ExecutionState.Stopped;
302      EventHandler handler = Stopped;
303      if (handler != null) handler(this, EventArgs.Empty);
304    }
305    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
306    private void OnExceptionOccurred(Exception exception) {
307      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
308      if (handler != null) handler(this, new EventArgs<Exception>(exception));
309    }
310
311    private void RegisterOptimizerEvents() {
312      optimizer.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
313      optimizer.ExecutionTimeChanged += new EventHandler(Optimizer_ExecutionTimeChanged);
314      optimizer.Paused += new EventHandler(Optimizer_Paused);
315      optimizer.Prepared += new EventHandler(Optimizer_Prepared);
316      optimizer.Started += new EventHandler(Optimizer_Started);
317      optimizer.Stopped += new EventHandler(Optimizer_Stopped);
318      optimizer.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
319      optimizer.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
320      optimizer.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
321    }
322    private void DeregisterOptimizerEvents() {
323      optimizer.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
324      optimizer.ExecutionTimeChanged -= new EventHandler(Optimizer_ExecutionTimeChanged);
325      optimizer.Paused -= new EventHandler(Optimizer_Paused);
326      optimizer.Prepared -= new EventHandler(Optimizer_Prepared);
327      optimizer.Started -= new EventHandler(Optimizer_Started);
328      optimizer.Stopped -= new EventHandler(Optimizer_Stopped);
329      optimizer.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
330      optimizer.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
331      optimizer.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
332    }
333    private void Optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
334      OnExceptionOccurred(e.Value);
335    }
336    private void Optimizer_ExecutionTimeChanged(object sender, EventArgs e) {
337      OnExecutionTimeChanged();
338    }
339    private void Optimizer_Paused(object sender, EventArgs e) {
340      if (ExecutionState == ExecutionState.Started) {
341        OnPaused();
342      }
343    }
344    private void Optimizer_Prepared(object sender, EventArgs e) {
345      if (ExecutionState == ExecutionState.Stopped || !batchRunStarted) {
346        OnPrepared();
347      }
348    }
349    private void Optimizer_Started(object sender, EventArgs e) {
350      if (ExecutionState != ExecutionState.Started)
351        OnStarted();
352    }
353    private void Optimizer_Stopped(object sender, EventArgs e) {
354      repetitionsCounter++;
355
356      if (batchRunStopped) OnStopped();
357      else if (repetitionsCounter >= repetitions) OnStopped();
358      else if (batchRunPaused) OnPaused();
359      else if (batchRunStarted) {
360        Optimizer.Prepare();
361        Optimizer.Start();
362      } else OnStopped();
363    }
364    private void Optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
365      Runs.RemoveRange(e.OldItems);
366      Runs.AddRange(e.Items);
367    }
368    private void Optimizer_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
369      Runs.AddRange(e.Items);
370    }
371    private void Optimizer_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
372      Runs.RemoveRange(e.Items);
373    }
374
375    private void RegisterRunsEvents() {
376      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
377      runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
378      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
379    }
380
381    private void DeregisterRunsEvents() {
382      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
383      runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
384      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
385    }
386    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
387      foreach (IRun run in e.OldItems) {
388        IItem item;
389        run.Results.TryGetValue("Execution Time", out item);
390        TimeSpanValue executionTime = item as TimeSpanValue;
391        if (executionTime != null) ExecutionTime -= executionTime.Value;
392      }
393      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.OldItems);
394      foreach (IRun run in e.Items) {
395        IItem item;
396        run.Results.TryGetValue("Execution Time", out item);
397        TimeSpanValue executionTime = item as TimeSpanValue;
398        if (executionTime != null) ExecutionTime += executionTime.Value;
399      }
400    }
401    private void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
402      foreach (IRun run in e.Items) {
403        IItem item;
404        run.Results.TryGetValue("Execution Time", out item);
405        TimeSpanValue executionTime = item as TimeSpanValue;
406        if (executionTime != null) ExecutionTime += executionTime.Value;
407      }
408    }
409    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
410      foreach (IRun run in e.Items) {
411        IItem item;
412        run.Results.TryGetValue("Execution Time", out item);
413        TimeSpanValue executionTime = item as TimeSpanValue;
414        if (executionTime != null) ExecutionTime -= executionTime.Value;
415      }
416      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.Items);
417    }
418    #endregion
419  }
420}
Note: See TracBrowser for help on using the repository browser.