Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 5300 was 5300, checked in by swagner, 13 years ago

Enabled batch runs to deal with optimizers (#1378)

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