Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization/3.3/Algorithms/Algorithm.cs @ 6103

Last change on this file since 6103 was 6103, checked in by cneumuel, 13 years ago

#1424

  • created extension method GetObjectGraphObjects for objects
  • created IStatefulItem interface, which means an object has a state which can be initialized and cleared
  • after an algorithm stopped, all objects of the algorithm-objectgraph with the type IStatefulItem are cleared
  • on prepare, all IStatefulItem objects are initialized
File size: 12.6 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.Data;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Optimization {
33  /// <summary>
34  /// A base class for algorithms.
35  /// </summary>
36  [Item("Algorithm", "A base class for algorithms.")]
37  [StorableClass]
38  public abstract class Algorithm : ParameterizedNamedItem, IAlgorithm {
39    public override Image ItemImage {
40      get {
41        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
42        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
43        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
44        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
45        else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
46      }
47    }
48
49    [Storable]
50    private ExecutionState executionState;
51    public ExecutionState ExecutionState {
52      get { return executionState; }
53      private set {
54        if (executionState != value) {
55          executionState = value;
56          OnExecutionStateChanged();
57          OnItemImageChanged();
58        }
59      }
60    }
61
62    [Storable]
63    private TimeSpan executionTime;
64    public TimeSpan ExecutionTime {
65      get { return executionTime; }
66      protected set {
67        executionTime = value;
68        OnExecutionTimeChanged();
69      }
70    }
71
72    public virtual Type ProblemType {
73      get { return typeof(IProblem); }
74    }
75
76    [Storable]
77    private IProblem problem;
78    public IProblem Problem {
79      get { return problem; }
80      set {
81        if (problem != value) {
82          if ((value != null) && !ProblemType.IsInstanceOfType(value)) throw new ArgumentException("Invalid problem type.");
83          if (problem != null) DeregisterProblemEvents();
84          problem = value;
85          if (problem != null) RegisterProblemEvents();
86          OnProblemChanged();
87          Prepare();
88        }
89      }
90    }
91
92    public abstract ResultCollection Results { get; }
93
94    [Storable]
95    private bool storeAlgorithmInEachRun;
96    public bool StoreAlgorithmInEachRun {
97      get { return storeAlgorithmInEachRun; }
98      set {
99        if (storeAlgorithmInEachRun != value) {
100          storeAlgorithmInEachRun = value;
101          OnStoreAlgorithmInEachRunChanged();
102        }
103      }
104    }
105
106    [Storable]
107    protected int runsCounter;
108
109    [Storable]
110    private RunCollection runs;
111    public RunCollection Runs {
112      get { return runs; }
113      protected set {
114        if (value == null) throw new ArgumentNullException();
115        if (runs != value) {
116          if (runs != null) DeregisterRunsEvents();
117          runs = value;
118          if (runs != null) RegisterRunsEvents();
119        }
120      }
121    }
122
123    public virtual IEnumerable<IOptimizer> NestedOptimizers {
124      get { return Enumerable.Empty<IOptimizer>(); }
125    }
126
127    protected Algorithm()
128      : base() {
129      executionState = ExecutionState.Stopped;
130      executionTime = TimeSpan.Zero;
131      storeAlgorithmInEachRun = false;
132      runsCounter = 0;
133      Runs = new RunCollection();
134    }
135    protected Algorithm(string name)
136      : base(name) {
137      executionState = ExecutionState.Stopped;
138      executionTime = TimeSpan.Zero;
139      storeAlgorithmInEachRun = false;
140      runsCounter = 0;
141      Runs = new RunCollection();
142    }
143    protected Algorithm(string name, ParameterCollection parameters)
144      : base(name, parameters) {
145      executionState = ExecutionState.Stopped;
146      executionTime = TimeSpan.Zero;
147      storeAlgorithmInEachRun = false;
148      runsCounter = 0;
149      Runs = new RunCollection();
150    }
151    protected Algorithm(string name, string description)
152      : base(name, description) {
153      executionState = ExecutionState.Stopped;
154      executionTime = TimeSpan.Zero;
155      storeAlgorithmInEachRun = false;
156      runsCounter = 0;
157      Runs = new RunCollection();
158    }
159    protected Algorithm(string name, string description, ParameterCollection parameters)
160      : base(name, description, parameters) {
161      executionState = ExecutionState.Stopped;
162      executionTime = TimeSpan.Zero;
163      storeAlgorithmInEachRun = false;
164      runsCounter = 0;
165      Runs = new RunCollection();
166    }
167    [StorableConstructor]
168    protected Algorithm(bool deserializing) : base(deserializing) { }
169    [StorableHook(HookType.AfterDeserialization)]
170    private void AfterDeserialization() {
171      Initialize();
172    }
173
174    protected Algorithm(Algorithm original, Cloner cloner)
175      : base(original, cloner) {
176      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
177      executionState = original.executionState;
178      executionTime = original.executionTime;
179      problem = cloner.Clone(original.problem);
180      storeAlgorithmInEachRun = original.storeAlgorithmInEachRun;
181      runsCounter = original.runsCounter;
182      runs = cloner.Clone(original.runs);
183      Initialize();
184    }
185
186    private void Initialize() {
187      if (problem != null) RegisterProblemEvents();
188      if (runs != null) RegisterRunsEvents();
189    }
190
191    public virtual void Prepare() {
192      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
193        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
194    }
195    public void Prepare(bool clearRuns) {
196      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
197        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
198      if (clearRuns) runs.Clear();
199      Prepare();
200    }
201    public virtual void Start() {
202      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
203        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
204    }
205    public virtual void Pause() {
206      if (ExecutionState != ExecutionState.Started)
207        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
208    }
209    public virtual void Stop() {
210      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
211        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
212    }
213
214    public override void CollectParameterValues(IDictionary<string, IItem> values) {
215      base.CollectParameterValues(values);
216      values.Add("Algorithm Name", new StringValue(Name));
217      values.Add("Algorithm Type", new StringValue(this.GetType().GetPrettyName()));
218      if (Problem != null) {
219        Problem.CollectParameterValues(values);
220        values.Add("Problem Name", new StringValue(Problem.Name));
221        values.Add("Problem Type", new StringValue(Problem.GetType().GetPrettyName()));
222      }
223    }
224    public virtual void CollectResultValues(IDictionary<string, IItem> values) {
225      values.Add("Execution Time", new TimeSpanValue(ExecutionTime));
226      CollectResultsRecursively("", Results, values);
227    }
228
229    private void CollectResultsRecursively(string path, ResultCollection results, IDictionary<string, IItem> values) {
230      foreach (IResult result in results) {
231        values.Add(path + result.Name, result.Value);
232        ResultCollection childCollection = result.Value as ResultCollection;
233        if (childCollection != null) {
234          CollectResultsRecursively(path + result.Name + ".", childCollection, values);
235        }
236      }
237    }
238
239    #region Events
240    public event EventHandler ExecutionStateChanged;
241    protected virtual void OnExecutionStateChanged() {
242      EventHandler handler = ExecutionStateChanged;
243      if (handler != null) handler(this, EventArgs.Empty);
244    }
245    public event EventHandler ExecutionTimeChanged;
246    protected virtual void OnExecutionTimeChanged() {
247      EventHandler handler = ExecutionTimeChanged;
248      if (handler != null) handler(this, EventArgs.Empty);
249    }
250    public event EventHandler ProblemChanged;
251    protected virtual void OnProblemChanged() {
252      EventHandler handler = ProblemChanged;
253      if (handler != null) handler(this, EventArgs.Empty);
254    }
255    public event EventHandler StoreAlgorithmInEachRunChanged;
256    protected virtual void OnStoreAlgorithmInEachRunChanged() {
257      EventHandler handler = StoreAlgorithmInEachRunChanged;
258      if (handler != null) handler(this, EventArgs.Empty);
259    }
260    public event EventHandler Prepared;
261    protected virtual void OnPrepared() {
262      ExecutionTime = TimeSpan.Zero;
263      foreach (IStatefulItem statefulObject in this.GetObjectGraphObjects().OfType<IStatefulItem>()) {
264        statefulObject.InitializeState();
265      }
266      ExecutionState = ExecutionState.Prepared;
267      EventHandler handler = Prepared;
268      if (handler != null) handler(this, EventArgs.Empty);
269    }
270    public event EventHandler Started;
271    protected virtual void OnStarted() {
272      ExecutionState = ExecutionState.Started;
273      EventHandler handler = Started;
274      if (handler != null) handler(this, EventArgs.Empty);
275    }
276    public event EventHandler Paused;
277    protected virtual void OnPaused() {
278      ExecutionState = ExecutionState.Paused;
279      EventHandler handler = Paused;
280      if (handler != null) handler(this, EventArgs.Empty);
281    }
282    public event EventHandler Stopped;
283    protected virtual void OnStopped() {
284      ExecutionState = ExecutionState.Stopped;
285      foreach (IStatefulItem statefulObject in this.GetObjectGraphObjects().OfType<IStatefulItem>()) {
286        statefulObject.ClearState();
287      }
288      runsCounter++;
289      runs.Add(new Run(string.Format("{0} Run {1}", Name, runsCounter), this));
290      EventHandler handler = Stopped;
291      if (handler != null) handler(this, EventArgs.Empty);
292    }
293    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
294    protected virtual void OnExceptionOccurred(Exception exception) {
295      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
296      if (handler != null) handler(this, new EventArgs<Exception>(exception));
297    }
298
299    protected virtual void DeregisterProblemEvents() {
300      problem.OperatorsChanged -= new EventHandler(Problem_OperatorsChanged);
301      problem.Reset -= new EventHandler(Problem_Reset);
302    }
303    protected virtual void RegisterProblemEvents() {
304      problem.OperatorsChanged += new EventHandler(Problem_OperatorsChanged);
305      problem.Reset += new EventHandler(Problem_Reset);
306    }
307    protected virtual void Problem_OperatorsChanged(object sender, EventArgs e) { }
308    protected virtual void Problem_Reset(object sender, EventArgs e) {
309      Prepare();
310    }
311
312    protected virtual void DeregisterRunsEvents() {
313      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
314    }
315    protected virtual void RegisterRunsEvents() {
316      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
317    }
318    protected virtual void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
319      runsCounter = runs.Count;
320    }
321    #endregion
322  }
323}
Note: See TracBrowser for help on using the repository browser.