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

Last change on this file since 8738 was 8738, checked in by mkommend, 8 years ago

#1673: Added new property AlgorithmName to the RunCollection and synced the property with the name of the surrounding IOptimizer. The AlgorithmName is used by the RunCollectionViews as prefix for its caption if it was set.

File size: 13.4 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 { AlgorithmName = Name };
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 { AlgorithmName = Name };
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 { AlgorithmName = Name };
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 { AlgorithmName = Name };
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 { AlgorithmName = Name };
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    protected override void OnNameChanged() {
253      base.OnNameChanged();
254      Runs.AlgorithmName = Name;
255    }
256
257    public event EventHandler ExecutionStateChanged;
258    protected virtual void OnExecutionStateChanged() {
259      EventHandler handler = ExecutionStateChanged;
260      if (handler != null) handler(this, EventArgs.Empty);
261    }
262    public event EventHandler ExecutionTimeChanged;
263    protected virtual void OnExecutionTimeChanged() {
264      EventHandler handler = ExecutionTimeChanged;
265      if (handler != null) handler(this, EventArgs.Empty);
266    }
267    public event EventHandler ProblemChanged;
268    protected virtual void OnProblemChanged() {
269      EventHandler handler = ProblemChanged;
270      if (handler != null) handler(this, EventArgs.Empty);
271    }
272    public event EventHandler StoreAlgorithmInEachRunChanged;
273    protected virtual void OnStoreAlgorithmInEachRunChanged() {
274      EventHandler handler = StoreAlgorithmInEachRunChanged;
275      if (handler != null) handler(this, EventArgs.Empty);
276    }
277    public event EventHandler Prepared;
278    protected virtual void OnPrepared() {
279      ExecutionTime = TimeSpan.Zero;
280      foreach (IStatefulItem statefulObject in this.GetObjectGraphObjects(new HashSet<object>() { Runs }).OfType<IStatefulItem>()) {
281        statefulObject.InitializeState();
282      }
283      ExecutionState = ExecutionState.Prepared;
284      EventHandler handler = Prepared;
285      if (handler != null) handler(this, EventArgs.Empty);
286    }
287    public event EventHandler Started;
288    protected virtual void OnStarted() {
289      ExecutionState = ExecutionState.Started;
290      EventHandler handler = Started;
291      if (handler != null) handler(this, EventArgs.Empty);
292    }
293    public event EventHandler Paused;
294    protected virtual void OnPaused() {
295      ExecutionState = ExecutionState.Paused;
296      EventHandler handler = Paused;
297      if (handler != null) handler(this, EventArgs.Empty);
298    }
299    public event EventHandler Stopped;
300    protected virtual void OnStopped() {
301      foreach (IStatefulItem statefulObject in this.GetObjectGraphObjects(new HashSet<object>() { Runs }).OfType<IStatefulItem>()) {
302        statefulObject.ClearState();
303      }
304      runsCounter++;
305      runs.Add(new Run(string.Format("{0} Run {1}", Name, runsCounter), this));
306      ExecutionState = ExecutionState.Stopped;
307      EventHandler handler = Stopped;
308      if (handler != null) handler(this, EventArgs.Empty);
309    }
310    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
311    protected virtual void OnExceptionOccurred(Exception exception) {
312      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
313      if (handler != null) handler(this, new EventArgs<Exception>(exception));
314    }
315
316    protected virtual void DeregisterProblemEvents() {
317      problem.OperatorsChanged -= new EventHandler(Problem_OperatorsChanged);
318      problem.Reset -= new EventHandler(Problem_Reset);
319    }
320    protected virtual void RegisterProblemEvents() {
321      problem.OperatorsChanged += new EventHandler(Problem_OperatorsChanged);
322      problem.Reset += new EventHandler(Problem_Reset);
323    }
324    protected virtual void Problem_OperatorsChanged(object sender, EventArgs e) { }
325    protected virtual void Problem_Reset(object sender, EventArgs e) {
326      Prepare();
327    }
328
329    protected virtual void DeregisterRunsEvents() {
330      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
331    }
332    protected virtual void RegisterRunsEvents() {
333      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
334    }
335    protected virtual void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
336      runsCounter = runs.Count;
337    }
338    #endregion
339  }
340}
Note: See TracBrowser for help on using the repository browser.