Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1402 - Implemented IOptmizer.NestedOptimizers and adapted optimizer views to stop their content only if no way to display the content is available.

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