Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 7238 was 7238, checked in by ascheibe, 12 years ago

#1714 reverted the changes from r7196 and r7197. If an optimizer in the experiment is stopped and there exists another prepared optimizer, the experiment is now set to prepared. This enables the correct buttons in the experiment view and the remaining optimizers can be executed.

File size: 16.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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 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.ExperimentPrepared;
47        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.ExperimentStarted;
48        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExperimentPaused;
49        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.ExperimentStopped;
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 { return executionTime; }
71      private set {
72        executionTime = value;
73        OnExecutionTimeChanged();
74      }
75    }
76
77    [Storable]
78    private OptimizerList optimizers;
79    public OptimizerList Optimizers {
80      get { return optimizers; }
81    }
82
83    [Storable]
84    private RunCollection runs;
85    public RunCollection Runs {
86      get { return runs; }
87      private set {
88        if (value == null) throw new ArgumentNullException();
89        if (runs != value) {
90          if (runs != null) DeregisterRunsEvents();
91          runs = value;
92          if (runs != null) RegisterRunsEvents();
93        }
94      }
95    }
96
97    public IEnumerable<IOptimizer> NestedOptimizers {
98      get {
99        if (Optimizers == null) yield break;
100
101        foreach (IOptimizer opt in Optimizers) {
102          yield return opt;
103          foreach (IOptimizer nestedOpt in opt.NestedOptimizers)
104            yield return nestedOpt;
105        }
106      }
107    }
108
109    private bool experimentStarted = false;
110    private bool experimentStopped = false;
111
112    public Experiment()
113      : base() {
114      name = ItemName;
115      description = ItemDescription;
116      executionState = ExecutionState.Stopped;
117      executionTime = TimeSpan.Zero;
118      optimizers = new OptimizerList();
119      Runs = new RunCollection();
120      Initialize();
121    }
122    public Experiment(string name)
123      : base(name) {
124      description = ItemDescription;
125      executionState = ExecutionState.Stopped;
126      executionTime = TimeSpan.Zero;
127      optimizers = new OptimizerList();
128      Runs = new RunCollection();
129      Initialize();
130    }
131    public Experiment(string name, string description)
132      : base(name, description) {
133      executionState = ExecutionState.Stopped;
134      executionTime = TimeSpan.Zero;
135      optimizers = new OptimizerList();
136      Runs = new RunCollection();
137      Initialize();
138    }
139    [StorableConstructor]
140    private Experiment(bool deserializing) : base(deserializing) { }
141    [StorableHook(HookType.AfterDeserialization)]
142    private void AfterDeserialization() {
143      Initialize();
144    }
145    private Experiment(Experiment original, Cloner cloner)
146      : base(original, cloner) {
147      executionState = original.executionState;
148      executionTime = original.executionTime;
149      optimizers = cloner.Clone(original.optimizers);
150      runs = cloner.Clone(original.runs);
151
152      experimentStarted = original.experimentStarted;
153      experimentStopped = original.experimentStopped;
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) return;
175
176      if (clearRuns) runs.Clear();
177      foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState != ExecutionState.Started))
178        if (clearRuns || optimizer.ExecutionState != ExecutionState.Prepared)
179          optimizer.Prepare(clearRuns);
180    }
181    public void Start() {
182      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
183        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
184      if (Optimizers.Count == 0) return;
185
186      experimentStarted = true;
187      experimentStopped = false;
188      IOptimizer optimizer = Optimizers.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
189      if (optimizer != null) optimizer.Start();
190    }
191    public void Pause() {
192      if (ExecutionState != ExecutionState.Started)
193        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
194      if (Optimizers.Count == 0) return;
195
196      experimentStarted = false;
197      experimentStopped = false;
198      foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState == ExecutionState.Started))
199        optimizer.Pause();
200    }
201    public void Stop() {
202      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
203        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
204      if (Optimizers.Count == 0) return;
205
206      experimentStarted = false;
207      experimentStopped = true;
208      foreach (IOptimizer optimizer in Optimizers.Where(x => (x.ExecutionState == ExecutionState.Started) || (x.ExecutionState == ExecutionState.Paused)))
209        optimizer.Stop();
210    }
211
212    #region Events
213    public event EventHandler ExecutionStateChanged;
214    private void OnExecutionStateChanged() {
215      EventHandler handler = ExecutionStateChanged;
216      if (handler != null) handler(this, EventArgs.Empty);
217    }
218    public event EventHandler ExecutionTimeChanged;
219    private void OnExecutionTimeChanged() {
220      EventHandler handler = ExecutionTimeChanged;
221      if (handler != null) handler(this, EventArgs.Empty);
222    }
223    public event EventHandler Prepared;
224    private void OnPrepared() {
225      ExecutionState = ExecutionState.Prepared;
226      EventHandler handler = Prepared;
227      if (handler != null) handler(this, EventArgs.Empty);
228    }
229    public event EventHandler Started;
230    private void OnStarted() {
231      ExecutionState = ExecutionState.Started;
232      EventHandler handler = Started;
233      if (handler != null) handler(this, EventArgs.Empty);
234    }
235    public event EventHandler Paused;
236    private void OnPaused() {
237      ExecutionState = ExecutionState.Paused;
238      EventHandler handler = Paused;
239      if (handler != null) handler(this, EventArgs.Empty);
240    }
241    public event EventHandler Stopped;
242    private void OnStopped() {
243      ExecutionState = ExecutionState.Stopped;
244      EventHandler handler = Stopped;
245      if (handler != null) handler(this, EventArgs.Empty);
246    }
247    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
248    private void OnExceptionOccurred(Exception exception) {
249      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
250      if (handler != null) handler(this, new EventArgs<Exception>(exception));
251    }
252
253    private void RegisterOptimizersEvents() {
254      Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
255      Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
256      Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
257      Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
258    }
259    private void DeregisterOptimizersEvents() {
260      Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
261      Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
262      Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
263      Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
264    }
265    private void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
266      foreach (IndexedItem<IOptimizer> item in e.OldItems)
267        RemoveOptimizer(item.Value);
268      foreach (IndexedItem<IOptimizer> item in e.Items)
269        AddOptimizer(item.Value);
270    }
271    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
272      foreach (IndexedItem<IOptimizer> item in e.Items)
273        AddOptimizer(item.Value);
274    }
275    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
276      foreach (IndexedItem<IOptimizer> item in e.Items)
277        RemoveOptimizer(item.Value);
278    }
279    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
280      foreach (IndexedItem<IOptimizer> item in e.OldItems)
281        RemoveOptimizer(item.Value);
282      foreach (IndexedItem<IOptimizer> item in e.Items)
283        AddOptimizer(item.Value);
284    }
285    private void AddOptimizer(IOptimizer optimizer) {
286      RegisterOptimizerEvents(optimizer);
287      Runs.AddRange(optimizer.Runs);
288      optimizer.Prepare();
289      if (ExecutionState == ExecutionState.Stopped && optimizer.ExecutionState == ExecutionState.Prepared)
290        OnPrepared();
291    }
292    private void RemoveOptimizer(IOptimizer optimizer) {
293      DeregisterOptimizerEvents(optimizer);
294      Runs.RemoveRange(optimizer.Runs);
295      if (ExecutionState == ExecutionState.Prepared && !optimizers.Any(opt => opt.ExecutionState == ExecutionState.Prepared))
296        OnStopped();
297    }
298
299    private void RegisterOptimizerEvents(IOptimizer optimizer) {
300      optimizer.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(optimizer_ExceptionOccurred);
301      optimizer.ExecutionTimeChanged += new EventHandler(optimizer_ExecutionTimeChanged);
302      optimizer.Paused += new EventHandler(optimizer_Paused);
303      optimizer.Prepared += new EventHandler(optimizer_Prepared);
304      optimizer.Started += new EventHandler(optimizer_Started);
305      optimizer.Stopped += new EventHandler(optimizer_Stopped);
306      optimizer.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_CollectionReset);
307      optimizer.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsAdded);
308      optimizer.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsRemoved);
309    }
310    private void DeregisterOptimizerEvents(IOptimizer optimizer) {
311      optimizer.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(optimizer_ExceptionOccurred);
312      optimizer.ExecutionTimeChanged -= new EventHandler(optimizer_ExecutionTimeChanged);
313      optimizer.Paused -= new EventHandler(optimizer_Paused);
314      optimizer.Prepared -= new EventHandler(optimizer_Prepared);
315      optimizer.Started -= new EventHandler(optimizer_Started);
316      optimizer.Stopped -= new EventHandler(optimizer_Stopped);
317      optimizer.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_CollectionReset);
318      optimizer.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsAdded);
319      optimizer.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsRemoved);
320    }
321    private void optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
322      OnExceptionOccurred(e.Value);
323    }
324    private void optimizer_ExecutionTimeChanged(object sender, EventArgs e) {
325      ExecutionTime = Optimizers.Aggregate(TimeSpan.Zero, (t, o) => t + o.ExecutionTime);
326    }
327    private void optimizer_Paused(object sender, EventArgs e) {
328      if (Optimizers.All(x => x.ExecutionState != ExecutionState.Started))
329        OnPaused();
330    }
331    private void optimizer_Prepared(object sender, EventArgs e) {
332      if (ExecutionState == ExecutionState.Stopped)
333        OnPrepared();
334    }
335    private void optimizer_Started(object sender, EventArgs e) {
336      if (ExecutionState != ExecutionState.Started)
337        OnStarted();
338    }
339    private void optimizer_Stopped(object sender, EventArgs e) {
340      if (!experimentStarted && Optimizers.Any(o => o.ExecutionState == ExecutionState.Prepared) && Optimizers.All(o => o.ExecutionState != ExecutionState.Started && o.ExecutionState != ExecutionState.Paused)) OnPrepared();
341      else if (Optimizers.All(o => o.ExecutionState == ExecutionState.Stopped)) OnStopped();
342      else if (Optimizers.Any(o => o.ExecutionState == ExecutionState.Paused) && Optimizers.All(o => o.ExecutionState != ExecutionState.Started)) OnPaused();
343      else if (experimentStarted && !experimentStopped && Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused))) {
344        Optimizers.First(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)).Start();
345      }
346    }
347    private void optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
348      Runs.RemoveRange(e.OldItems);
349      Runs.AddRange(e.Items);
350    }
351    private void optimizer_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
352      Runs.AddRange(e.Items);
353    }
354    private void optimizer_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
355      Runs.RemoveRange(e.Items);
356    }
357
358    private void RegisterRunsEvents() {
359      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
360      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
361    }
362    private void DeregisterRunsEvents() {
363      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
364      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
365    }
366    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
367      foreach (IOptimizer optimizer in Optimizers)
368        optimizer.Runs.RemoveRange(e.OldItems);
369    }
370    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
371      foreach (IOptimizer optimizer in Optimizers)
372        optimizer.Runs.RemoveRange(e.Items);
373    }
374    #endregion
375  }
376}
Note: See TracBrowser for help on using the repository browser.