#region License Information /* HeuristicLab * Copyright (C) 2002-2012 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.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HEAL.Attic; namespace HeuristicLab.Problems.DataAnalysis.Symbolic { [Item("Sliding Window GP Analyzer", "Base class for concrete sliding window GP analyzers.")] [StorableType("FDBFFC8A-27BF-44F7-B499-352443B65DBA")] public abstract class SlidingWindowAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer { private const string ProblemDataParameterName = "ProblemData"; private const string EvaluatorParameterName = "Evaluator"; private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition"; private const string ValidationPartitionParameterName = "ValidationPartition"; private const string SlidingWindowSizeParameterName = "Sliding Window Size"; private const string ValidationSlidingWindowSizeParameterName = "Validation Sliding Window Size"; private const string SlidingWindowStepWidthParameterName = "Sliding Window Step Width"; private const string InitialSlidingWindowParameterName = "Initial Sliding Window"; private const string TerminateSlidingWindowParameterName = "TerminateSlidingWindow"; private const string InterpreterParameterName = "SymbolicExpressionTreeInterpreter"; protected const string BestSlidingWindowSolutionsResultName = "Best Sliding Window Solutions"; #region parameter properties private ILookupParameter InterpreterParameter { get { return (ILookupParameter)Parameters[InterpreterParameterName]; } } public IValueLookupParameter ProblemDataParameter { get { return (IValueLookupParameter)Parameters[ProblemDataParameterName]; } } public ILookupParameter FitnessCalculationPartitionParameter { get { return (ILookupParameter)Parameters[FitnessCalculationPartitionParameterName]; } } public ILookupParameter ValidationPartitionParameter { get { return (ILookupParameter)Parameters[ValidationPartitionParameterName]; } } public IFixedValueParameter SlidingWindowSizeParameter { get { return (IFixedValueParameter)Parameters[SlidingWindowSizeParameterName]; } } public IFixedValueParameter ValidationSlidingWindowSizeParameter { get { return (IFixedValueParameter)Parameters[ValidationSlidingWindowSizeParameterName]; } } public IFixedValueParameter SlidingWindowStepWidthParameter { get { return (IFixedValueParameter)Parameters[SlidingWindowStepWidthParameterName]; } } public IFixedValueParameter InitialSlidingWindowParameter { get { return (IFixedValueParameter)Parameters[InitialSlidingWindowParameterName]; } } public ILookupParameter TerminateSlidingWindowParameter { get { return (ILookupParameter)Parameters[TerminateSlidingWindowParameterName]; } } public ILookupParameter EvaluatorParameter { get { return (ILookupParameter)Parameters[EvaluatorParameterName]; } } #endregion #region properties public override bool EnabledByDefault { get { return false; } } public IntValue SlidingWindowSize { get { return SlidingWindowSizeParameter.Value; } } public IntValue ValidationSlidingWindowSize { get { return ValidationSlidingWindowSizeParameter.Value; } } public IntValue SlidingWindowStepWidth { get { return SlidingWindowStepWidthParameter.Value; } } public IntRange InitialSlidingWindow { get { return InitialSlidingWindowParameter.Value; } } public ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter { get { return InterpreterParameter.ActualValue; } } public IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } } #endregion [StorableConstructor] protected SlidingWindowAnalyzer(StorableConstructorFlag _) : base(_) { } protected SlidingWindowAnalyzer(SlidingWindowAnalyzer original, Cloner cloner) : base(original, cloner) { } protected SlidingWindowAnalyzer() : base() { Parameters.Add(new ValueLookupParameter(ProblemDataParameterName, "The problem data on which the symbolic data analysis solution should be evaluated.")); Parameters.Add(new LookupParameter(EvaluatorParameterName, "")); Parameters.Add(new LookupParameter(FitnessCalculationPartitionParameterName, "")); Parameters.Add(new LookupParameter(ValidationPartitionParameterName, "")); Parameters.Add(new FixedValueParameter(SlidingWindowSizeParameterName, "", new IntValue(1))); Parameters.Add(new FixedValueParameter(ValidationSlidingWindowSizeParameterName, "", new IntValue(0))); Parameters.Add(new FixedValueParameter(SlidingWindowStepWidthParameterName, "", new IntValue(1))); Parameters.Add(new FixedValueParameter(InitialSlidingWindowParameterName, "", new IntRange(0, 1))); Parameters.Add(new LookupParameter(TerminateSlidingWindowParameterName, "")); if (!Parameters.ContainsKey(InterpreterParameterName)) Parameters.Add(new LookupParameter(InterpreterParameterName, "")); if (!Parameters.ContainsKey("Quality")) Parameters.Add(new ScopeTreeLookupParameter("Quality", "")); if (!Parameters.ContainsKey("Maximization")) Parameters.Add(new LookupParameter("Maximization", "The direction of optimization.")); ProblemDataParameter.Hidden = true; } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { if (!Parameters.ContainsKey(EvaluatorParameterName)) Parameters.Add(new LookupParameter(EvaluatorParameterName, "")); if (!Parameters.ContainsKey(InterpreterParameterName)) Parameters.Add(new LookupParameter(InterpreterParameterName, "")); if (!Parameters.ContainsKey("Quality")) Parameters.Add(new ScopeTreeLookupParameter("Quality", "")); if (!Parameters.ContainsKey("Maximization")) Parameters.Add(new LookupParameter("Maximization", "The direction of optimization.")); if (!Parameters.ContainsKey(ProblemDataParameterName)) Parameters.Add(new LookupParameter(ProblemDataParameterName)); } public override IOperation Apply() { //intialize sliding window if (FitnessCalculationPartitionParameter.ActualValue == null) { TerminateSlidingWindowParameter.ActualValue = new BoolValue(false); FitnessCalculationPartitionParameter.ActualValue = (IntRange)InitialSlidingWindow.Clone(); ValidationPartitionParameter.ActualValue = new IntRange(InitialSlidingWindow.End, InitialSlidingWindow.End + ValidationSlidingWindowSize.Value); return base.Apply(); } SaveBestSolution(); if (!CheckForUpdate()) return base.Apply(); //update necessary - move sliding window var fitnessPartition = (IntRange)FitnessCalculationPartitionParameter.ActualValue.Clone(); if (fitnessPartition.End - fitnessPartition.Start == SlidingWindowSize.Value) fitnessPartition.Start += SlidingWindowStepWidth.Value; fitnessPartition.End += SlidingWindowStepWidth.Value; if (fitnessPartition.End - fitnessPartition.Start > SlidingWindowSize.Value) fitnessPartition.End = fitnessPartition.Start + SlidingWindowSize.Value; //check if update should be performed or if the algorithm should stop if (fitnessPartition.End > ProblemDataParameter.ActualValue.TrainingPartition.End) { TerminateSlidingWindowParameter.ActualValue.Value = true; return base.Apply(); } FitnessCalculationPartitionParameter.ActualValue.Start = fitnessPartition.Start; FitnessCalculationPartitionParameter.ActualValue.End = fitnessPartition.End; ValidationPartitionParameter.ActualValue.Start = fitnessPartition.End; ValidationPartitionParameter.ActualValue.End = ValidationPartitionParameter.ActualValue.Start + ValidationSlidingWindowSize.Value; //reevaluate all individuals with new sliding window UniformSubScopesProcessor subScopesProcessor = new UniformSubScopesProcessor(); subScopesProcessor.Operator = EvaluatorParameter.ActualValue; subScopesProcessor.Depth.Value = 1; var operation = ExecutionContext.CreateChildOperation(subScopesProcessor); var successor = base.Apply(); return new OperationCollection() { operation, successor }; } private ISymbolicExpressionTree FindBestIndividual() { var pop = SymbolicExpressionTree.Zip(Quality, (t, q) => new { Tree = t, Quality = q.Value }).ToList(); Func comparer = (a, b) => Maximization.Value ? a.CompareTo(b) : b.CompareTo(a); pop.Sort((a, b) => comparer(a.Quality, b.Quality)); return pop.Last().Tree; } private void SaveBestSolution() { var bestSolutionsCollection = (SlidingWindowBestSolutionsCollection)ResultCollection[BestSlidingWindowSolutionsResultName].Value; bestSolutionsCollection.ProblemData = ProblemData; bestSolutionsCollection.Interpreter = Interpreter; bestSolutionsCollection.ApplyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value; var fitnessPartition = FitnessCalculationPartitionParameter.ActualValue; var best = FindBestIndividual(); var range = new SlidingWindowRange(fitnessPartition.Start, fitnessPartition.End); bestSolutionsCollection[range] = best; } protected abstract bool CheckForUpdate(); } }