#region License Information /* HeuristicLab * Copyright (C) 2002-2015 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.Collections.Generic; using System.Linq; 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; using HeuristicLab.Problems.DataAnalysis; namespace HeuristicLab.GoalSeeking { [StorableClass] [Item("BestSolutionAnalyzer", "An analyzer which identifies the best solution from the SingleObjectiveProcessParameterOptimizationProblem")] public class BestSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer { private const string RowParameterName = "Row"; private const string ProblemDataParameterName = "ProblemData"; private const string QualityParameterName = "Quality"; private const string MaximizationParameterName = "Maximization"; public bool EnabledByDefault { get { return true; } } public IScopeTreeLookupParameter QualityParameter { get { return (IScopeTreeLookupParameter)Parameters[QualityParameterName]; } } public ILookupParameter MaximizationParameter { get { return (ILookupParameter)Parameters[MaximizationParameterName]; } } public IFixedValueParameter BestSolutionResultNameParameter { get { return (IFixedValueParameter)Parameters["BestSolution ResultName"]; } } public ILookupParameter BestKnownQualityParameter { get { return (ILookupParameter)Parameters["BestKnownQuality"]; } } public ILookupParameter ResultsParameter { get { return (ILookupParameter)Parameters["Results"]; } } public ILookupParameter RowParameter { get { return (ILookupParameter)Parameters[RowParameterName]; } } public ILookupParameter ProblemDataParameter { get { return (ILookupParameter)Parameters[ProblemDataParameterName]; } } public BoolValue Maximization { get { return MaximizationParameter.ActualValue; } } public ItemArray Quality { get { return QualityParameter.ActualValue; } } public ResultCollection Results { get { return ResultsParameter.ActualValue; } } public string BestSolutionResultName { get { return BestSolutionResultNameParameter.Value.Value; } set { BestSolutionResultNameParameter.Value.Value = value; } } public BestSolutionAnalyzer() { Parameters.Add(new FixedValueParameter("BestSolution ResultName", "The name of the result for storing the best solution.", new StringValue("Best Solution"))); Parameters.Add(new LookupParameter("BestKnownQuality", "The quality of the best known solution.")); Parameters.Add(new LookupParameter(RowParameterName, "The current row")); Parameters.Add(new LookupParameter(ProblemDataParameterName, "The problem data")); Parameters.Add(new LookupParameter(MaximizationParameterName, "Specifies whether the problem is a minimization or a maximization problem.")); Parameters.Add(new ScopeTreeLookupParameter(QualityParameterName, "The qualities of the individuals in the population")); Parameters.Add(new LookupParameter("Results", "The result collection")); } protected BestSolutionAnalyzer(BestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new BestSolutionAnalyzer(this, cloner); } [StorableConstructor] protected BestSolutionAnalyzer(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { if (!Parameters.ContainsKey(MaximizationParameterName)) Parameters.Add(new LookupParameter(MaximizationParameterName, "Specifies whether the problem is a minimization or a maximization problem.")); if (!Parameters.ContainsKey(QualityParameterName)) Parameters.Add(new ScopeTreeLookupParameter(QualityParameterName, "The qualities of the individuals in the population")); if (!Parameters.ContainsKey("Results")) Parameters.Add(new LookupParameter("Results", "The result collection")); } public override IOperation Apply() { IEnumerable scopes = new[] { ExecutionContext.Scope }; var zipped = Quality.Select((x, index) => new { Index = index, x.Value }); var best = Maximization.Value ? zipped.OrderBy(x => x.Value).First() : zipped.OrderByDescending(x => x.Value).First(); for (int j = 0; j < QualityParameter.Depth; j++) scopes = scopes.SelectMany(x => x.SubScopes); IScope currentBestScope = scopes.ToList()[best.Index]; var bestSolution = (RealVector)currentBestScope.Variables["RealVector"].Value; var bestSolutionMatrix = new DoubleMatrix(bestSolution.Length, 3); var targetNames = bestSolution.ElementNames.ToList(); bestSolutionMatrix.RowNames = targetNames; bestSolutionMatrix.ColumnNames = new[] { "Estimated value", "Target value", "Deviation" }; var problemData = ProblemDataParameter.ActualValue; var row = RowParameter.ActualValue.Value; for (int i = 0; i < bestSolution.Length; ++i) { var estimatedValue = bestSolution[i]; var targetValue = problemData.Dataset.GetDoubleValue(targetNames[i], row); bestSolutionMatrix[i, 0] = estimatedValue; bestSolutionMatrix[i, 1] = targetValue; bestSolutionMatrix[i, 2] = estimatedValue - targetValue; } if (!Results.ContainsKey(BestSolutionResultName)) { Results.Add(new Result(BestSolutionResultName, bestSolutionMatrix)); } else { var result = Results[BestSolutionResultName]; result.Value = bestSolutionMatrix; } return base.Apply(); } } }