Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Optimizers/IRRestarter.cs @ 12813

Last change on this file since 12813 was 12813, checked in by abeham, 9 years ago

#2431:

  • Added calculation of RTs, RTus, FEs, FEus and prune runs in alg before every restart
  • merged changes from trunk
File size: 27.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using HeuristicLab.Common;
28using HeuristicLab.Common.Resources;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HeuristicLab.Optimization;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33
34namespace HeuristicLab.Analysis {
35  public enum TerminationCriterium { OnlyByTime, OnlyByEvaluations, OnlyByTarget, ByTargetAndTime, ByTargetAndEvaluations, ByTimeAndEvaluations, WhicheverHitsFirst, WhicheverHitsLast }
36  /// <summary>
37  /// A run in which an algorithm is executed for a certain maximum time only.
38  /// </summary>
39  [Item("Independent Random Restarter", "An optimizer that repeats an algorithm until either a certain target value is reached or a maximum budget is exceeded.")]
40  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 117)]
41  [StorableClass]
42  public sealed class IndepdentRandomRestarter : NamedItem, IOptimizer, IStorableContent, INotifyPropertyChanged {
43    private const string ExecutionTimeResultName = "Execution Time";
44    private const string BestQualityResultName = "BestQuality";
45    private const string RandomRestartsResultName = "RandomRestarts";
46    private const string RTsResultName = "RTs";
47    private const string RTusResultName = "RTus";
48    private const string FEsResultName = "FEs";
49    private const string FEusResultName = "FEus";
50
51    public string Filename { get; set; }
52
53    #region ItemImage
54    public static new Image StaticItemImage {
55      get { return VSImageLibrary.Event; }
56    }
57    public override Image ItemImage {
58      get { return (Algorithm != null) ? Algorithm.ItemImage : VSImageLibrary.ExecutableStopped; }
59    }
60    #endregion
61
62    [Storable]
63    private TerminationCriterium terminationCriterium;
64    public TerminationCriterium TerminationCriterium {
65      get { return terminationCriterium; }
66      set {
67        if (terminationCriterium == value) return;
68        terminationCriterium = value;
69        OnPropertyChanged("TerminationCriterium");
70      }
71    }
72
73    [Storable]
74    private TimeSpan maximumExecutionTime;
75    public TimeSpan MaximumExecutionTime {
76      get { return maximumExecutionTime; }
77      set {
78        if (maximumExecutionTime == value) return;
79        maximumExecutionTime = value;
80        OnPropertyChanged("MaximumExecutionTime");
81      }
82    }
83
84    [Storable]
85    private int maximumEvaluations;
86    public int MaximumEvaluations {
87      get { return maximumEvaluations; }
88      set {
89        if (maximumEvaluations == value) return;
90        maximumEvaluations = value;
91        OnPropertyChanged("MaximumEvaluations");
92      }
93    }
94
95    [Storable]
96    private double targetValue;
97    public double TargetValue {
98      get { return targetValue; }
99      set {
100        if (targetValue == value) return;
101        targetValue = value;
102        OnPropertyChanged("TargetValue");
103      }
104    }
105
106    [Storable]
107    private bool maximization;
108    public bool Maximization {
109      get { return maximization; }
110      set {
111        if (maximization == value) return;
112        maximization = value;
113        OnPropertyChanged("Maximization");
114      }
115    }
116
117    [Storable]
118    private double moveCostPerSolution;
119    public double MoveCostPerSolution {
120      get { return moveCostPerSolution; }
121      set {
122        if (moveCostPerSolution == value) return;
123        moveCostPerSolution = value;
124        perEvaluationsAnalyzer.MoveCostPerSolutionParameter.Value = new DoubleValue(moveCostPerSolution);
125        OnPropertyChanged("MoveCostPerSolution");
126      }
127    }
128
129    [Storable]
130    private QualityPerClockAnalyzer perClockAnalyzer;
131    [Storable]
132    private QualityPerEvaluationsAnalyzer perEvaluationsAnalyzer;
133
134    [Storable]
135    private ExecutionState executionState;
136    public ExecutionState ExecutionState {
137      get { return executionState; }
138      private set {
139        if (executionState != value) {
140          executionState = value;
141          OnExecutionStateChanged();
142          OnItemImageChanged();
143        }
144      }
145    }
146
147    private TimeSpan lastAlgorithmExecutionTime;
148    [Storable]
149    private TimeSpan executionTime;
150    public TimeSpan ExecutionTime {
151      get { return executionTime; }
152      set {
153        if (executionTime == value) return;
154        executionTime = value;
155        OnPropertyChanged("ExecutionTime");
156        OnExecutionTimeChanged();
157      }
158    }
159
160    [Storable]
161    private double evaluations;
162    public double Evaluations {
163      get { return evaluations; }
164      set {
165        if (evaluations == value) return;
166        evaluations = value;
167        OnPropertyChanged("Evaluations");
168      }
169    }
170
171    [Storable]
172    private double bestSoFar;
173    public double BestSoFar {
174      get { return bestSoFar; }
175      set {
176        if (bestSoFar == value) return;
177        bestSoFar = value;
178        OnPropertyChanged("BestSoFar");
179      }
180    }
181
182    [Storable]
183    private IRun currentRun;
184    public IRun CurrentRun {
185      get { return currentRun; }
186      private set {
187        if (currentRun == value) return;
188        currentRun = value;
189        OnPropertyChanged("CurrentRun");
190      }
191    }
192
193    [Storable]
194    private IAlgorithm algorithm;
195    public IAlgorithm Algorithm {
196      get { return algorithm; }
197      set {
198        if (value != null && !value.ProblemType.IsAssignableFrom(typeof(ISingleObjectiveHeuristicOptimizationProblem)))
199          throw new ArgumentException("Algorithm is not single-objective!");
200        if (algorithm == value) return;
201        if (algorithm != null) {
202          DeregisterAlgorithmEvents();
203          RemoveAlgorithmAnalyzers();
204        }
205        algorithm = value;
206        if (algorithm != null) {
207          RegisterAlgorithmEvents();
208          AddAlgorithmAnalyzers();
209        }
210        OnPropertyChanged("Algorithm");
211        Prepare();
212      }
213    }
214
215    [Storable]
216    private RunCollection runs;
217    public RunCollection Runs {
218      get { return runs; }
219      private set {
220        if (value == null) throw new ArgumentNullException();
221        if (runs == value) return;
222        runs = value;
223        OnPropertyChanged("Runs");
224      }
225    }
226
227    public IEnumerable<IOptimizer> NestedOptimizers {
228      get {
229        if (Algorithm == null) yield break;
230        yield return Algorithm;
231        foreach (var opt in Algorithm.NestedOptimizers)
232          yield return opt;
233      }
234    }
235
236    private bool IsFinished {
237      get {
238        var timeHit = ExecutionTime >= MaximumExecutionTime;
239        var evalHit = Evaluations >= MaximumEvaluations;
240        var targetHit = (Maximization && BestSoFar >= TargetValue || !Maximization && BestSoFar <= TargetValue);
241
242        return timeHit && evalHit && targetHit
243          || timeHit && (TerminationCriterium == TerminationCriterium.OnlyByTime
244                      || TerminationCriterium == TerminationCriterium.WhicheverHitsFirst
245                      || TerminationCriterium == TerminationCriterium.ByTargetAndTime
246                      || TerminationCriterium == TerminationCriterium.ByTimeAndEvaluations)
247          || evalHit && (TerminationCriterium == TerminationCriterium.OnlyByEvaluations
248                      || TerminationCriterium == TerminationCriterium.WhicheverHitsFirst
249                      || TerminationCriterium == TerminationCriterium.ByTargetAndEvaluations
250                      || TerminationCriterium == TerminationCriterium.ByTimeAndEvaluations)
251          || targetHit && (TerminationCriterium == TerminationCriterium.OnlyByTarget
252                        || TerminationCriterium == TerminationCriterium.WhicheverHitsFirst
253                        || TerminationCriterium == TerminationCriterium.ByTargetAndTime
254                        || TerminationCriterium == TerminationCriterium.ByTargetAndEvaluations);
255      }
256    }
257
258    private ISingleObjectiveHeuristicOptimizationProblem problem;
259
260    [StorableConstructor]
261    private IndepdentRandomRestarter(bool deserializing) : base(deserializing) { }
262    private IndepdentRandomRestarter(IndepdentRandomRestarter original, Cloner cloner)
263      : base(original, cloner) {
264      terminationCriterium = original.terminationCriterium;
265      maximumExecutionTime = original.maximumExecutionTime;
266      maximumEvaluations = original.maximumEvaluations;
267      moveCostPerSolution = original.moveCostPerSolution;
268      targetValue = original.targetValue;
269      maximization = original.maximization;
270      executionTime = original.executionTime;
271      evaluations = original.evaluations;
272      bestSoFar = original.bestSoFar;
273      lastAlgorithmExecutionTime = original.lastAlgorithmExecutionTime;
274
275      perClockAnalyzer = cloner.Clone(original.perClockAnalyzer);
276      perEvaluationsAnalyzer = cloner.Clone(original.perEvaluationsAnalyzer);
277
278      algorithm = cloner.Clone(original.algorithm);
279      runs = cloner.Clone(original.runs);
280
281      ExecutionState = original.ExecutionState;
282
283      Initialize();
284    }
285    public IndepdentRandomRestarter()
286      : base() {
287      name = ItemName;
288      description = ItemDescription;
289      terminationCriterium = TerminationCriterium.ByTargetAndEvaluations;
290      maximumExecutionTime = TimeSpan.FromMinutes(1);
291      maximumEvaluations = 10000000; // 10 mio
292      moveCostPerSolution = 1;
293      targetValue = 0;
294      maximization = false;
295      executionTime = TimeSpan.Zero;
296      evaluations = 0;
297      bestSoFar = double.NaN;
298      lastAlgorithmExecutionTime = TimeSpan.Zero;
299
300      perClockAnalyzer = new QualityPerClockAnalyzer();
301      perEvaluationsAnalyzer = new QualityPerEvaluationsAnalyzer();
302
303      Runs = new RunCollection { OptimizerName = Name };
304      Initialize();
305    }
306    public IndepdentRandomRestarter(string name)
307      : base(name) {
308      description = ItemDescription;
309      terminationCriterium = TerminationCriterium.ByTargetAndEvaluations;
310      maximumExecutionTime = TimeSpan.FromMinutes(1);
311      maximumEvaluations = 10000000; // 10 mio
312      moveCostPerSolution = 1;
313      targetValue = 0;
314      maximization = false;
315      executionTime = TimeSpan.Zero;
316      evaluations = 0;
317      bestSoFar = double.NaN;
318      lastAlgorithmExecutionTime = TimeSpan.Zero;
319
320      perClockAnalyzer = new QualityPerClockAnalyzer();
321      perEvaluationsAnalyzer = new QualityPerEvaluationsAnalyzer();
322
323      Runs = new RunCollection { OptimizerName = Name };
324      Initialize();
325    }
326    public IndepdentRandomRestarter(string name, string description)
327      : base(name, description) {
328      terminationCriterium = TerminationCriterium.ByTargetAndEvaluations;
329      maximumExecutionTime = TimeSpan.FromMinutes(1);
330      maximumEvaluations = 10000000; // 10 mio
331      moveCostPerSolution = 1;
332      targetValue = 0;
333      maximization = false;
334      executionTime = TimeSpan.Zero;
335      evaluations = 0;
336      bestSoFar = double.NaN;
337      lastAlgorithmExecutionTime = TimeSpan.Zero;
338
339      perClockAnalyzer = new QualityPerClockAnalyzer();
340      perEvaluationsAnalyzer = new QualityPerEvaluationsAnalyzer();
341
342      Runs = new RunCollection { OptimizerName = Name };
343      Initialize();
344    }
345
346    public override IDeepCloneable Clone(Cloner cloner) {
347      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
348      return new IndepdentRandomRestarter(this, cloner);
349    }
350
351    [StorableHook(HookType.AfterDeserialization)]
352    private void AfterDeserialization() {
353      Initialize();
354    }
355
356    private void Initialize() {
357      if (algorithm != null) RegisterAlgorithmEvents();
358    }
359
360    private void Reset() {
361      ExecutionTime = TimeSpan.Zero;
362      Evaluations = 0;
363      BestSoFar = double.NaN;
364      lastAlgorithmExecutionTime = TimeSpan.Zero;
365
366      CurrentRun = null;
367    }
368
369    public void Prepare() {
370      Prepare(false);
371    }
372    public void Prepare(bool clearRuns) {
373      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
374        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
375      Reset();
376
377      if (Algorithm != null) {
378        Algorithm.Prepare(clearRuns);
379        ExecutionState = ExecutionState.Prepared;
380        OnPrepared();
381      }
382    }
383    public void Start() {
384      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
385        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
386
387      if (ExecutionState == ExecutionState.Prepared) {
388        CurrentRun = new Run(Algorithm) {
389          Name = Algorithm.Name + " IRRRun" + Runs.Count
390        };
391        if (!CurrentRun.Results.ContainsKey(ExecutionTimeResultName))
392          CurrentRun.Results.Add(ExecutionTimeResultName, new TimeSpanValue(TimeSpan.Zero));
393        CurrentRun.Results.Add(perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName, new IntValue(0));
394        CurrentRun.Results.Add(perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName, new IntValue(0));
395        CurrentRun.Results.Add(BestQualityResultName, new DoubleValue(Maximization ? double.MinValue : double.MaxValue));
396        CurrentRun.Results.Add(RandomRestartsResultName, new IntValue(0));
397        CurrentRun.Results.Add(RTsResultName, new DoubleValue(0));
398        CurrentRun.Results.Add(RTusResultName, new DoubleValue(0));
399        CurrentRun.Results.Add(FEsResultName, new DoubleValue(0));
400        CurrentRun.Results.Add(FEusResultName, new DoubleValue(0));
401      }
402      Algorithm.Start();
403      ExecutionState = ExecutionState.Started;
404      OnStarted();
405    }
406    public void Pause() {
407      if (ExecutionState != ExecutionState.Started)
408        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
409      Algorithm.Pause();
410      ExecutionState = ExecutionState.Paused;
411      OnPaused();
412    }
413
414    private bool forceStop = false;
415    public void Stop() {
416      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
417        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
418      forceStop = true;
419      Algorithm.Stop();
420    }
421
422    private void AddAlgorithmAnalyzers() {
423      if (!Algorithm.Parameters.ContainsKey("Analyzer")) return;
424      var analyzerParam = Algorithm.Parameters["Analyzer"] as IValueParameter<MultiAnalyzer>;
425      if (analyzerParam == null) return;
426      if (!analyzerParam.Value.Operators.Contains(perClockAnalyzer))
427        analyzerParam.Value.Operators.Add(perClockAnalyzer);
428      if (!analyzerParam.Value.Operators.Contains(perEvaluationsAnalyzer))
429        analyzerParam.Value.Operators.Add(perEvaluationsAnalyzer);
430    }
431
432    private void RemoveAlgorithmAnalyzers() {
433      if (!Algorithm.Parameters.ContainsKey("Analyzer")) return;
434      var analyzerParam = Algorithm.Parameters["Analyzer"] as IValueParameter<MultiAnalyzer>;
435      if (analyzerParam == null) return;
436      analyzerParam.Value.Operators.Remove(perClockAnalyzer);
437      analyzerParam.Value.Operators.Remove(perEvaluationsAnalyzer);
438    }
439
440    #region Events
441    protected override void OnNameChanged() {
442      base.OnNameChanged();
443      runs.OptimizerName = Name;
444    }
445
446    public event PropertyChangedEventHandler PropertyChanged;
447    private void OnPropertyChanged(string property) {
448      var handler = PropertyChanged;
449      if (handler != null) handler(this, new PropertyChangedEventArgs(property));
450    }
451
452    #region IExecutable Events
453    public event EventHandler ExecutionStateChanged;
454    private void OnExecutionStateChanged() {
455      var handler = ExecutionStateChanged;
456      if (handler != null) handler(this, EventArgs.Empty);
457    }
458    public event EventHandler ExecutionTimeChanged;
459    private void OnExecutionTimeChanged() {
460      var handler = ExecutionTimeChanged;
461      if (handler != null) handler(this, EventArgs.Empty);
462    }
463    public event EventHandler Prepared;
464    private void OnPrepared() {
465      var handler = Prepared;
466      if (handler != null) handler(this, EventArgs.Empty);
467    }
468    public event EventHandler Started;
469    private void OnStarted() {
470      var handler = Started;
471      if (handler != null) handler(this, EventArgs.Empty);
472    }
473    public event EventHandler Paused;
474    private void OnPaused() {
475      var handler = Paused;
476      if (handler != null) handler(this, EventArgs.Empty);
477    }
478    public event EventHandler Stopped;
479    private void OnStopped() {
480      var handler = Stopped;
481      if (handler != null) handler(this, EventArgs.Empty);
482    }
483    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
484    private void OnExceptionOccurred(Exception exception) {
485      var handler = ExceptionOccurred;
486      if (handler != null) handler(this, new EventArgs<Exception>(exception));
487    }
488    #endregion
489
490    #region Algorithm Events
491    private void RegisterAlgorithmEvents() {
492      algorithm.ExceptionOccurred += Algorithm_ExceptionOccurred;
493      algorithm.ExecutionTimeChanged += Algorithm_ExecutionTimeChanged;
494      algorithm.Paused += Algorithm_Paused;
495      algorithm.Prepared += Algorithm_Prepared;
496      algorithm.Stopped += Algorithm_Stopped;
497      algorithm.ProblemChanged += Algorithm_ProblemChanged;
498      Algorithm_ProblemChanged(algorithm, EventArgs.Empty);
499    }
500    private void DeregisterAlgorithmEvents() {
501      algorithm.ExceptionOccurred -= Algorithm_ExceptionOccurred;
502      algorithm.ExecutionTimeChanged -= Algorithm_ExecutionTimeChanged;
503      algorithm.Paused -= Algorithm_Paused;
504      algorithm.Prepared -= Algorithm_Prepared;
505      algorithm.Stopped -= Algorithm_Stopped;
506      algorithm.ProblemChanged -= Algorithm_ProblemChanged;
507    }
508    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
509      OnExceptionOccurred(e.Value);
510    }
511    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
512      ExecutionTime += Algorithm.ExecutionTime - lastAlgorithmExecutionTime;
513      lastAlgorithmExecutionTime = Algorithm.ExecutionTime;
514    }
515    private void Algorithm_Paused(object sender, EventArgs e) {
516      ExecutionTime += Algorithm.ExecutionTime - lastAlgorithmExecutionTime;
517      lastAlgorithmExecutionTime = Algorithm.ExecutionTime;
518      OnPaused();
519    }
520    private void Algorithm_Prepared(object sender, EventArgs e) {
521      lastAlgorithmExecutionTime = TimeSpan.Zero;
522    }
523    private void Algorithm_Stopped(object sender, EventArgs e) {
524      var bestQuality = UpdateAlgorithmResults();
525
526      var execTime = ((TimeSpanValue)CurrentRun.Results[ExecutionTimeResultName]).Value;
527      double evaluationsInThisRun = 0;
528      foreach (var result in Algorithm.Results) {
529        if (result.Name == perClockAnalyzer.QualityPerClockParameter.ResultName) {
530          if (!CurrentRun.Results.ContainsKey(result.Name))
531            CurrentRun.Results.Add(result.Name, (IItem)result.Value.Clone());
532          else {
533            var dt = (IndexedDataTable<double>)CurrentRun.Results[result.Name];
534            var best = dt.Rows.First().Values.Last().Item2;
535            var resultDt = (IndexedDataTable<double>)result.Value;
536            foreach (var tupl in resultDt.Rows.First().Values) {
537              if (Maximization && tupl.Item2 > best || !Maximization && tupl.Item2 < best) {
538                dt.Rows.First().Values.Add(Tuple.Create(execTime.TotalSeconds + tupl.Item1, tupl.Item2));
539                best = tupl.Item2;
540              }
541            }
542          }
543        } else if (result.Name == perEvaluationsAnalyzer.QualityPerEvaluationsParameter.ResultName) {
544          if (!CurrentRun.Results.ContainsKey(result.Name))
545            CurrentRun.Results.Add(result.Name, (IItem)result.Value.Clone());
546          else {
547            var dt = (IndexedDataTable<double>)CurrentRun.Results[result.Name];
548            var evalSols = ((IntValue)CurrentRun.Results[perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName]).Value;
549            var evalMoves = ((IntValue)CurrentRun.Results[perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName]).Value;
550            var best = dt.Rows.First().Values.Last().Item2;
551            var resultDt = (IndexedDataTable<double>)result.Value;
552            foreach (var tupl in resultDt.Rows.First().Values) {
553              if (Maximization && tupl.Item2 > best || !Maximization && tupl.Item2 < best) {
554                dt.Rows.First().Values.Add(Tuple.Create(evalSols + moveCostPerSolution * evalMoves + tupl.Item1, tupl.Item2));
555                best = tupl.Item2;
556              }
557            }
558          }
559        } else if (result.Name == perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName) {
560          var oldEvals = ((IntValue)CurrentRun.Results[perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName]).Value;
561          var newEvals = ((IntValue)result.Value).Value;
562          CurrentRun.Results[perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName] = new IntValue(oldEvals + newEvals);
563          evaluationsInThisRun += newEvals;
564        } else if (result.Name == perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName) {
565          var oldEvals = ((IntValue)CurrentRun.Results[perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName]).Value;
566          var newEvals = ((IntValue)result.Value).Value;
567          CurrentRun.Results[perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName] = new IntValue(oldEvals + newEvals);
568          evaluationsInThisRun += newEvals * moveCostPerSolution;
569        } else if (result.Name == perEvaluationsAnalyzer.BestQualityParameter.ActualName) {
570          var best = ((DoubleValue)CurrentRun.Results[BestQualityResultName]).Value;
571          if (Maximization && best < bestQuality || !Maximization && best > bestQuality)
572            CurrentRun.Results[BestQualityResultName] = new DoubleValue(bestQuality);
573        } else if (result.Name.ToLower().EndsWith("solution") && BestSoFar == bestQuality) {
574          if (CurrentRun.Results.ContainsKey(result.Name))
575            CurrentRun.Results[result.Name] = (IItem)result.Value.Clone();
576          else CurrentRun.Results.Add(result.Name, (IItem)result.Value.Clone());
577        }
578      }
579      CurrentRun.Results[ExecutionTimeResultName] = new TimeSpanValue(execTime + Algorithm.ExecutionTime);
580
581      // Algorithm sets ExecutionTime to zero before firing Prepared
582      // We will thus see ExecutionTimeChanged before Prepared
583      lastAlgorithmExecutionTime = TimeSpan.Zero;
584
585      if (!forceStop && !IsFinished) {
586        var restarts = ((IntValue)CurrentRun.Results[RandomRestartsResultName]).Value;
587        if (restarts == 0) {
588          CurrentRun.Results[RTusResultName] = new DoubleValue(Algorithm.ExecutionTime.TotalSeconds);
589          CurrentRun.Results[FEusResultName] = new DoubleValue(evaluationsInThisRun);
590        } else {
591          var rtus = ((DoubleValue)CurrentRun.Results[RTusResultName]).Value;
592          var feus = ((DoubleValue)CurrentRun.Results[FEusResultName]).Value;
593          CurrentRun.Results[RTusResultName] = new DoubleValue(rtus * restarts / (restarts + 1.0) + Algorithm.ExecutionTime.TotalSeconds / (restarts + 1.0));
594          CurrentRun.Results[FEusResultName] = new DoubleValue(feus * restarts / (restarts + 1.0) + evaluationsInThisRun / (restarts + 1.0));
595        }
596        CurrentRun.Results[RandomRestartsResultName] = new IntValue(restarts + 1);
597        Algorithm.Prepare(true);
598        Algorithm.Start();
599      } else {
600        if (Maximization && BestSoFar >= TargetValue || !Maximization && BestSoFar <= TargetValue) {
601          CurrentRun.Results[RTsResultName] = (IItem)Algorithm.Results[perClockAnalyzer.QualityPerClockParameter.ResultName].Value.Clone();
602          CurrentRun.Results[FEsResultName] = (IItem)Algorithm.Results[perEvaluationsAnalyzer.QualityPerEvaluationsParameter.ResultName].Value.Clone();
603        }
604        forceStop = false;
605        Runs.Add(CurrentRun);
606        Algorithm.Prepare(true);
607        ExecutionState = ExecutionState.Stopped;
608        OnStopped();
609      }
610    }
611
612    private double UpdateAlgorithmResults() {
613      ExecutionTime += Algorithm.ExecutionTime - lastAlgorithmExecutionTime;
614      lastAlgorithmExecutionTime = Algorithm.ExecutionTime;
615
616      IResult evaluationsResult;
617      if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.EvaluatedSolutionsParameter.ActualName, out evaluationsResult)) {
618        var evals = ((IntValue)evaluationsResult.Value).Value;
619        Evaluations += evals;
620      }
621      if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.EvaluatedMovesParameter.ActualName, out evaluationsResult)) {
622        var evals = ((IntValue)evaluationsResult.Value).Value;
623        Evaluations += moveCostPerSolution * evals;
624      }
625      if (Algorithm.Results.TryGetValue(perEvaluationsAnalyzer.BestQualityParameter.ActualName, out evaluationsResult)) {
626        var bestQuality = ((DoubleValue)evaluationsResult.Value).Value;
627        if (double.IsNaN(BestSoFar)
628            || Maximization && bestQuality > BestSoFar
629            || !Maximization && bestQuality < BestSoFar)
630          BestSoFar = bestQuality;
631        return bestQuality;
632      }
633      return double.NaN;
634    }
635
636    private void Algorithm_ProblemChanged(object sender, EventArgs e) {
637      if (problem != null) DeregisterProblemEvents();
638
639      problem = Algorithm.Problem as ISingleObjectiveHeuristicOptimizationProblem;
640      if (problem == null) return;
641      RegisterProblemEvents();
642
643      AddAlgorithmAnalyzers();
644
645      var maxParam = problem.MaximizationParameter as IValueParameter<BoolValue>;
646      if (maxParam != null)
647        Maximization = maxParam.Value.Value;
648      var bkParam = problem.BestKnownQualityParameter as IValueParameter<DoubleValue>;
649      if (bkParam != null && bkParam.Value != null)
650        TargetValue = bkParam.Value.Value;
651
652      Reset();
653    }
654
655    private void RegisterProblemEvents() {
656      problem.Reset += ProblemOnReset;
657      problem.OperatorsChanged += ProblemOnOperatorsChanged;
658    }
659
660    private void DeregisterProblemEvents() {
661      problem.Reset -= ProblemOnReset;
662      problem.OperatorsChanged -= ProblemOnOperatorsChanged;
663    }
664
665    private void ProblemOnReset(object sender, EventArgs eventArgs) {
666      AddAlgorithmAnalyzers();
667    }
668
669    private void ProblemOnOperatorsChanged(object sender, EventArgs eventArgs) {
670      AddAlgorithmAnalyzers();
671    }
672    #endregion
673    #endregion
674  }
675}
Note: See TracBrowser for help on using the repository browser.