#region License Information /* HeuristicLab * Copyright (C) 2002-2010 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.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Common; namespace HeuristicLab.Problems.DataAnalysis.Operators { [Item("DynamicDepthLimitComparator", "As implemented by Ciprian.")] [StorableClass] public class DynamicDepthLimitComparator : SingleSuccessorOperator, ISubScopesQualityComparator { public IValueLookupParameter MaximizationParameter { get { return (IValueLookupParameter)Parameters["Maximization"]; } } public ILookupParameter ResultParameter { get { return (ILookupParameter)Parameters["Result"]; } } public ILookupParameter LeftSideParameter { get { return (ILookupParameter)Parameters["LeftSide"]; } } public ILookupParameter> RightSideParameter { get { return (ILookupParameter>)Parameters["RightSide"]; } } public ILookupParameter SymbolicExpressionTreeParameter { get { return (ILookupParameter)Parameters["SymbolicExpressionTree"]; } } public IValueLookupParameter DynamicDepthLimitParameter { get { return (IValueLookupParameter)Parameters["DynamicDepthLimit"]; } } public IValueLookupParameter InitialDepthLimitParameter { get { return (IValueLookupParameter)Parameters["InitialDepthLimit"]; } } public IValueParameter CLowerParameter { get { return (IValueParameter)Parameters["cLower"]; } } public IValueParameter CRaiseParameter { get { return (IValueParameter)Parameters["cRaise"]; } } public ILookupParameter BestQualityParameter { get { return (ILookupParameter)Parameters["BestQuality"]; } } [StorableConstructor] protected DynamicDepthLimitComparator(bool deserializing) : base(deserializing) { } protected DynamicDepthLimitComparator(DynamicDepthLimitComparator original, Cloner cloner) : base(original, cloner) { } public DynamicDepthLimitComparator() : base() { Parameters.Add(new ValueLookupParameter("Maximization", "True if the problem is a maximization problem, false otherwise")); Parameters.Add(new LookupParameter("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents.")); Parameters.Add(new LookupParameter("LeftSide", "The quality of the child.")); Parameters.Add(new ScopeTreeLookupParameter("RightSide", "The qualities of the parents.")); Parameters.Add(new ValueLookupParameter("DynamicDepthLimit", "The current depth limit.")); Parameters.Add(new ValueLookupParameter("InitialDepthLimit")); Parameters.Add(new LookupParameter("SymbolicExpressionTree", "The newly created child.")); Parameters.Add(new LookupParameter("BestQuality")); Parameters.Add(new ValueParameter("cLower", "", new DoubleValue(0.03))); Parameters.Add(new ValueParameter("cRaise", "", new DoubleValue(0.015))); } public override IDeepCloneable Clone(Cloner cloner) { return new DynamicDepthLimitComparator(this, cloner); } public override IOperation Apply() { if (ResultParameter.ActualValue == null || ResultParameter.ActualValue.Value) { ResultParameter.ActualValue = new BoolValue(true); double leftQuality = LeftSideParameter.ActualValue.Value; bool maximization = MaximizationParameter.ActualValue.Value; SymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue; int ddl = DynamicDepthLimitParameter.ActualValue.Value; double cRaise = CRaiseParameter.Value.Value; double cLower = CLowerParameter.Value.Value; double bestQuality = BestQualityParameter.ActualValue.Value; double relativeQuality = maximization ? leftQuality / bestQuality - 1 : bestQuality / leftQuality - 1; if (tree.Height <= ddl) { // height is smaller than ddl => check improvement and reduce ddl if (relativeQuality >= (ddl - tree.Height) * cLower) { ddl = Math.Max(tree.Height, InitialDepthLimitParameter.ActualValue.Value); } } else { // height is larger than dll => check improvement and increase ddl if (relativeQuality >= (tree.Height - ddl) * cRaise) { ddl = tree.Height; } else { // height is larger but no improvement => reject ResultParameter.ActualValue.Value = false; } } // update best quality if (relativeQuality > 0 && ResultParameter.ActualValue.Value) BestQualityParameter.ActualValue.Value = leftQuality; DynamicDepthLimitParameter.ActualValue.Value = ddl; } return base.Apply(); } } }