Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OptimizationNetworks/HeuristicLab.Networks/3.3/AlgorithmNode.cs @ 14488

Last change on this file since 14488 was 13799, checked in by jkarder, 8 years ago

#2205: worked on optimization networks

  • improved network visualization
File size: 10.0 KB
RevLine 
[11406]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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
[13459]22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Threading;
[11406]26using HeuristicLab.Common;
27using HeuristicLab.Core;
[11526]28using HeuristicLab.Core.Networks;
[11554]29using HeuristicLab.Operators;
[11577]30using HeuristicLab.Optimization;
[11406]31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
[11577]33namespace HeuristicLab.Networks {
[11713]34  [Item("AlgorithmNode", "A node of a network which contains a HeuristicLab algorithm.")]
[11406]35  [StorableClass]
[11409]36  public class AlgorithmNode : Node, IAlgorithmNode {
[13459]37    protected object locker = new object();
[11519]38
[11409]39    new public PortCollection Ports {
40      get { return base.Ports; }
41    }
42
[11406]43    [Storable]
44    private IAlgorithm algorithm;
45    public IAlgorithm Algorithm {
46      get { return algorithm; }
47      set {
48        if (value != algorithm) {
49          algorithm = value;
50          OnAlgorithmChanged();
51        }
52      }
53    }
54
[11519]55    [Storable]
56    private RunCollection runs;
57    public RunCollection Runs {
58      get { return runs; }
59    }
60
[13799]61    [Storable]
62    private IItemCollection<IAlgorithm> startedAlgorithms;
63    public IItemCollection<IAlgorithm> StartedAlgorithms {
64      get { return startedAlgorithms; }
65    }
66
[11406]67    [StorableConstructor]
68    protected AlgorithmNode(bool deserializing) : base(deserializing) { }
69    protected AlgorithmNode(AlgorithmNode original, Cloner cloner)
70      : base(original, cloner) {
71      algorithm = cloner.Clone(original.algorithm);
[11519]72      runs = cloner.Clone(original.runs);
[13799]73      startedAlgorithms = cloner.Clone(original.startedAlgorithms);
74      RegisterStartedAlgorithmsEvents();
[11406]75    }
[11519]76    public AlgorithmNode()
77      : base("AlgorithmNode") {
78      runs = new RunCollection();
[13799]79      startedAlgorithms = new ItemCollection<IAlgorithm>();
80      RegisterStartedAlgorithmsEvents();
[11406]81    }
[13799]82
[11519]83    public AlgorithmNode(string name)
84      : base(name) {
85      runs = new RunCollection();
[13799]86      startedAlgorithms = new ItemCollection<IAlgorithm>();
87      RegisterStartedAlgorithmsEvents();
[11519]88    }
89    public AlgorithmNode(string name, string description)
90      : base(name, description) {
91      runs = new RunCollection();
[13799]92      startedAlgorithms = new ItemCollection<IAlgorithm>();
93      RegisterStartedAlgorithmsEvents();
[11519]94    }
[11406]95
96    public override IDeepCloneable Clone(Cloner cloner) {
97      return new AlgorithmNode(this, cloner);
98    }
99
[13799]100    [StorableHook(HookType.AfterDeserialization)]
101    private void AfterDeserialization() {
102      RegisterStartedAlgorithmsEvents();
103    }
104
105    protected virtual void RegisterStartedAlgorithmsEvents() {
106      startedAlgorithms.ItemsAdded += StartedAlgorithms_ItemsChanged;
107      startedAlgorithms.ItemsRemoved += StartedAlgorithms_ItemsChanged;
108    }
109
110    private void StartedAlgorithms_ItemsChanged(object sender, Collections.CollectionItemsChangedEventArgs<IAlgorithm> e) {
111      OnStartedAlgorithmsChanged();
112    }
113
[11519]114    protected virtual void Configure(IConfigurationPort port, IMessage message, CancellationToken token) {
115      // set algorithm and problem parameters
116      lock (locker) {
117        if (algorithm != null) {
118          foreach (var v in message.Values) {
119            IParameter param = null;
120            if (Algorithm.Parameters.TryGetValue(v.Name, out param)) {
121              var vp = param as IValueParameter;
122              if (vp != null) vp.Value = v.Value;
123            }
124            if (Algorithm.Problem.Parameters.TryGetValue(v.Name, out param)) {
125              var vp = param as IValueParameter;
126              if (vp != null) vp.Value = v.Value;
127            }
[11406]128          }
129        }
130      }
131    }
[11519]132
133    protected virtual void Execute(IExecutionPort port, IMessage message, CancellationToken token) {
134      if (Algorithm == null) throw new InvalidOperationException("Algorithm is null");
135
136      IAlgorithm algorithm;
137      lock (locker) {
[11554]138        // prevent cloning of ports in hook operators
139        var cloner = new Cloner();
140        foreach (var hook in Algorithm.GetObjectGraphObjects(new HashSet<object>() { Algorithm.Results, Algorithm.Runs }).OfType<IHookOperator>()) {
141          cloner.RegisterClonedObject(hook.Port, hook.Port);
142        }
143        algorithm = (IAlgorithm)Algorithm.Clone(cloner);
[11519]144      }
145
146      // set parameters
147      foreach (var v in message.Values) {
148        IParameter param = null;
149        if (algorithm.Parameters.TryGetValue(v.Name, out param)) {
150          var vp = param as IValueParameter;
151          if (vp != null) vp.Value = v.Value;
[11406]152        }
[11519]153        if (algorithm.Problem.Parameters.TryGetValue(v.Name, out param)) {
154          var vp = param as IValueParameter;
155          if (vp != null) vp.Value = v.Value;
156        }
[11406]157      }
[11519]158
[11682]159      token.ThrowIfCancellationRequested();
[11519]160
[11682]161      Exception exception = null;
162      using (var started = new AutoResetEvent(false))
163      using (var stopped = new AutoResetEvent(false))
164      using (var ctr = token.Register(() => {
165        started.WaitOne();
166        try { algorithm.Stop(); }
167        catch (InvalidOperationException) {
168          // NOTE:
169          // After the algorithm's engine is stopped, all stateful items in the algorithm are cleared before the execution state of the algorithm is set to stopped.
170          // When algorithm.Stop() is called during that operation, an InvalidOperationException is thrown because Stop is called on the engine but the engine is already stopped.
171          // This exception can be ignored, as the algorithm will stop immediately after the clearing of its stateful items is finished.
172        }
173      })) {
174        algorithm.StoreAlgorithmInEachRun = false;
175        algorithm.Prepare(true);
176        algorithm.ExceptionOccurred += (sender, args) => { exception = args.Value; };
[13799]177        algorithm.Started += (sender, args) => { started.Set(); startedAlgorithms.Add((IAlgorithm)sender); };
178        algorithm.Stopped += (sender, args) => { stopped.Set(); startedAlgorithms.Remove((IAlgorithm)sender); };
[11519]179        algorithm.Start();
[11682]180        stopped.WaitOne();
[11519]181      }
182
[11682]183      if (exception != null) throw exception;
184      token.ThrowIfCancellationRequested();
[11519]185
186      // retrieve results
187      var run = algorithm.Runs.First();
188      foreach (var v in message.Values) {
189        IItem result = null;
190        if (run.Results.TryGetValue(v.Name, out result)) {
191          v.Value = result;
192        }
193      }
194
195      lock (locker) {
196        Runs.Add(run);
197      }
[11409]198    }
[11406]199
200    public event EventHandler AlgorithmChanged;
201    protected virtual void OnAlgorithmChanged() {
202      var handler = AlgorithmChanged;
203      if (handler != null) handler(this, EventArgs.Empty);
204    }
205
[13799]206    public event EventHandler StartedAlgorithmsChanged;
207    protected virtual void OnStartedAlgorithmsChanged() {
208      var handler = StartedAlgorithmsChanged;
209      if (handler != null) handler(this, EventArgs.Empty);
210    }
211
[11406]212    #region Ports Events
[11423]213    protected override void RegisterPortsEvents() {
214      base.RegisterPortsEvents();
[11409]215      foreach (var p in Ports)
216        RegisterPortEvents(p);
[11406]217    }
[11423]218    protected override void Ports_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
219      base.Ports_ItemsAdded(sender, e);
[11406]220      foreach (var p in e.Items)
221        RegisterPortEvents(p);
222    }
[11423]223    protected override void Ports_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
224      base.Ports_ItemsRemoved(sender, e);
[11406]225      foreach (var p in e.Items)
226        DeregisterPortEvents(p);
227    }
[11423]228    protected override void Ports_ItemsReplaced(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
229      base.Ports_ItemsReplaced(sender, e);
[11406]230      foreach (var p in e.OldItems)
231        DeregisterPortEvents(p);
232      foreach (var p in e.Items)
233        RegisterPortEvents(p);
234    }
[11423]235    protected override void Ports_CollectionReset(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
236      base.Ports_CollectionReset(sender, e);
[11406]237      foreach (var p in e.OldItems)
238        DeregisterPortEvents(p);
239      foreach (var p in e.Items)
240        RegisterPortEvents(p);
241    }
242    #endregion
243
244    #region Port Events
245    private void RegisterPortEvents(IPort port) {
[11519]246      IConfigurationPort c = port as IConfigurationPort;
247      if (c != null) {
248        c.MessageReceived += ConfigurationPort_MessageReceived;
[11406]249      }
[11519]250      IExecutionPort e = port as IExecutionPort;
251      if (e != null) {
252        e.MessageReceived += ExecutionPort_MessageReceived;
[11409]253      }
[11406]254    }
255    private void DeregisterPortEvents(IPort port) {
[11519]256      IConfigurationPort c = port as IConfigurationPort;
257      if (c != null) {
258        c.MessageReceived -= ConfigurationPort_MessageReceived;
[11406]259      }
[11519]260      IExecutionPort e = port as IExecutionPort;
261      if (e != null) {
262        e.MessageReceived -= ExecutionPort_MessageReceived;
[11409]263      }
[11406]264    }
[11519]265    protected virtual void ConfigurationPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
266      Configure((IConfigurationPort)sender, e.Value, e.Value2);
[11409]267    }
[11519]268    protected virtual void ExecutionPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
269      Execute((IExecutionPort)sender, e.Value, e.Value2);
[11406]270    }
271    #endregion
272  }
273}
Note: See TracBrowser for help on using the repository browser.