Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 8155 was 8155, checked in by gkronber, 12 years ago

#1875 set the ExecutionState to stopped only after all results have been generated. This mitigates the problem of the race condition in CrossValidation even though the underlying problem is not actually solved.

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