#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Drawing; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Optimization { /// /// A base class for algorithms. /// [Item("Algorithm", "A base class for algorithms.")] [StorableClass] public abstract class Algorithm : ParameterizedNamedItem, IAlgorithm { public override Image ItemImage { get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event; } } [Storable] private ExecutionState executionState; public ExecutionState ExecutionState { get { return executionState; } private set { if (executionState != value) { executionState = value; OnExecutionStateChanged(); } } } [Storable] private TimeSpan executionTime; public TimeSpan ExecutionTime { get { return executionTime; } protected set { executionTime = value; OnExecutionTimeChanged(); } } public virtual Type ProblemType { get { return typeof(IProblem); } } [Storable] private IProblem problem; public IProblem Problem { get { return problem; } set { if (problem != value) { if ((value != null) && !ProblemType.IsInstanceOfType(value)) throw new ArgumentException("Invalid problem type."); if (problem != null) DeregisterProblemEvents(); problem = value; if (problem != null) RegisterProblemEvents(); OnProblemChanged(); Prepare(); } } } public abstract ResultCollection Results { get; } [Storable] protected int runsCounter; [Storable] private RunCollection runs; public RunCollection Runs { get { return runs; } } protected Algorithm() : base() { executionState = ExecutionState.Stopped; executionTime = TimeSpan.Zero; runsCounter = 0; runs = new RunCollection(); } protected Algorithm(string name) : base(name) { executionState = ExecutionState.Stopped; executionTime = TimeSpan.Zero; runsCounter = 0; runs = new RunCollection(); } protected Algorithm(string name, ParameterCollection parameters) : base(name, parameters) { executionState = ExecutionState.Stopped; executionTime = TimeSpan.Zero; runsCounter = 0; runs = new RunCollection(); } protected Algorithm(string name, string description) : base(name, description) { executionState = ExecutionState.Stopped; executionTime = TimeSpan.Zero; runsCounter = 0; runs = new RunCollection(); } protected Algorithm(string name, string description, ParameterCollection parameters) : base(name, description, parameters) { executionState = ExecutionState.Stopped; executionTime = TimeSpan.Zero; runsCounter = 0; runs = new RunCollection(); } internal Algorithm(Algorithm algorithm, Cloner cloner) : base(algorithm.Name, algorithm.Description, (ParameterCollection)cloner.Clone(algorithm.Parameters)) { executionState = algorithm.executionState; executionTime = algorithm.executionTime; problem = (IProblem)cloner.Clone(algorithm.problem); runsCounter = algorithm.runsCounter; runs = (RunCollection)cloner.Clone(algorithm.runs); Initialize(); } [StorableConstructor] protected Algorithm(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void Initialize() { if (problem != null) RegisterProblemEvents(); } public override IDeepCloneable Clone(Cloner cloner) { if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState)); Algorithm clone = (Algorithm)base.Clone(cloner); clone.executionState = executionState; clone.executionTime = executionTime; clone.problem = (IProblem)cloner.Clone(problem); clone.runsCounter = runsCounter; clone.runs = (RunCollection)cloner.Clone(runs); clone.Initialize(); return clone; } public virtual void Prepare() { if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped)) throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState)); } public void Prepare(bool clearRuns) { if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped)) throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState)); if (clearRuns) { runsCounter = 0; runs.Clear(); } Prepare(); } public virtual void Start() { if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused)) throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState)); } public virtual void Pause() { if (ExecutionState != ExecutionState.Started) throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState)); } public virtual void Stop() { if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused)) throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState)); } public override void CollectParameterValues(IDictionary values) { base.CollectParameterValues(values); Problem.CollectParameterValues(values); } public virtual void CollectResultValues(IDictionary values) { foreach (IResult result in Results) values.Add(result.Name, result.Value); } #region Events public event EventHandler ExecutionStateChanged; protected virtual void OnExecutionStateChanged() { EventHandler handler = ExecutionStateChanged; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler ExecutionTimeChanged; protected virtual void OnExecutionTimeChanged() { EventHandler handler = ExecutionTimeChanged; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler ProblemChanged; protected virtual void OnProblemChanged() { EventHandler handler = ProblemChanged; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler Prepared; protected virtual void OnPrepared() { ExecutionTime = TimeSpan.Zero; ExecutionState = ExecutionState.Prepared; EventHandler handler = Prepared; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler Started; protected virtual void OnStarted() { ExecutionState = ExecutionState.Started; EventHandler handler = Started; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler Paused; protected virtual void OnPaused() { ExecutionState = ExecutionState.Paused; EventHandler handler = Paused; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler Stopped; protected virtual void OnStopped() { ExecutionState = ExecutionState.Stopped; runsCounter++; runs.Add(new Run(string.Format("{0} Run {1} ({2})", Name, runsCounter, ExecutionTime), this)); EventHandler handler = Stopped; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler> ExceptionOccurred; protected virtual void OnExceptionOccurred(Exception exception) { EventHandler> handler = ExceptionOccurred; if (handler != null) handler(this, new EventArgs(exception)); } protected virtual void DeregisterProblemEvents() { problem.SolutionCreatorChanged -= new EventHandler(Problem_SolutionCreatorChanged); problem.EvaluatorChanged -= new EventHandler(Problem_EvaluatorChanged); problem.VisualizerChanged -= new EventHandler(Problem_VisualizerChanged); problem.OperatorsChanged -= new EventHandler(Problem_OperatorsChanged); } protected virtual void RegisterProblemEvents() { problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged); problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged); problem.VisualizerChanged += new EventHandler(Problem_VisualizerChanged); problem.OperatorsChanged += new EventHandler(Problem_OperatorsChanged); } protected virtual void Problem_SolutionCreatorChanged(object sender, EventArgs e) { } protected virtual void Problem_EvaluatorChanged(object sender, EventArgs e) { } protected virtual void Problem_VisualizerChanged(object sender, EventArgs e) { } protected virtual void Problem_OperatorsChanged(object sender, EventArgs e) { } #endregion } }