Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2711: Added try/catch/finally blocks in the OnStopped method of algorithms to force the change of the execution state.

File size: 13.2 KB
RevLine 
[2851]1#region License Information
2/* HeuristicLab
[14185]3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[2851]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;
[3260]23using System.Collections.Generic;
[2851]24using System.Drawing;
[5419]25using System.Linq;
[3716]26using HeuristicLab.Collections;
[2851]27using HeuristicLab.Common;
28using HeuristicLab.Core;
[3694]29using HeuristicLab.Data;
[2851]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.")]
[3017]37  [StorableClass]
[4437]38  public abstract class Algorithm : ParameterizedNamedItem, IAlgorithm {
[7201]39    public static new Image StaticItemImage {
40      get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
41    }
[2851]42    public override Image ItemImage {
[3351]43      get {
[5287]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;
[7201]48        else return base.ItemImage;
[3351]49      }
[2851]50    }
51
[3262]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();
[3351]60          OnItemImageChanged();
[3262]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
[2852]75    public virtual Type ProblemType {
76      get { return typeof(IProblem); }
77    }
78
[3280]79    [Storable]
[2851]80    private IProblem problem;
81    public IProblem Problem {
82      get { return problem; }
83      set {
84        if (problem != value) {
[2852]85          if ((value != null) && !ProblemType.IsInstanceOfType(value)) throw new ArgumentException("Invalid problem type.");
86          if (problem != null) DeregisterProblemEvents();
[2851]87          problem = value;
[2852]88          if (problem != null) RegisterProblemEvents();
[2851]89          OnProblemChanged();
[2864]90          Prepare();
[2851]91        }
92      }
93    }
94
[3226]95    public abstract ResultCollection Results { get; }
[2882]96
[3275]97    [Storable]
[4102]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]
[3280]110    protected int runsCounter;
111
112    [Storable]
[3275]113    private RunCollection runs;
114    public RunCollection Runs {
115      get { return runs; }
[3716]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      }
[3275]124    }
125
[5419]126    public virtual IEnumerable<IOptimizer> NestedOptimizers {
127      get { return Enumerable.Empty<IOptimizer>(); }
128    }
129
[3262]130    protected Algorithm()
131      : base() {
132      executionState = ExecutionState.Stopped;
133      executionTime = TimeSpan.Zero;
[5203]134      storeAlgorithmInEachRun = false;
[3280]135      runsCounter = 0;
[8962]136      Runs = new RunCollection { OptimizerName = Name };
[2851]137    }
[3262]138    protected Algorithm(string name)
139      : base(name) {
140      executionState = ExecutionState.Stopped;
141      executionTime = TimeSpan.Zero;
[5203]142      storeAlgorithmInEachRun = false;
[3280]143      runsCounter = 0;
[8962]144      Runs = new RunCollection { OptimizerName = Name };
[2851]145    }
[3262]146    protected Algorithm(string name, ParameterCollection parameters)
147      : base(name, parameters) {
148      executionState = ExecutionState.Stopped;
149      executionTime = TimeSpan.Zero;
[5203]150      storeAlgorithmInEachRun = false;
[3280]151      runsCounter = 0;
[8962]152      Runs = new RunCollection { OptimizerName = Name };
[3262]153    }
154    protected Algorithm(string name, string description)
155      : base(name, description) {
156      executionState = ExecutionState.Stopped;
157      executionTime = TimeSpan.Zero;
[5203]158      storeAlgorithmInEachRun = false;
[3280]159      runsCounter = 0;
[8962]160      Runs = new RunCollection { OptimizerName = Name };
[3262]161    }
162    protected Algorithm(string name, string description, ParameterCollection parameters)
163      : base(name, description, parameters) {
164      executionState = ExecutionState.Stopped;
165      executionTime = TimeSpan.Zero;
[5203]166      storeAlgorithmInEachRun = false;
[3280]167      runsCounter = 0;
[8962]168      Runs = new RunCollection { OptimizerName = Name };
[3262]169    }
[3280]170    [StorableConstructor]
[5203]171    protected Algorithm(bool deserializing) : base(deserializing) { }
[3280]172    [StorableHook(HookType.AfterDeserialization)]
[4722]173    private void AfterDeserialization() {
174      Initialize();
[3280]175    }
176
[4722]177    protected Algorithm(Algorithm original, Cloner cloner)
178      : base(original, cloner) {
[3280]179      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
[4722]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();
[2851]187    }
[4722]188
189    private void Initialize() {
190      if (problem != null) RegisterProblemEvents();
191      if (runs != null) RegisterRunsEvents();
[3286]192    }
[2851]193
[3275]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));
[3274]197    }
[3275]198    public void Prepare(bool clearRuns) {
[3262]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));
[3716]201      if (clearRuns) runs.Clear();
[3275]202      Prepare();
[2851]203    }
[3262]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));
[2851]207    }
[3262]208    public virtual void Pause() {
209      if (ExecutionState != ExecutionState.Started)
210        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
[2851]211    }
[3262]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    }
[2851]216
[3260]217    public override void CollectParameterValues(IDictionary<string, IItem> values) {
218      base.CollectParameterValues(values);
[3785]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      }
[3260]226    }
227    public virtual void CollectResultValues(IDictionary<string, IItem> values) {
[3694]228      values.Add("Execution Time", new TimeSpanValue(ExecutionTime));
[11762]229      Results.CollectResultValues(values);
[3260]230    }
231
[7706]232    protected override IEnumerable<KeyValuePair<string, IItem>> GetCollectedValues(IValueParameter param) {
233      var children = base.GetCollectedValues(param);
[7579]234      foreach (var child in children) {
235        if (child.Value is IOperator)
236          yield return new KeyValuePair<string, IItem>(child.Key, new StringValue(((IOperator)child.Value).Name));
237        else yield return child;
238      }
239    }
240
[2851]241    #region Events
[8738]242    protected override void OnNameChanged() {
243      base.OnNameChanged();
[8962]244      Runs.OptimizerName = Name;
[8738]245    }
246
[3262]247    public event EventHandler ExecutionStateChanged;
248    protected virtual void OnExecutionStateChanged() {
249      EventHandler handler = ExecutionStateChanged;
250      if (handler != null) handler(this, EventArgs.Empty);
[2851]251    }
252    public event EventHandler ExecutionTimeChanged;
253    protected virtual void OnExecutionTimeChanged() {
[3262]254      EventHandler handler = ExecutionTimeChanged;
255      if (handler != null) handler(this, EventArgs.Empty);
[2851]256    }
[3262]257    public event EventHandler ProblemChanged;
258    protected virtual void OnProblemChanged() {
259      EventHandler handler = ProblemChanged;
260      if (handler != null) handler(this, EventArgs.Empty);
[3226]261    }
[4102]262    public event EventHandler StoreAlgorithmInEachRunChanged;
263    protected virtual void OnStoreAlgorithmInEachRunChanged() {
264      EventHandler handler = StoreAlgorithmInEachRunChanged;
265      if (handler != null) handler(this, EventArgs.Empty);
266    }
[2851]267    public event EventHandler Prepared;
268    protected virtual void OnPrepared() {
[3275]269      ExecutionTime = TimeSpan.Zero;
[8212]270      foreach (IStatefulItem statefulObject in this.GetObjectGraphObjects(new HashSet<object>() { Runs }).OfType<IStatefulItem>()) {
[6103]271        statefulObject.InitializeState();
272      }
[8155]273      ExecutionState = ExecutionState.Prepared;
[3262]274      EventHandler handler = Prepared;
275      if (handler != null) handler(this, EventArgs.Empty);
[2851]276    }
277    public event EventHandler Started;
278    protected virtual void OnStarted() {
[3262]279      ExecutionState = ExecutionState.Started;
280      EventHandler handler = Started;
281      if (handler != null) handler(this, EventArgs.Empty);
[2851]282    }
[3262]283    public event EventHandler Paused;
284    protected virtual void OnPaused() {
285      ExecutionState = ExecutionState.Paused;
286      EventHandler handler = Paused;
287      if (handler != null) handler(this, EventArgs.Empty);
288    }
[2851]289    public event EventHandler Stopped;
290    protected virtual void OnStopped() {
[14433]291      try {
292        foreach (
293          IStatefulItem statefulObject in
294          this.GetObjectGraphObjects(new HashSet<object>() {Runs}).OfType<IStatefulItem>()) {
295          statefulObject.ClearState();
296        }
297        runsCounter++;
298        try {
299          runs.Add(new Run(string.Format("{0} Run {1}", Name, runsCounter), this));
300        }
301        catch (ArgumentException e) {
302          OnExceptionOccurred(new InvalidOperationException("Run creation failed.", e));
303        }
304      }   
305      finally {
306        ExecutionState = ExecutionState.Stopped;
307        EventHandler handler = Stopped;
308        if (handler != null) handler(this, EventArgs.Empty);
[6103]309      }
[2851]310    }
311    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
312    protected virtual void OnExceptionOccurred(Exception exception) {
[3262]313      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
314      if (handler != null) handler(this, new EventArgs<Exception>(exception));
[2851]315    }
[2975]316
[2852]317    protected virtual void DeregisterProblemEvents() {
[2975]318      problem.OperatorsChanged -= new EventHandler(Problem_OperatorsChanged);
[3739]319      problem.Reset -= new EventHandler(Problem_Reset);
[2852]320    }
321    protected virtual void RegisterProblemEvents() {
[2975]322      problem.OperatorsChanged += new EventHandler(Problem_OperatorsChanged);
[3739]323      problem.Reset += new EventHandler(Problem_Reset);
[2852]324    }
[2975]325    protected virtual void Problem_OperatorsChanged(object sender, EventArgs e) { }
[3739]326    protected virtual void Problem_Reset(object sender, EventArgs e) {
327      Prepare();
328    }
[3716]329
330    protected virtual void DeregisterRunsEvents() {
331      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
332    }
333    protected virtual void RegisterRunsEvents() {
334      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
335    }
336    protected virtual void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
337      runsCounter = runs.Count;
338    }
[2851]339    #endregion
340  }
341}
Note: See TracBrowser for help on using the repository browser.