Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization/3.3/Experiment.cs @ 4661

Last change on this file since 4661 was 4551, checked in by mkommend, 14 years ago

Corrected ExecutionState of experiments if optimizers are added or removed (ticket #1231).

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