Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 4533 was 4533, checked in by mkommend, 13 years ago

Corrected the execution time of BatchRuns (ticket #1222).

File size: 15.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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 algorithm is executed a given number of times.
34  /// </summary>
35  [Item("Batch Run", "A run in which an algorithm 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 override Image ItemImage {
42      get {
43        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
44        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStarted;
45        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePaused;
46        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
47        else return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event;
48      }
49    }
50
51    [Storable]
52    private ExecutionState executionState;
53    public ExecutionState ExecutionState {
54      get { return executionState; }
55      private set {
56        if (executionState != value) {
57          executionState = value;
58          OnExecutionStateChanged();
59          OnItemImageChanged();
60        }
61      }
62    }
63
64    [Storable]
65    private TimeSpan executionTime;
66    public TimeSpan ExecutionTime {
67      get {
68        if ((Algorithm != null) && (Algorithm.ExecutionState != ExecutionState.Stopped))
69          return executionTime + Algorithm.ExecutionTime;
70        else
71          return executionTime;
72      }
73      private set {
74        executionTime = value;
75        OnExecutionTimeChanged();
76      }
77    }
78
79    [Storable]
80    private IAlgorithm algorithm;
81    public IAlgorithm Algorithm {
82      get { return algorithm; }
83      set {
84        if (algorithm != value) {
85          if (algorithm != null) {
86            DeregisterAlgorithmEvents();
87            IEnumerable<IRun> runs = algorithm.Runs;
88            algorithm = null; //necessary to avoid removing the runs from the old algorithm
89            Runs.RemoveRange(runs);
90          }
91          algorithm = value;
92          if (algorithm != null) {
93            RegisterAlgorithmEvents();
94            Runs.AddRange(algorithm.Runs);
95          }
96          OnAlgorithmChanged();
97          Prepare();
98        }
99      }
100    }
101
102    [Storable]
103    private int repetitions;
104    public int Repetitions {
105      get { return repetitions; }
106      set {
107        if (repetitions != value) {
108          repetitions = value;
109          OnRepetitionsChanged();
110          if ((Algorithm != null) && (Algorithm.ExecutionState == ExecutionState.Stopped))
111            Prepare();
112        }
113      }
114    }
115    [Storable]
116    private int repetitionsCounter;
117
118    [Storable]
119    private RunCollection runs;
120    public RunCollection Runs {
121      get { return runs; }
122      private set {
123        if (value == null) throw new ArgumentNullException();
124        if (runs != value) {
125          if (runs != null) DeregisterRunsEvents();
126          runs = value;
127          if (runs != null) RegisterRunsEvents();
128        }
129      }
130    }
131
132    private bool stopPending;
133
134    public BatchRun()
135      : base() {
136      name = ItemName;
137      description = ItemDescription;
138      executionState = ExecutionState.Stopped;
139      executionTime = TimeSpan.Zero;
140      repetitions = 10;
141      repetitionsCounter = 0;
142      Runs = new RunCollection();
143      stopPending = false;
144    }
145    public BatchRun(string name)
146      : base(name) {
147      description = ItemDescription;
148      executionState = ExecutionState.Stopped;
149      executionTime = TimeSpan.Zero;
150      repetitions = 10;
151      repetitionsCounter = 0;
152      Runs = new RunCollection();
153      stopPending = false;
154    }
155    public BatchRun(string name, string description)
156      : base(name, description) {
157      executionState = ExecutionState.Stopped;
158      executionTime = TimeSpan.Zero;
159      repetitions = 10;
160      repetitionsCounter = 0;
161      Runs = new RunCollection();
162      stopPending = false;
163    }
164    [StorableConstructor]
165    private BatchRun(bool deserializing)
166      : base(deserializing) {
167      stopPending = false;
168    }
169
170    [StorableHook(HookType.AfterDeserialization)]
171    private void Initialize() {
172      if (algorithm != null) RegisterAlgorithmEvents();
173      if (runs != null) RegisterRunsEvents();
174    }
175
176    public override IDeepCloneable Clone(Cloner cloner) {
177      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
178      BatchRun clone = (BatchRun)base.Clone(cloner);
179      clone.executionState = executionState;
180      clone.executionTime = executionTime;
181      clone.algorithm = (IAlgorithm)cloner.Clone(algorithm);
182      clone.repetitions = repetitions;
183      clone.repetitionsCounter = repetitionsCounter;
184      clone.runs = (RunCollection)cloner.Clone(runs);
185      clone.stopPending = stopPending;
186      clone.Initialize();
187      return clone;
188    }
189
190    public void Prepare() {
191      Prepare(false);
192    }
193    public void Prepare(bool clearRuns) {
194      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
195        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
196      if (Algorithm != null) {
197        repetitionsCounter = 0;
198        if (clearRuns) runs.Clear();
199        Algorithm.Prepare(clearRuns);
200      }
201    }
202    public void Start() {
203      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
204        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
205      if (Algorithm != null) Algorithm.Start();
206    }
207    public void Pause() {
208      if (ExecutionState != ExecutionState.Started)
209        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
210      if ((Algorithm != null) && (Algorithm.ExecutionState == ExecutionState.Started))
211        Algorithm.Pause();
212    }
213    public void Stop() {
214      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
215        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
216      stopPending = true;
217      if ((Algorithm != null) &&
218          ((Algorithm.ExecutionState == ExecutionState.Started) || (Algorithm.ExecutionState == ExecutionState.Paused)))
219        Algorithm.Stop();
220    }
221
222    #region Events
223    public event EventHandler ExecutionStateChanged;
224    private void OnExecutionStateChanged() {
225      EventHandler handler = ExecutionStateChanged;
226      if (handler != null) handler(this, EventArgs.Empty);
227    }
228    public event EventHandler ExecutionTimeChanged;
229    private void OnExecutionTimeChanged() {
230      EventHandler handler = ExecutionTimeChanged;
231      if (handler != null) handler(this, EventArgs.Empty);
232    }
233    public event EventHandler AlgorithmChanged;
234    private void OnAlgorithmChanged() {
235      EventHandler handler = AlgorithmChanged;
236      if (handler != null) handler(this, EventArgs.Empty);
237    }
238    public event EventHandler RepetitionsChanged;
239    private void OnRepetitionsChanged() {
240      EventHandler handler = RepetitionsChanged;
241      if (handler != null) handler(this, EventArgs.Empty);
242    }
243    public event EventHandler Prepared;
244    private void OnPrepared() {
245      ExecutionState = ExecutionState.Prepared;
246      EventHandler handler = Prepared;
247      if (handler != null) handler(this, EventArgs.Empty);
248    }
249    public event EventHandler Started;
250    private void OnStarted() {
251      ExecutionState = ExecutionState.Started;
252      EventHandler handler = Started;
253      if (handler != null) handler(this, EventArgs.Empty);
254    }
255    public event EventHandler Paused;
256    private void OnPaused() {
257      ExecutionState = ExecutionState.Paused;
258      EventHandler handler = Paused;
259      if (handler != null) handler(this, EventArgs.Empty);
260    }
261    public event EventHandler Stopped;
262    private void OnStopped() {
263      ExecutionState = ExecutionState.Stopped;
264      EventHandler handler = Stopped;
265      if (handler != null) handler(this, EventArgs.Empty);
266    }
267    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
268    private void OnExceptionOccurred(Exception exception) {
269      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
270      if (handler != null) handler(this, new EventArgs<Exception>(exception));
271    }
272
273    private void RegisterAlgorithmEvents() {
274      algorithm.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
275      algorithm.ExecutionTimeChanged += new EventHandler(Algorithm_ExecutionTimeChanged);
276      algorithm.Paused += new EventHandler(Algorithm_Paused);
277      algorithm.Prepared += new EventHandler(Algorithm_Prepared);
278      algorithm.Started += new EventHandler(Algorithm_Started);
279      algorithm.Stopped += new EventHandler(Algorithm_Stopped);
280      algorithm.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_CollectionReset);
281      algorithm.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
282      algorithm.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsRemoved);
283    }
284    private void DeregisterAlgorithmEvents() {
285      algorithm.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Algorithm_ExceptionOccurred);
286      algorithm.ExecutionTimeChanged -= new EventHandler(Algorithm_ExecutionTimeChanged);
287      algorithm.Paused -= new EventHandler(Algorithm_Paused);
288      algorithm.Prepared -= new EventHandler(Algorithm_Prepared);
289      algorithm.Started -= new EventHandler(Algorithm_Started);
290      algorithm.Stopped -= new EventHandler(Algorithm_Stopped);
291      algorithm.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_CollectionReset);
292      algorithm.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsAdded);
293      algorithm.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Algorithm_Runs_ItemsRemoved);
294    }
295    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
296      OnExceptionOccurred(e.Value);
297    }
298    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
299      OnExecutionTimeChanged();
300    }
301    private void Algorithm_Paused(object sender, EventArgs e) {
302      OnPaused();
303    }
304    private void Algorithm_Prepared(object sender, EventArgs e) {
305      if ((ExecutionState == ExecutionState.Paused) || (ExecutionState == ExecutionState.Stopped))
306        OnPrepared();
307    }
308    private void Algorithm_Started(object sender, EventArgs e) {
309      stopPending = false;
310      if (ExecutionState != ExecutionState.Started)
311        OnStarted();
312    }
313    private void Algorithm_Stopped(object sender, EventArgs e) {
314      repetitionsCounter++;
315
316      if (!stopPending && (repetitionsCounter < repetitions)) {
317        Algorithm.Prepare();
318        Algorithm.Start();
319      } else {
320        OnStopped();
321      }
322    }
323    private void Algorithm_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
324      Runs.RemoveRange(e.OldItems);
325      Runs.AddRange(e.Items);
326    }
327    private void Algorithm_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
328      Runs.AddRange(e.Items);
329    }
330    private void Algorithm_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
331      Runs.RemoveRange(e.Items);
332    }
333
334    private void RegisterRunsEvents() {
335      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
336      runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
337      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
338    }
339
340    private void DeregisterRunsEvents() {
341      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
342      runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
343      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
344    }
345    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
346      foreach (IRun run in e.OldItems) {
347        IItem item;
348        run.Results.TryGetValue("Execution Time", out item);
349        TimeSpanValue executionTime = item as TimeSpanValue;
350        if (executionTime != null) ExecutionTime -= executionTime.Value;
351      }
352      if (Algorithm != null) Algorithm.Runs.RemoveRange(e.OldItems);
353      foreach (IRun run in e.Items) {
354        IItem item;
355        run.Results.TryGetValue("Execution Time", out item);
356        TimeSpanValue executionTime = item as TimeSpanValue;
357        if (executionTime != null) ExecutionTime += executionTime.Value;
358      }
359    }
360    private void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
361      foreach (IRun run in e.Items) {
362        IItem item;
363        run.Results.TryGetValue("Execution Time", out item);
364        TimeSpanValue executionTime = item as TimeSpanValue;
365        if (executionTime != null) ExecutionTime += executionTime.Value;
366      }
367    }
368    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
369      foreach (IRun run in e.Items) {
370        IItem item;
371        run.Results.TryGetValue("Execution Time", out item);
372        TimeSpanValue executionTime = item as TimeSpanValue;
373        if (executionTime != null) ExecutionTime -= executionTime.Value;
374      }
375      if (Algorithm != null) Algorithm.Runs.RemoveRange(e.Items);
376    }
377    #endregion
378  }
379}
Note: See TracBrowser for help on using the repository browser.