Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3280 was 3280, checked in by swagner, 14 years ago

Continued work on algorithm batch processing (#947).

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