Free cookie consent management tool by TermsFeed Policy Generator

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

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

Continued work on algorithm batch processing (#947).

File size: 11.7 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 batch runs of algorithms.
33  /// </summary>
34  [Item("Experiment", "An experiment which contains multiple batch runs of algorithms.")]
35  [Creatable("Testing & Analysis")]
36  [StorableClass]
37  public sealed class Experiment : NamedItem, IExecutable {
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
64    private BatchRunList batchRuns;
65    [Storable]
66    public BatchRunList BatchRuns {
67      get { return batchRuns; }
68      private set {
69        if (batchRuns != value) {
70          if (batchRuns != null) DeregisterBatchRunsEvents();
71          batchRuns = value;
72          if (batchRuns != null) RegisterBatchRunsEvents();
73          foreach (BatchRun batchRun in batchRuns)
74            RegisterBatchRunEvents(batchRun);
75        }
76      }
77    }
78
79    [Storable]
80    private RunCollection runs;
81    public RunCollection Runs {
82      get { return runs; }
83    }
84
85    private bool stopPending;
86
87    public Experiment()
88      : base() {
89      executionState = ExecutionState.Stopped;
90      executionTime = TimeSpan.Zero;
91      BatchRuns = new BatchRunList();
92      runs = new RunCollection();
93      stopPending = false;
94    }
95    public Experiment(string name) : base(name) {
96      executionState = ExecutionState.Stopped;
97      executionTime = TimeSpan.Zero;
98      BatchRuns = new BatchRunList();
99      runs = new RunCollection();
100      stopPending = false;
101    }
102    public Experiment(string name, string description) : base(name, description) {
103      executionState = ExecutionState.Stopped;
104      executionTime = TimeSpan.Zero;
105      BatchRuns = new BatchRunList();
106      runs = new RunCollection();
107      stopPending = false;
108    }
109
110    public override IDeepCloneable Clone(Cloner cloner) {
111      Experiment clone = (Experiment)base.Clone(cloner);
112      clone.executionState = executionState;
113      clone.executionTime = executionTime;
114      clone.BatchRuns = (BatchRunList)cloner.Clone(batchRuns);
115      clone.runs = (RunCollection)cloner.Clone(runs);
116      clone.stopPending = stopPending;
117      return clone;
118    }
119
120    public void Prepare() {
121      Prepare(true);
122    }
123    public void Prepare(bool clearRuns) {
124      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
125        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
126      if (BatchRuns.Count > 0) {
127        if (clearRuns) {
128          ExecutionTime = TimeSpan.Zero;
129          runs.Clear();
130        }
131        foreach (BatchRun batchRun in BatchRuns.Where(x => x.ExecutionState != ExecutionState.Started))
132          batchRun.Prepare(clearRuns);
133      }
134    }
135    public void Start() {
136      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
137        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
138      stopPending = false;
139      if (BatchRuns.Count > 0) {
140        BatchRun batchRun = BatchRuns.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
141        if (batchRun != null) batchRun.Start();
142      }
143    }
144    public void Pause() {
145      if (ExecutionState != ExecutionState.Started)
146        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
147      if (BatchRuns.Count > 0) {
148        foreach (BatchRun batchRun in BatchRuns.Where(x => x.ExecutionState == ExecutionState.Started))
149          batchRun.Pause();
150      }
151    }
152    public void Stop() {
153      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
154        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
155      stopPending = true;
156      if (BatchRuns.Count > 0) {
157        foreach (BatchRun batchRun in BatchRuns.Where(x => (x.ExecutionState == ExecutionState.Started) || (x.ExecutionState == ExecutionState.Paused)))
158          batchRun.Stop();
159      }
160    }
161
162    #region Events
163    public event EventHandler ExecutionStateChanged;
164    private void OnExecutionStateChanged() {
165      EventHandler handler = ExecutionStateChanged;
166      if (handler != null) handler(this, EventArgs.Empty);
167    }
168    public event EventHandler ExecutionTimeChanged;
169    private void OnExecutionTimeChanged() {
170      EventHandler handler = ExecutionTimeChanged;
171      if (handler != null) handler(this, EventArgs.Empty);
172    }
173    public event EventHandler Prepared;
174    private void OnPrepared() {
175      ExecutionState = ExecutionState.Prepared;
176      EventHandler handler = Prepared;
177      if (handler != null) handler(this, EventArgs.Empty);
178    }
179    public event EventHandler Started;
180    private void OnStarted() {
181      ExecutionState = ExecutionState.Started;
182      EventHandler handler = Started;
183      if (handler != null) handler(this, EventArgs.Empty);
184    }
185    public event EventHandler Paused;
186    private void OnPaused() {
187      ExecutionState = ExecutionState.Paused;
188      EventHandler handler = Paused;
189      if (handler != null) handler(this, EventArgs.Empty);
190    }
191    public event EventHandler Stopped;
192    private void OnStopped() {
193      ExecutionState = ExecutionState.Stopped;
194      EventHandler handler = Stopped;
195      if (handler != null) handler(this, EventArgs.Empty);
196    }
197    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
198    private void OnExceptionOccurred(Exception exception) {
199      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
200      if (handler != null) handler(this, new EventArgs<Exception>(exception));
201    }
202
203    private void RegisterBatchRunsEvents() {
204      BatchRuns.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_CollectionReset);
205      BatchRuns.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsAdded);
206      BatchRuns.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsRemoved);
207      BatchRuns.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsReplaced);
208    }
209    private void DeregisterBatchRunsEvents() {
210      BatchRuns.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_CollectionReset);
211      BatchRuns.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsAdded);
212      BatchRuns.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsRemoved);
213      BatchRuns.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsReplaced);
214    }
215    private void BatchRuns_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
216      foreach (IndexedItem<BatchRun> item in e.OldItems) {
217        DeregisterBatchRunEvents(item.Value);
218      }
219      foreach (IndexedItem<BatchRun> item in e.Items) {
220        RegisterBatchRunEvents(item.Value);
221      }
222    }
223    private void BatchRuns_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
224      foreach (IndexedItem<BatchRun> item in e.Items) {
225        RegisterBatchRunEvents(item.Value);
226      }
227    }
228    private void BatchRuns_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
229      foreach (IndexedItem<BatchRun> item in e.Items) {
230        DeregisterBatchRunEvents(item.Value);
231      }
232    }
233    private void BatchRuns_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
234      foreach (IndexedItem<BatchRun> item in e.OldItems) {
235        DeregisterBatchRunEvents(item.Value);
236      }
237      foreach (IndexedItem<BatchRun> item in e.Items) {
238        RegisterBatchRunEvents(item.Value);
239      }
240    }
241
242    private void RegisterBatchRunEvents(BatchRun batchRun) {
243      batchRun.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(batchRun_ExceptionOccurred);
244      batchRun.Paused += new EventHandler(batchRun_Paused);
245      batchRun.Prepared += new EventHandler(batchRun_Prepared);
246      batchRun.Started += new EventHandler(batchRun_Started);
247      batchRun.Stopped += new EventHandler(batchRun_Stopped);
248    }
249    private void DeregisterBatchRunEvents(BatchRun batchRun) {
250      batchRun.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(batchRun_ExceptionOccurred);
251      batchRun.Paused -= new EventHandler(batchRun_Paused);
252      batchRun.Prepared -= new EventHandler(batchRun_Prepared);
253      batchRun.Started -= new EventHandler(batchRun_Started);
254      batchRun.Stopped -= new EventHandler(batchRun_Stopped);
255    }
256    private void batchRun_ExceptionOccurred(object sender, EventArgs<Exception> e) {
257      OnExceptionOccurred(e.Value);
258    }
259    private void batchRun_Paused(object sender, EventArgs e) {
260      if (BatchRuns.All(x => x.ExecutionState != ExecutionState.Started))
261        OnPaused();
262    }
263    void batchRun_Prepared(object sender, EventArgs e) {
264      if (ExecutionState == ExecutionState.Stopped)
265        OnPrepared();
266    }
267    private void batchRun_Started(object sender, EventArgs e) {
268      if (ExecutionState != ExecutionState.Started)
269        OnStarted();
270    }
271    private void batchRun_Stopped(object sender, EventArgs e) {
272      bool stop = stopPending;
273      BatchRun batchRun = (BatchRun)sender;
274      ExecutionTime += batchRun.ExecutionTime;
275      runs.AddRange(batchRun.Runs);
276
277      if (BatchRuns.All(x => (x.ExecutionState != ExecutionState.Started) && (x.ExecutionState != ExecutionState.Paused))) {
278        stopPending = false;
279        OnStopped();
280      }
281
282      if (!stop) {
283        BatchRun next = BatchRuns.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
284        if (next != null)
285          next.Start();
286      }
287    }
288    #endregion
289  }
290}
Note: See TracBrowser for help on using the repository browser.