#region License Information /* HeuristicLab * Copyright (C) 2002-2019 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.Linq; using HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.MovingPeaksBenchmark { /// /// An operator for analyzing the best solution for a SingleObjectiveTestFunction problem. /// [Item("BestMovingPeaksBenchmarkSolutionAnalyzer", "An operator for analyzing the best solution for a Moving Peaks Benchmark problem.")] [StorableClass] public class BestMovingPeaksBenchmarkSolutionAnalyzer : SingleSuccessorOperator, IBestMovingPeaksBenchmarkSolutionAnalyzer { public virtual bool EnabledByDefault { get { return true; } } public LookupParameter MaximizationParameter { get { return (LookupParameter)Parameters["Maximization"]; } } public ScopeTreeLookupParameter RealVectorParameter { get { return (ScopeTreeLookupParameter)Parameters["RealVector"]; } } ILookupParameter IBestMovingPeaksBenchmarkSolutionAnalyzer.RealVectorParameter { get { return RealVectorParameter; } } public ScopeTreeLookupParameter QualityParameter { get { return (ScopeTreeLookupParameter)Parameters["Quality"]; } } ILookupParameter IBestMovingPeaksBenchmarkSolutionAnalyzer.QualityParameter { get { return QualityParameter; } } public ILookupParameter BestKnownSolutionParameter { get { return (ILookupParameter)Parameters["BestKnownSolution"]; } } public ILookupParameter BestKnownQualityParameter { get { return (ILookupParameter)Parameters["BestKnownQuality"]; } } public IValueLookupParameter ResultsParameter { get { return (IValueLookupParameter)Parameters["Results"]; } } [StorableConstructor] protected BestMovingPeaksBenchmarkSolutionAnalyzer(bool deserializing) : base(deserializing) { } protected BestMovingPeaksBenchmarkSolutionAnalyzer(BestMovingPeaksBenchmarkSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { } public BestMovingPeaksBenchmarkSolutionAnalyzer() : base() { Parameters.Add(new LookupParameter("Maximization", "True if the problem is a maximization problem.")); Parameters.Add(new ScopeTreeLookupParameter("RealVector", "The SingleObjectiveTestFunction solutions from which the best solution should be visualized.")); Parameters.Add(new ScopeTreeLookupParameter("Quality", "The qualities of the SingleObjectiveTestFunction solutions which should be visualized.")); Parameters.Add(new LookupParameter("BestKnownSolution", "The best known solution.")); Parameters.Add(new LookupParameter("BestKnownQuality", "The quality of the best known solution.")); Parameters.Add(new ValueLookupParameter("Results", "The result collection where the SingleObjectiveTestFunction solution should be stored.")); MaximizationParameter.Hidden = true; RealVectorParameter.Hidden = true; QualityParameter.Hidden = true; BestKnownSolutionParameter.Hidden = true; BestKnownQualityParameter.Hidden = true; ResultsParameter.Hidden = true; } public override IDeepCloneable Clone(Cloner cloner) { return new BestMovingPeaksBenchmarkSolutionAnalyzer(this, cloner); } public override IOperation Apply() { ItemArray realVectors = RealVectorParameter.ActualValue; ItemArray qualities = QualityParameter.ActualValue; bool max = MaximizationParameter.ActualValue.Value; DoubleValue bestKnownQuality = BestKnownQualityParameter.ActualValue; int i = -1; if (!max) i = qualities.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index; else i = qualities.Select((x, index) => new { index, x.Value }).OrderByDescending(x => x.Value).First().index; RealVector best = (RealVector)realVectors[i].Clone(); RealVector bestKnown = (RealVector)BestKnownSolutionParameter.ActualValue.Clone(); ResultCollection results = ResultsParameter.ActualValue; IResult bestSolution, bestKnownSolution; if (!results.TryGetValue("Best Solution", out bestSolution)) { bestSolution = new Result("Best Solution", best); results.Add(bestSolution); } else { bestSolution.Value = best; } if (!results.TryGetValue("Best Known Solution", out bestKnownSolution)) { bestKnownSolution = new Result("Best Known Solution", bestKnown); results.Add(bestKnownSolution); } else { bestKnownSolution.Value = bestKnown; } double distanceToOptimum = 0; for (int j = 0; j < best.Length; j++) { distanceToOptimum += (best[j] - bestKnown[j]) * (best[j] - bestKnown[j]); } distanceToOptimum = Math.Sqrt(distanceToOptimum); IResult distanceTable; if (!results.TryGetValue("Distance to Optimum", out distanceTable)) { DataTable table = new DataTable("Distance to Optimum"); table.Rows.Add(new DataRow("Distance to Optimum")); table.Rows["Distance to Optimum"].VisualProperties.StartIndexZero = true; distanceTable = new Result("Distance to Optimum", table); results.Add(distanceTable); } (distanceTable.Value as DataTable).Rows["Distance to Optimum"].Values.Add(distanceToOptimum); IResult offlineErrorTable; if (!results.TryGetValue("Offline Error Chart", out offlineErrorTable)) { DataTable table = new DataTable("Offline Error"); table.Rows.Add(new DataRow("Offline Error")); table.Rows["Offline Error"].VisualProperties.StartIndexZero = true; offlineErrorTable = new Result("Offline Error Chart", table); results.Add(offlineErrorTable); } (offlineErrorTable.Value as DataTable).Rows["Offline Error"].Values.Add((results["Offline Error"].Value as DoubleValue).Value); return base.Apply(); } } }