source: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/SurrogateModelingOrchestrator.cs @ 15897

Last change on this file since 15897 was 15896, checked in by jkarder, 4 years ago

#2205: added surrogate modeling network

File size: 26.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Threading;
5using System.Threading.Tasks;
6using HeuristicLab.Common;
7using HeuristicLab.Core;
8using HeuristicLab.Core.Networks;
9using HeuristicLab.Data;
10using HeuristicLab.Encodings.RealVectorEncoding;
11using HeuristicLab.Optimization;
12using HeuristicLab.Parameters;
13using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
14using HeuristicLab.Problems.DataAnalysis;
15using HeuristicLab.Problems.TestFunctions;
16
17namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
18  [Item("Surrogate Modeling Orchestrator", "")]
19  [StorableClass]
20  public sealed class SurrogateModelingOrchestrator : OrchestratorNode {
21    private readonly object aoProblemSync = new object();
22    private readonly object mbProblemSync = new object();
23    private readonly object bestSolutionSync = new object();
24    private readonly ManualResetEventSlim mbSignal = new ManualResetEventSlim(false);
25    private readonly ManualResetEventSlim aoSignal = new ManualResetEventSlim(false);
26    private CancellationTokenSource cts;
27
28    [Storable]
29    public ExecutionState ExecutionState { get; set; }
30
31    [Storable]
32    public IRegressionProblem CurrentModelBuilderProblem { get; set; }
33    [Storable]
34    public AssistedOptimizerProblem CurrentAssistedOptimizerProblem { get; set; }
35    [Storable]
36    public IScope EstimatedBestSolution { get; set; }
37
38    #region Port Names
39    private const string FullEvaluatorOrchPortName = "Full Evaluator Orchestration";
40    private const string FullEvaluatorEvalPortName = "Full Evaluator Evaluation";
41    private const string FullEvaluatorExploitationEvalPortName = "Full Evaluator Exploitation";
42    private const string FullEvaluatorExplorationEvalPortName = "Full Evaluator Exploration";
43    private const string FullEvaluatorUpdatePortName = "Full Evaluator Update";
44    private const string PointGeneratorOrchPortName = "Point Generator Orchestration";
45    private const string PointGeneratorEvalPortName = "Point Generator Evaluation";
46    private const string ModelBuilderOrchPortName = "Model Builder Orchestration";
47    private const string ModelBuilderEvalPortName = "Model Builder Evaluation";
48    private const string ModelBuilderUpdatePortName = "Model Builder Update";
49    private const string AssistedOptimizerOrchPortName = "Assisted Optimizer Orchestration";
50    private const string AssistedOptimizerEvalPortName = "Assisted Optimizer Evaluation";
51    private const string AssistedOptimizerUpdatePortName = "Assisted Optimizer Update";
52    #endregion
53
54    #region Ports
55    public IMessagePort FullEvaluatorOrchPort { get { return (IMessagePort)Ports[FullEvaluatorOrchPortName]; } }
56    public IMessagePort FullEvaluatorEvalPort { get { return (IMessagePort)Ports[FullEvaluatorEvalPortName]; } }
57    public IMessagePort FullEvaluatorExploitationEvalPort { get { return (IMessagePort)Ports[FullEvaluatorExploitationEvalPortName]; } }
58    public IMessagePort FullEvaluatorExplorationEvalPort { get { return (IMessagePort)Ports[FullEvaluatorExplorationEvalPortName]; } }
59    public IMessagePort FullEvaluatorUpdatePort { get { return (IMessagePort)Ports[FullEvaluatorUpdatePortName]; } }
60    public IMessagePort PointGeneratorOrchPort { get { return (IMessagePort)Ports[PointGeneratorOrchPortName]; } }
61    public IMessagePort PointGeneratorEvalPort { get { return (IMessagePort)Ports[PointGeneratorEvalPortName]; } }
62    public IMessagePort ModelBuilderOrchPort { get { return (IMessagePort)Ports[ModelBuilderOrchPortName]; } }
63    public IMessagePort ModelBuilderEvalPort { get { return (IMessagePort)Ports[ModelBuilderEvalPortName]; } }
64    public IMessagePort ModelBuilderUpdatePort { get { return (IMessagePort)Ports[ModelBuilderUpdatePortName]; } }
65    public IMessagePort AssistedOptimizerOrchPort { get { return (IMessagePort)Ports[AssistedOptimizerOrchPortName]; } }
66    public IMessagePort AssistedOptimizerEvalPort { get { return (IMessagePort)Ports[AssistedOptimizerEvalPortName]; } }
67    public IMessagePort AssistedOptimizerUpdatePort { get { return (IMessagePort)Ports[AssistedOptimizerUpdatePortName]; } }
68    #endregion
69
70    #region Parameter Names
71    private const string TestFunctionProblemParameterName = "TestFunctionProblem";
72    private const string PointGeneratorProblemParameterName = "PointGeneratorProblem";
73    private const string ModelBuilderRegressionProblemParameterName = "ModelBuilderRegressionProblem";
74    private const string AssistedOptimizerProblemParameterName = "AssistedOptimizerProblem";
75    private const string MinPointsParameterName = "MinPoints";
76    private const string MaxPointsParameterName = "MaxPoints";
77    private const string MinModelQualityParameterName = "MinModelQuality";
78    #endregion
79
80    #region Parameters
81    private IValueParameter<SingleObjectiveTestFunctionProblem> TestFunctionProblemParameter {
82      get { return (IValueParameter<SingleObjectiveTestFunctionProblem>)Parameters[TestFunctionProblemParameterName]; }
83    }
84
85    private IValueParameter<PointGeneratorProblem> PointGeneratorProblemParameter {
86      get { return (IValueParameter<PointGeneratorProblem>)Parameters[PointGeneratorProblemParameterName]; }
87    }
88
89    private IValueParameter<IRegressionProblem> ModelBuilderRegressionProblemParameter {
90      get { return (IValueParameter<IRegressionProblem>)Parameters[ModelBuilderRegressionProblemParameterName]; }
91    }
92
93    private IValueParameter<AssistedOptimizerProblem> AssistedOptimizerProblemParameter {
94      get { return (IValueParameter<AssistedOptimizerProblem>)Parameters[AssistedOptimizerProblemParameterName]; }
95    }
96
97    private IValueParameter<IntValue> MinPointsParameter {
98      get { return (IValueParameter<IntValue>)Parameters[MinPointsParameterName]; }
99    }
100
101    private IValueParameter<IntValue> MaxPointsParameter {
102      get { return (IValueParameter<IntValue>)Parameters[MaxPointsParameterName]; }
103    }
104
105    private IValueParameter<DoubleValue> MinModelQualityParameter {
106      get { return (IValueParameter<DoubleValue>)Parameters[MinModelQualityParameterName]; }
107    }
108    #endregion
109
110    #region Parameter Properties
111    private SingleObjectiveTestFunctionProblem TestFunctionProblem {
112      get { return TestFunctionProblemParameter.Value; }
113      set { TestFunctionProblemParameter.Value = value; }
114    }
115
116    private PointGeneratorProblem PointGeneratorProblem {
117      get { return PointGeneratorProblemParameter.Value; }
118      set { PointGeneratorProblemParameter.Value = value; }
119    }
120
121    private IRegressionProblem ModelBuilderRegressionProblem {
122      get { return ModelBuilderRegressionProblemParameter.Value; }
123      set { ModelBuilderRegressionProblemParameter.Value = value; }
124    }
125
126    private AssistedOptimizerProblem AssistedOptimizerProblem {
127      get { return AssistedOptimizerProblemParameter.Value; }
128      set { AssistedOptimizerProblemParameter.Value = value; }
129    }
130
131    private IntValue MinPoints {
132      get { return MinPointsParameter.Value; }
133      set { MinPointsParameter.Value = value; }
134    }
135
136    private IntValue MaxPoints {
137      get { return MaxPointsParameter.Value; }
138      set { MaxPointsParameter.Value = value; }
139    }
140
141    private DoubleValue MinModelQuality {
142      get { return MinModelQualityParameter.Value; }
143      set { MinModelQualityParameter.Value = value; }
144    }
145    #endregion
146
147    #region Constructors & Cloning
148    [StorableConstructor]
149    private SurrogateModelingOrchestrator(bool deserializing) : base(deserializing) { }
150    private SurrogateModelingOrchestrator(SurrogateModelingOrchestrator original, Cloner cloner) : base(original, cloner) {
151      RegisterPortEvents();
152    }
153    public SurrogateModelingOrchestrator() : this("Surrogate Modeling Orchestrator") { }
154    public SurrogateModelingOrchestrator(string name) : this(name, "") { }
155    public SurrogateModelingOrchestrator(string name, string description) : base(name, description) {
156      AddParameters();
157
158      AddFullEvaluatorPorts();
159      AddPointGeneratorPorts();
160      AddModelBuilderPorts();
161      AddAssistedOptimizerPorts();
162
163      RegisterPortEvents();
164    }
165
166    public override IDeepCloneable Clone(Cloner cloner) {
167      return new SurrogateModelingOrchestrator(this, cloner);
168    }
169    #endregion
170
171    [StorableHook(HookType.AfterDeserialization)]
172    private void AfterDeserialization() {
173      RegisterPortEvents();
174    }
175
176    public override void Prepare(bool clearRuns = false) {
177      if (ExecutionState == ExecutionState.Started)
178        throw new InvalidOperationException("Prepare not allowed in execution state " + ExecutionState);
179
180      ExecutionState = ExecutionState.Prepared;
181      EstimatedBestSolution = null;
182      Results.Clear();
183
184      var orchMsg = OrchestrationMessage.Prepare;
185      if (clearRuns) orchMsg |= OrchestrationMessage.ClearRuns;
186
187      var tfProblem = (SingleObjectiveTestFunctionProblem)TestFunctionProblem.Clone();
188      var pgProblem = (PointGeneratorProblem)PointGeneratorProblem.Clone();
189      var mbProblem = (IRegressionProblem)ModelBuilderRegressionProblem.Clone();
190      var aoProblem = (AssistedOptimizerProblem)AssistedOptimizerProblem.Clone();
191
192      pgProblem.Encoding.Bounds = tfProblem.Bounds;
193      pgProblem.Encoding.Length = tfProblem.ProblemSize.Value;
194      pgProblem.NotifyEvaluation = (point, quality) => {
195        var evalPort = (IMessagePort)PointGeneratorOrchPort.ConnectedPort.Parent.Ports["EvaluationPort"];
196        var evalMsg = evalPort.PrepareMessage();
197        evalMsg["RealVector"] = point;
198        evalMsg["Quality"] = new DoubleValue(quality);
199        evalPort.SendMessage(evalMsg);
200      };
201
202      var fullEvaluatorNode = (FullEvaluatorNode)FullEvaluatorOrchPort.ConnectedPort.Parent;
203      fullEvaluatorNode.Algorithm.NotifyEvaluation = (point, quality) => {
204        var evalPort = (IMessagePort)fullEvaluatorNode.Ports["EvaluationPort"];
205        var evalMsg = evalPort.PrepareMessage();
206        evalMsg["RealVector"] = point;
207        evalMsg["Quality"] = new DoubleValue(quality);
208        evalPort.SendMessage(evalMsg);
209      };
210
211      var variableNames = Enumerable.Range(0, tfProblem.ProblemSize.Value).Select(x => x.ToString("X00#")).Concat(new[] { "TARGET" });
212      var variableValues = variableNames.Select(x => new List<double>());
213      var modifiableDataset = new ModifiableDataset(variableNames, variableValues);
214      mbProblem.ProblemData = new RegressionProblemData(modifiableDataset, variableNames.Except(new[] { "TARGET" }), variableNames.Last());
215
216      aoProblem.Encoding.Bounds = tfProblem.Bounds;
217      aoProblem.Encoding.Length = tfProblem.ProblemSize.Value;
218      aoProblem.NotifyEvaluation = (point, quality) => {
219        var evalPort = (IMessagePort)AssistedOptimizerOrchPort.ConnectedPort.Parent.Ports["EvaluationPort"];
220        var evalMsg = evalPort.PrepareMessage();
221        evalMsg["RealVector"] = point;
222        evalMsg["Quality"] = new DoubleValue(quality);
223        evalPort.SendMessage(evalMsg);
224      };
225
226      CurrentModelBuilderProblem = mbProblem;
227      CurrentAssistedOptimizerProblem = aoProblem;
228
229      var tasks = new[] {
230        SendOrchestrationMessageAsync(FullEvaluatorOrchPort, orchMsg, tfProblem),
231        SendOrchestrationMessageAsync(PointGeneratorOrchPort, orchMsg, pgProblem),
232        SendOrchestrationMessageAsync(ModelBuilderOrchPort, orchMsg, mbProblem),
233        SendOrchestrationMessageAsync(AssistedOptimizerOrchPort, orchMsg, aoProblem)
234      };
235
236      Task.WhenAll(tasks);
237    }
238
239    public override void Start() {
240      if (ExecutionState != ExecutionState.Prepared)
241        throw new InvalidOperationException("Start not allowed in execution state " + ExecutionState);
242
243      ExecutionState = ExecutionState.Started;
244
245      bool mbReady = CurrentModelBuilderProblem.ProblemData.Dataset.Rows >= MinPoints.Value;
246      if (mbReady) mbSignal.Set();
247      else mbSignal.Reset();
248
249      bool aoReady = CurrentAssistedOptimizerProblem.RegressionSolution != null;
250      if (aoReady) aoSignal.Set();
251      else aoSignal.Reset();
252
253      if (cts != null) {
254        cts.Cancel();
255        cts.Dispose();
256      }
257      cts = new CancellationTokenSource();
258
259      var tasks = new[] {
260        StartFullEvaluatorAsync(),
261        StartPointGeneratorMonitoringAsync(),
262        StartModelBuilderMonitoringAsync(),
263        StartAssistedOptimizerMonitoringAsync()
264      };
265
266      Task.WhenAll(tasks);
267    }
268
269    public override void Pause() {
270      if (ExecutionState != ExecutionState.Started)
271        throw new InvalidOperationException("Pause not allowed in execution state " + ExecutionState);
272
273      ExecutionState = ExecutionState.Paused;
274
275      cts.Cancel();
276
277      var tasks = new[] {
278        SendOrchestrationMessageAsync(PointGeneratorOrchPort, OrchestrationMessage.Pause),
279        SendOrchestrationMessageAsync(FullEvaluatorOrchPort, OrchestrationMessage.Pause),
280        SendOrchestrationMessageAsync(ModelBuilderOrchPort, OrchestrationMessage.Pause),
281        SendOrchestrationMessageAsync(AssistedOptimizerOrchPort, OrchestrationMessage.Pause)
282      };
283
284      Task.WhenAll(tasks);
285    }
286
287    public override void Stop() {
288      if (ExecutionState != ExecutionState.Started && ExecutionState != ExecutionState.Paused)
289        throw new InvalidOperationException("Stop not allowed in execution state " + ExecutionState);
290
291      ExecutionState = ExecutionState.Stopped;
292
293      cts.Cancel();
294
295      var tasks = new[] {
296        SendOrchestrationMessageAsync(PointGeneratorOrchPort, OrchestrationMessage.Stop),
297        SendOrchestrationMessageAsync(FullEvaluatorOrchPort, OrchestrationMessage.Stop),
298        SendOrchestrationMessageAsync(ModelBuilderOrchPort, OrchestrationMessage.Stop),
299        SendOrchestrationMessageAsync(AssistedOptimizerOrchPort, OrchestrationMessage.Stop)
300      };
301
302      Task.WhenAll(tasks);
303    }
304
305    #region Helpers
306    private void AddParameters() {
307      var tfProblem = new SingleObjectiveTestFunctionProblem();
308      var pgProblem = new PointGeneratorProblem();
309      var mbProblem = new RegressionProblem();
310      var aoProblem = new AssistedOptimizerProblem();
311
312      var variableNames = "DUMMY".ToEnumerable();
313      var variableValues = new List<double>().ToEnumerable();
314      var modifiableDataset = new ModifiableDataset(variableNames, variableValues);
315      mbProblem.ProblemData = new RegressionProblemData(modifiableDataset, variableNames, variableNames.Last());
316
317      Parameters.Add(new ValueParameter<SingleObjectiveTestFunctionProblem>(TestFunctionProblemParameterName, tfProblem));
318      Parameters.Add(new ValueParameter<PointGeneratorProblem>(PointGeneratorProblemParameterName, pgProblem));
319      Parameters.Add(new ValueParameter<IRegressionProblem>(ModelBuilderRegressionProblemParameterName, mbProblem));
320      Parameters.Add(new ValueParameter<AssistedOptimizerProblem>(AssistedOptimizerProblemParameterName, aoProblem));
321      Parameters.Add(new ValueParameter<IntValue>(MinPointsParameterName, new IntValue(1)));
322      Parameters.Add(new ValueParameter<IntValue>(MaxPointsParameterName, new IntValue(int.MaxValue)));
323      Parameters.Add(new ValueParameter<DoubleValue>(MinModelQualityParameterName, new DoubleValue(0.95)));
324    }
325
326    private void AddFullEvaluatorPorts() {
327      var orchPort = CreateOrchestrationPort<SingleObjectiveTestFunctionProblem>(FullEvaluatorOrchPortName);
328      Ports.Add(orchPort);
329
330      var evalPort = CreateEvaluationPort<RealVector>(FullEvaluatorEvalPortName, "RealVector", "Quality");
331      Ports.Add(evalPort);
332
333      var exploitationPort = CreateEvaluationPort<RealVector>(FullEvaluatorExploitationEvalPortName, "RealVector", "Quality");
334      Ports.Add(exploitationPort);
335
336      var explorationPort = CreateEvaluationPort<RealVector>(FullEvaluatorExplorationEvalPortName, "RealVector", "Quality");
337      Ports.Add(explorationPort);
338
339      var updatePort = new ConfigurationPort(FullEvaluatorUpdatePortName) {
340        Parameters = {
341          new PortParameter<IRegressionSolution>("RegressionSolution") {
342            Type = PortParameterType.Output
343          }
344        }
345      };
346      Ports.Add(updatePort);
347    }
348
349    private void AddPointGeneratorPorts() {
350      var orchPort = CreateOrchestrationPort<PointGeneratorProblem>(PointGeneratorOrchPortName);
351      Ports.Add(orchPort);
352
353      var evalPort = CreateEvaluationPort<RealVector>(PointGeneratorEvalPortName, "RealVector", "Quality");
354      Ports.Add(evalPort);
355    }
356
357    private void AddModelBuilderPorts() {
358      var orchPort = CreateOrchestrationPort<IRegressionProblem>(ModelBuilderOrchPortName);
359      Ports.Add(orchPort);
360
361      var evalPort = CreateEvaluationPort<IRegressionSolution>(ModelBuilderEvalPortName, "RegressionSolution", "Quality");
362      Ports.Add(evalPort);
363
364      var updatePort = new ConfigurationPort(ModelBuilderUpdatePortName) {
365        Parameters = {
366          new PortParameter<IRegressionProblemData>("ProblemData") {
367            Type = PortParameterType.Output
368          }
369        }
370      };
371      Ports.Add(updatePort);
372    }
373
374    private void AddAssistedOptimizerPorts() {
375      var orchPort = CreateOrchestrationPort<AssistedOptimizerProblem>(AssistedOptimizerOrchPortName);
376      Ports.Add(orchPort);
377
378      var evalPort = CreateEvaluationPort<RealVector>(AssistedOptimizerEvalPortName, "RealVector", "Quality");
379      Ports.Add(evalPort);
380
381      var updatePort = new ConfigurationPort(AssistedOptimizerUpdatePortName) {
382        Parameters = {
383          new PortParameter<IRegressionSolution>("RegressionSolution") {
384            Type = PortParameterType.Output
385          }
386        }
387      };
388      Ports.Add(updatePort);
389    }
390
391    private void RegisterPortEvents() {
392      PointGeneratorEvalPort.MessageReceived += PointGeneratorEvalPort_MessageReceived;
393      ModelBuilderEvalPort.MessageReceived += ModelBuilderEvalPort_MessageReceived;
394      AssistedOptimizerEvalPort.MessageReceived += AssistedOptimizerEvalPort_MessageReceived;
395      FullEvaluatorEvalPort.MessageReceived += FullEvaluatorEvalPort_MessageReceived;
396    }
397
398    private IMessage SendOrchestrationMessage(IMessagePort orchPort, OrchestrationMessage message, IProblem problem = null) {
399      var msg = orchPort.PrepareMessage();
400
401      msg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(message);
402      if (problem != null) msg["Problem"] = problem;
403
404      orchPort.SendMessage(msg);
405
406      return msg;
407    }
408
409    private async Task<IMessage> SendOrchestrationMessageAsync(IMessagePort orchPort, OrchestrationMessage message, IProblem problem = null) {
410      var msg = orchPort.PrepareMessage();
411
412      msg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(message);
413      if (problem != null) msg["Problem"] = problem;
414
415      await orchPort.SendMessageAsync(msg);
416
417      return msg;
418    }
419
420    private Task StartFullEvaluatorAsync() {
421      return SendOrchestrationMessageAsync(FullEvaluatorOrchPort, OrchestrationMessage.Start);
422    }
423
424    private Task StartPointGeneratorMonitoringAsync() {
425      return AsyncHelper.DoAsync(ct => {
426        var startOrchMsg = OrchestrationMessage.Start;
427        var prepareOrchMsg = OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns;
428
429        while (!ct.IsCancellationRequested) {
430          SendOrchestrationMessage(PointGeneratorOrchPort, prepareOrchMsg);
431          SendOrchestrationMessage(PointGeneratorOrchPort, startOrchMsg);
432        }
433      }, cts.Token);
434    }
435
436    private Task StartModelBuilderMonitoringAsync() {
437      return AsyncHelper.DoAsync(ct => {
438        IMessage message;
439        var startOrchMsg = OrchestrationMessage.Start;
440        var prepareOrchMsg = OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns;
441
442        mbSignal.Wait(cts.Token);
443
444        IRegressionProblem mbProblem;
445
446        while (!ct.IsCancellationRequested) {
447          lock (mbProblemSync) mbProblem = (IRegressionProblem)CurrentModelBuilderProblem.Clone();
448          SendOrchestrationMessage(ModelBuilderOrchPort, prepareOrchMsg, mbProblem);
449
450          message = SendOrchestrationMessage(ModelBuilderOrchPort, startOrchMsg);
451
452          var results = (ResultCollection)message["Results"];
453          var bestSolution = results.Select(x => x.Value).OfType<IRegressionSolution>().SingleOrDefault();
454          var clonedSolution = (IRegressionSolution)bestSolution.Clone();
455
456          var evalMsg = ModelBuilderEvalPort.PrepareMessage();
457          evalMsg["RegressionSolution"] = clonedSolution;
458          evalMsg["Quality"] = new DoubleValue(clonedSolution.TrainingRSquared);
459          ModelBuilderEvalPort.ReceiveMessage(evalMsg, ct);
460        }
461      }, cts.Token);
462    }
463
464    private Task StartAssistedOptimizerMonitoringAsync() {
465      return AsyncHelper.DoAsync(ct => {
466        IMessage message;
467        var prepareOrchMsg = OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns;
468        var startOrchMsg = OrchestrationMessage.Start;
469
470        aoSignal.Wait(cts.Token);
471
472        AssistedOptimizerProblem aoProblem;
473
474        while (!ct.IsCancellationRequested) {
475          lock (aoProblemSync) aoProblem = (AssistedOptimizerProblem)CurrentAssistedOptimizerProblem.Clone();
476          aoProblem.NotifyEvaluation = (point, quality) => {
477            var evalPort = (IMessagePort)AssistedOptimizerOrchPort.ConnectedPort.Parent.Ports["EvaluationPort"];
478            var msg = evalPort.PrepareMessage();
479            msg["RealVector"] = point;
480            msg["Quality"] = new DoubleValue(quality);
481            evalPort.SendMessage(msg);
482          };
483          SendOrchestrationMessage(AssistedOptimizerOrchPort, prepareOrchMsg, aoProblem);
484
485          message = SendOrchestrationMessage(AssistedOptimizerOrchPort, startOrchMsg);
486
487          var results = (ResultCollection)message["Results"];
488          var bestSolution = (RealVector)results["BestSolution"].Value.Clone();
489          var bestQuality = (DoubleValue)results["BestQuality"].Value.Clone();
490
491          var evalMsg = AssistedOptimizerEvalPort.PrepareMessage();
492          evalMsg["RealVector"] = bestSolution;
493          evalMsg["Quality"] = bestQuality;
494          AssistedOptimizerEvalPort.ReceiveMessage(evalMsg, ct);
495        }
496      }, cts.Token);
497    }
498
499    private void AddRowToDataset(IRegressionProblem problem, IEnumerable<object> row) {
500      var problemData = problem.ProblemData;
501      var dataset = problemData.Dataset;
502      var r = row.ToArray();
503
504      var modifiableDataset = dataset as ModifiableDataset ?? ((Dataset)dataset).ToModifiable();
505      if (modifiableDataset.Rows > MaxPoints.Value) {
506        var targetValues = modifiableDataset.GetDoubleValues(problemData.TargetVariable).ToList();
507        var maxTargetValue = targetValues.Max();
508        if (maxTargetValue > (double)r.Last()) {
509          int index = targetValues.IndexOf(maxTargetValue);
510          modifiableDataset.ReplaceRow(index, row);
511        }
512      } else modifiableDataset.AddRow(row);
513
514      problemData = new RegressionProblemData(modifiableDataset, problemData.AllowedInputVariables, problemData.TargetVariable);
515      problemData.TrainingPartition.End = modifiableDataset.Rows;
516      problemData.TestPartition.Start = modifiableDataset.Rows;
517
518      problem.ProblemData = problemData;
519    }
520
521
522    private static bool IsBetter(double oldValue, double newValue, bool maximization) {
523      return maximization ? newValue > oldValue : newValue < oldValue;
524    }
525    #endregion
526
527    #region Event Handlers
528    private void PointGeneratorEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
529      var evalMsg = e.Value;
530      // just forward message to full evaluator
531      FullEvaluatorExplorationEvalPort.SendMessage(evalMsg);
532    }
533
534    private void FullEvaluatorEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
535      var evalMsg = e.Value;
536      var realVector = (RealVector)evalMsg["RealVector"];
537      var quality = (DoubleValue)evalMsg["Quality"];
538
539      if (realVector.Length == 0 && double.IsNaN(quality.Value)) {
540        Stop();
541        return;
542      }
543
544      var sample = realVector.ToList();
545      sample.Add(quality.Value);
546      var row = sample.Select(x => (object)x).ToList();
547
548      lock (mbProblemSync) {
549        AddRowToDataset(CurrentModelBuilderProblem, row);
550        if (!mbSignal.IsSet && CurrentModelBuilderProblem.ProblemData.Dataset.Rows >= MinPoints.Value) mbSignal.Set();
551      }
552
553      //lock (aoProblemSync) {
554      //  if (CurrentAssistedOptimizerProblem.RegressionSolution != null)
555      //    CurrentAssistedOptimizerProblem.RegressionSolution.ProblemData = CurrentModelBuilderProblem.ProblemData;
556      //}
557    }
558
559    private void ModelBuilderEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
560      var evalMsg = e.Value;
561      var solution = (IRegressionSolution)evalMsg["RegressionSolution"];
562      var quality = (DoubleValue)evalMsg["Quality"];
563
564      if (solution.TrainingRSquared < MinModelQuality.Value) return;
565
566      lock (aoProblemSync) {
567        CurrentAssistedOptimizerProblem.RegressionSolution = solution;
568        if (!aoSignal.IsSet) aoSignal.Set();
569        else {
570          if (AssistedOptimizerUpdatePort.ConnectedPort != null) {
571            var updateMsg = AssistedOptimizerUpdatePort.PrepareMessage();
572            updateMsg["RegressionSolution"] = (IRegressionSolution)CurrentAssistedOptimizerProblem.RegressionSolution.Clone();
573            AssistedOptimizerUpdatePort.SendMessage(updateMsg);
574          }
575          if (FullEvaluatorUpdatePort.ConnectedPort != null) {
576            var updateMsg = FullEvaluatorUpdatePort.PrepareMessage();
577            updateMsg["RegressionSolution"] = (IRegressionSolution)CurrentAssistedOptimizerProblem.RegressionSolution.Clone();
578            FullEvaluatorUpdatePort.SendMessage(updateMsg);
579          }
580        }
581      }
582    }
583
584    private void AssistedOptimizerEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
585      var evalMsg = e.Value;
586      // just forward message to full evaluator
587      FullEvaluatorExploitationEvalPort.SendMessage(evalMsg);
588
589      var realVector = (RealVector)evalMsg["RealVector"];
590      var quality = (DoubleValue)evalMsg["Quality"];
591
592      lock (bestSolutionSync) {
593        if (EstimatedBestSolution == null) {
594          EstimatedBestSolution = new Scope("BestSolution") {
595            Variables = {
596              new Variable("RealVector", realVector),
597              new Variable("Quality", quality)
598            }
599          };
600        } else {
601          var oldRealVectorVariable = EstimatedBestSolution.Variables["RealVector"];
602          var oldQualityVariable = EstimatedBestSolution.Variables["Quality"];
603
604          var oldQuality = (DoubleValue)oldQualityVariable.Value;
605          if (IsBetter(oldQuality.Value, quality.Value, false)) {
606            oldRealVectorVariable.Value = realVector;
607            oldQualityVariable.Value = quality;
608          }
609        }
610      }
611    }
612    #endregion
613  }
614}
Note: See TracBrowser for help on using the repository browser.