Free cookie consent management tool by TermsFeed Policy Generator

source: branches/GeneralizedQAP/HeuristicLab.Optimization/3.3/Algorithms/EngineAlgorithm.cs @ 15605

Last change on this file since 15605 was 15605, checked in by abeham, 6 years ago

#1614: merged trunk into branch

File size: 8.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 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.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27using HeuristicLab.PluginInfrastructure;
28
29namespace HeuristicLab.Optimization {
30  /// <summary>
31  /// A base class for algorithms which use an engine for execution.
32  /// </summary>
33  [Item("EngineAlgorithm", "A base class for algorithms which use an engine for execution.")]
34  [StorableClass]
35  public abstract class EngineAlgorithm : Algorithm {
36    [Storable]
37    private OperatorGraph operatorGraph;
38    public OperatorGraph OperatorGraph {
39      get { return operatorGraph; }
40      protected set {
41        if (value == null) throw new ArgumentNullException();
42        if (value != operatorGraph) {
43          operatorGraph.InitialOperatorChanged -= new EventHandler(OperatorGraph_InitialOperatorChanged);
44          operatorGraph = value;
45          operatorGraph.InitialOperatorChanged += new EventHandler(OperatorGraph_InitialOperatorChanged);
46          OnOperatorGraphChanged();
47          Prepare();
48        }
49      }
50    }
51
52    [Storable]
53    private IScope globalScope;
54    protected IScope GlobalScope {
55      get { return globalScope; }
56    }
57
58    [Storable]
59    private IEngine engine;
60    public IEngine Engine {
61      get { return engine; }
62      set {
63        if (engine != value) {
64          if (engine != null) DeregisterEngineEvents();
65          engine = value;
66          if (engine != null) RegisterEngineEvents();
67          OnEngineChanged();
68          Prepare();
69        }
70      }
71    }
72
73    public override TimeSpan ExecutionTime {
74      get { return engine.ExecutionTime; }
75    }
76
77    public override ResultCollection Results {
78      get {
79        return (ResultCollection)globalScope.Variables["Results"].Value;
80      }
81    }
82
83    protected EngineAlgorithm()
84      : base() {
85      globalScope = new Scope("Global Scope");
86      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
87      operatorGraph = new OperatorGraph();
88      Initialize();
89    }
90    protected EngineAlgorithm(string name)
91      : base(name) {
92      globalScope = new Scope("Global Scope");
93      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
94      operatorGraph = new OperatorGraph();
95      Initialize();
96    }
97    protected EngineAlgorithm(string name, ParameterCollection parameters)
98      : base(name, parameters) {
99      globalScope = new Scope("Global Scope");
100      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
101      operatorGraph = new OperatorGraph();
102      Initialize();
103    }
104    protected EngineAlgorithm(string name, string description)
105      : base(name, description) {
106      globalScope = new Scope("Global Scope");
107      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
108      operatorGraph = new OperatorGraph();
109      Initialize();
110    }
111    protected EngineAlgorithm(string name, string description, ParameterCollection parameters)
112      : base(name, description, parameters) {
113      globalScope = new Scope("Global Scope");
114      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
115      operatorGraph = new OperatorGraph();
116      Initialize();
117    }
118    [StorableConstructor]
119    protected EngineAlgorithm(bool deserializing) : base(deserializing) { }
120    [StorableHook(HookType.AfterDeserialization)]
121    private void AfterDeserialization() {
122      Initialize();
123
124      // BackwardsCompatibility3.3
125      #region Backwards compatible code (remove with 3.4)
126      // clear global scope if it contains any sub-scopes or additional variables
127      if ((ExecutionState == Core.ExecutionState.Stopped) && ((globalScope.SubScopes.Count > 0) || (globalScope.Variables.Count > 1))) {
128        ResultCollection results = Results;
129        globalScope.Clear();
130        globalScope.Variables.Add(new Variable("Results", results));
131      }
132      #endregion
133    }
134
135    protected EngineAlgorithm(EngineAlgorithm original, Cloner cloner)
136      : base(original, cloner) {
137      globalScope = cloner.Clone(original.globalScope);
138      engine = cloner.Clone(original.engine);
139      operatorGraph = cloner.Clone(original.operatorGraph);
140      Initialize();
141    }
142
143    private void Initialize() {
144      operatorGraph.InitialOperatorChanged += new EventHandler(OperatorGraph_InitialOperatorChanged);
145      if (engine == null) {
146        var types = ApplicationManager.Manager.GetTypes(typeof(IEngine));
147        Type t = types.FirstOrDefault(x => x.Name.Equals("SequentialEngine"));
148        if (t == null) t = types.FirstOrDefault();
149        if (t != null) engine = (IEngine)Activator.CreateInstance(t);
150      }
151      if (engine != null) RegisterEngineEvents();
152    }
153
154    public virtual IAlgorithm CreateUserDefinedAlgorithm() {
155      return new UserDefinedAlgorithm(this, new Cloner());
156    }
157
158    public override void Prepare() {
159      base.Prepare();
160      globalScope.Clear();
161      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
162
163      if ((engine != null) && (operatorGraph.InitialOperator != null)) {
164        ExecutionContext context = null;
165        if (Problem != null) {
166          foreach (var item in Problem.ExecutionContextItems)
167            context = new ExecutionContext(context, item, globalScope);
168        }
169        context = new ExecutionContext(context, this, globalScope);
170        context = new ExecutionContext(context, operatorGraph.InitialOperator, globalScope);
171        engine.Prepare(context);
172      }
173    }
174    public override void Start(System.Threading.CancellationToken cancellationToken) {
175      base.Start(cancellationToken);
176      if (engine != null) engine.Start(cancellationToken);
177    }
178    public override void Pause() {
179      base.Pause();
180      if (engine != null) engine.Pause();
181    }
182    public override void Stop() {
183      base.Stop();
184      if (engine != null) engine.Stop();
185    }
186
187    #region Events
188    public event EventHandler EngineChanged;
189    protected virtual void OnEngineChanged() {
190      EventHandler handler = EngineChanged;
191      if (handler != null) handler(this, EventArgs.Empty);
192    }
193    public event EventHandler OperatorGraphChanged;
194    protected virtual void OnOperatorGraphChanged() {
195      EventHandler handler = OperatorGraphChanged;
196      if (handler != null) handler(this, EventArgs.Empty);
197    }
198
199    private void RegisterEngineEvents() {
200      Engine.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Engine_ExceptionOccurred);
201      Engine.Paused += new EventHandler(Engine_Paused);
202      Engine.Prepared += new EventHandler(Engine_Prepared);
203      Engine.Started += new EventHandler(Engine_Started);
204      Engine.Stopped += new EventHandler(Engine_Stopped);
205    }
206    private void DeregisterEngineEvents() {
207      Engine.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Engine_ExceptionOccurred);
208      Engine.Paused -= new EventHandler(Engine_Paused);
209      Engine.Prepared -= new EventHandler(Engine_Prepared);
210      Engine.Started -= new EventHandler(Engine_Started);
211      Engine.Stopped -= new EventHandler(Engine_Stopped);
212    }
213    private void Engine_ExceptionOccurred(object sender, EventArgs<Exception> e) {
214      OnExceptionOccurred(e.Value);
215    }
216    private void Engine_Paused(object sender, EventArgs e) {
217      OnPaused();
218    }
219    private void Engine_Prepared(object sender, EventArgs e) {
220      OnPrepared();
221    }
222    private void Engine_Started(object sender, EventArgs e) {
223      OnStarted();
224    }
225    private void Engine_Stopped(object sender, EventArgs e) {
226      ResultCollection results = Results;
227      globalScope.Clear();
228      globalScope.Variables.Add(new Variable("Results", results));
229      OnStopped();
230    }
231
232    private void OperatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
233      Prepare();
234    }
235    #endregion
236  }
237}
Note: See TracBrowser for help on using the repository browser.