Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 4174 was 4115, checked in by mkommend, 14 years ago

Added correct handling of adding and removing runs in experiments and batch runs (ticket #1111).

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