Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 8150 was 8150, checked in by mkommend, 12 years ago

#1884: Corrected special case in executime calculation of the Batchrun if the inner optimizer is prepared.

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