Enabled saving only for some specific items (#1193)
[heuristiclab.git] / HeuristicLab.Optimization / 3.3 / Algorithm.cs
blob09b82896f356647da166df6d934912deb25aea1b
1 #region License Information
2 /* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 * This file is part of HeuristicLab.
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.
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.
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/>.
20 #endregion
22 using System;
23 using System.Collections.Generic;
24 using System.Drawing;
25 using HeuristicLab.Collections;
26 using HeuristicLab.Common;
27 using HeuristicLab.Core;
28 using HeuristicLab.Data;
29 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31 namespace HeuristicLab.Optimization {
32 /// <summary>
33 /// A base class for algorithms.
34 /// </summary>
35 [Item("Algorithm", "A base class for algorithms.")]
36 [StorableClass]
37 public abstract class Algorithm : ParameterizedNamedItem, IAlgorithm, IStorableContent {
38 public string Filename { get; set; }
40 public override Image ItemImage {
41 get {
42 if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
43 else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStarted;
44 else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePaused;
45 else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
46 else return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event;
50 [Storable]
51 private ExecutionState executionState;
52 public ExecutionState ExecutionState {
53 get { return executionState; }
54 private set {
55 if (executionState != value) {
56 executionState = value;
57 OnExecutionStateChanged();
58 OnItemImageChanged();
63 [Storable]
64 private TimeSpan executionTime;
65 public TimeSpan ExecutionTime {
66 get { return executionTime; }
67 protected set {
68 executionTime = value;
69 OnExecutionTimeChanged();
73 public virtual Type ProblemType {
74 get { return typeof(IProblem); }
77 [Storable]
78 private IProblem problem;
79 public IProblem Problem {
80 get { return problem; }
81 set {
82 if (problem != value) {
83 if ((value != null) && !ProblemType.IsInstanceOfType(value)) throw new ArgumentException("Invalid problem type.");
84 if (problem != null) DeregisterProblemEvents();
85 problem = value;
86 if (problem != null) RegisterProblemEvents();
87 OnProblemChanged();
88 Prepare();
93 public abstract ResultCollection Results { get; }
95 [Storable]
96 private bool storeAlgorithmInEachRun;
97 public bool StoreAlgorithmInEachRun {
98 get { return storeAlgorithmInEachRun; }
99 set {
100 if (storeAlgorithmInEachRun != value) {
101 storeAlgorithmInEachRun = value;
102 OnStoreAlgorithmInEachRunChanged();
107 [Storable]
108 protected int runsCounter;
110 [Storable]
111 private RunCollection runs;
112 public RunCollection Runs {
113 get { return runs; }
114 protected set {
115 if (value == null) throw new ArgumentNullException();
116 if (runs != value) {
117 if (runs != null) DeregisterRunsEvents();
118 runs = value;
119 if (runs != null) RegisterRunsEvents();
124 protected Algorithm()
125 : base() {
126 executionState = ExecutionState.Stopped;
127 executionTime = TimeSpan.Zero;
128 storeAlgorithmInEachRun = true;
129 runsCounter = 0;
130 Runs = new RunCollection();
132 protected Algorithm(string name)
133 : base(name) {
134 executionState = ExecutionState.Stopped;
135 executionTime = TimeSpan.Zero;
136 storeAlgorithmInEachRun = true;
137 runsCounter = 0;
138 Runs = new RunCollection();
140 protected Algorithm(string name, ParameterCollection parameters)
141 : base(name, parameters) {
142 executionState = ExecutionState.Stopped;
143 executionTime = TimeSpan.Zero;
144 storeAlgorithmInEachRun = true;
145 runsCounter = 0;
146 Runs = new RunCollection();
148 protected Algorithm(string name, string description)
149 : base(name, description) {
150 executionState = ExecutionState.Stopped;
151 executionTime = TimeSpan.Zero;
152 storeAlgorithmInEachRun = true;
153 runsCounter = 0;
154 Runs = new RunCollection();
156 protected Algorithm(string name, string description, ParameterCollection parameters)
157 : base(name, description, parameters) {
158 executionState = ExecutionState.Stopped;
159 executionTime = TimeSpan.Zero;
160 storeAlgorithmInEachRun = true;
161 runsCounter = 0;
162 Runs = new RunCollection();
164 [StorableConstructor]
165 protected Algorithm(bool deserializing)
166 : base(deserializing) {
167 storeAlgorithmInEachRun = true;
170 [StorableHook(HookType.AfterDeserialization)]
171 private void Initialize() {
172 if (problem != null) RegisterProblemEvents();
173 if (runs != null) RegisterRunsEvents();
176 public override IDeepCloneable Clone(Cloner cloner) {
177 if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
178 Algorithm clone = (Algorithm)base.Clone(cloner);
179 clone.executionState = executionState;
180 clone.executionTime = executionTime;
181 clone.problem = (IProblem)cloner.Clone(problem);
182 clone.storeAlgorithmInEachRun = storeAlgorithmInEachRun;
183 clone.runsCounter = runsCounter;
184 clone.runs = (RunCollection)cloner.Clone(runs);
185 clone.Initialize();
186 return clone;
188 protected virtual void Clone(IDeepCloneable clone, Cloner cloner) {
189 Algorithm algorithm = clone as Algorithm;
190 if (algorithm != null) {
191 algorithm.name = name;
192 algorithm.description = description;
193 foreach (IParameter param in Parameters)
194 algorithm.Parameters.Add((IParameter)cloner.Clone(param));
195 algorithm.executionState = executionState;
196 algorithm.executionTime = executionTime;
197 algorithm.problem = (IProblem)cloner.Clone(problem);
198 algorithm.storeAlgorithmInEachRun = storeAlgorithmInEachRun;
199 algorithm.runsCounter = runsCounter;
200 algorithm.runs = (RunCollection)cloner.Clone(runs);
201 algorithm.Initialize();
205 public virtual void Prepare() {
206 if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
207 throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
209 public void Prepare(bool clearRuns) {
210 if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
211 throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
212 if (clearRuns) runs.Clear();
213 Prepare();
215 public virtual void Start() {
216 if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
217 throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
219 public virtual void Pause() {
220 if (ExecutionState != ExecutionState.Started)
221 throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
223 public virtual void Stop() {
224 if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
225 throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
228 public override void CollectParameterValues(IDictionary<string, IItem> values) {
229 base.CollectParameterValues(values);
230 values.Add("Algorithm Name", new StringValue(Name));
231 values.Add("Algorithm Type", new StringValue(this.GetType().GetPrettyName()));
232 if (Problem != null) {
233 Problem.CollectParameterValues(values);
234 values.Add("Problem Name", new StringValue(Problem.Name));
235 values.Add("Problem Type", new StringValue(Problem.GetType().GetPrettyName()));
238 public virtual void CollectResultValues(IDictionary<string, IItem> values) {
239 values.Add("Execution Time", new TimeSpanValue(ExecutionTime));
240 foreach (IResult result in Results)
241 values.Add(result.Name, result.Value);
244 #region Events
245 public event EventHandler ExecutionStateChanged;
246 protected virtual void OnExecutionStateChanged() {
247 EventHandler handler = ExecutionStateChanged;
248 if (handler != null) handler(this, EventArgs.Empty);
250 public event EventHandler ExecutionTimeChanged;
251 protected virtual void OnExecutionTimeChanged() {
252 EventHandler handler = ExecutionTimeChanged;
253 if (handler != null) handler(this, EventArgs.Empty);
255 public event EventHandler ProblemChanged;
256 protected virtual void OnProblemChanged() {
257 EventHandler handler = ProblemChanged;
258 if (handler != null) handler(this, EventArgs.Empty);
260 public event EventHandler StoreAlgorithmInEachRunChanged;
261 protected virtual void OnStoreAlgorithmInEachRunChanged() {
262 EventHandler handler = StoreAlgorithmInEachRunChanged;
263 if (handler != null) handler(this, EventArgs.Empty);
265 public event EventHandler Prepared;
266 protected virtual void OnPrepared() {
267 ExecutionTime = TimeSpan.Zero;
268 ExecutionState = ExecutionState.Prepared;
269 EventHandler handler = Prepared;
270 if (handler != null) handler(this, EventArgs.Empty);
272 public event EventHandler Started;
273 protected virtual void OnStarted() {
274 ExecutionState = ExecutionState.Started;
275 EventHandler handler = Started;
276 if (handler != null) handler(this, EventArgs.Empty);
278 public event EventHandler Paused;
279 protected virtual void OnPaused() {
280 ExecutionState = ExecutionState.Paused;
281 EventHandler handler = Paused;
282 if (handler != null) handler(this, EventArgs.Empty);
284 public event EventHandler Stopped;
285 protected virtual void OnStopped() {
286 ExecutionState = ExecutionState.Stopped;
287 runsCounter++;
288 runs.Add(new Run(string.Format("{0} Run {1}", Name, runsCounter), this));
289 EventHandler handler = Stopped;
290 if (handler != null) handler(this, EventArgs.Empty);
292 public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
293 protected virtual void OnExceptionOccurred(Exception exception) {
294 EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
295 if (handler != null) handler(this, new EventArgs<Exception>(exception));
298 protected virtual void DeregisterProblemEvents() {
299 problem.SolutionCreatorChanged -= new EventHandler(Problem_SolutionCreatorChanged);
300 problem.EvaluatorChanged -= new EventHandler(Problem_EvaluatorChanged);
301 problem.OperatorsChanged -= new EventHandler(Problem_OperatorsChanged);
302 problem.Reset -= new EventHandler(Problem_Reset);
304 protected virtual void RegisterProblemEvents() {
305 problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);
306 problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);
307 problem.OperatorsChanged += new EventHandler(Problem_OperatorsChanged);
308 problem.Reset += new EventHandler(Problem_Reset);
310 protected virtual void Problem_SolutionCreatorChanged(object sender, EventArgs e) { }
311 protected virtual void Problem_EvaluatorChanged(object sender, EventArgs e) { }
312 protected virtual void Problem_OperatorsChanged(object sender, EventArgs e) { }
313 protected virtual void Problem_Reset(object sender, EventArgs e) {
314 Prepare();
317 protected virtual void DeregisterRunsEvents() {
318 runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
320 protected virtual void RegisterRunsEvents() {
321 runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
323 protected virtual void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
324 runsCounter = runs.Count;
326 #endregion