Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3932 was 3716, checked in by swagner, 15 years ago

Implemented reviewers' comments (#947)

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