#region License Information /* HeuristicLab * Copyright (C) 2002-2016 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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using System; using System.Collections.Generic; using System.Linq; namespace HeuristicLab.Analysis.FitnessLandscape { [Item("Ruggedness Calculator", "Calculates ruggedness descriptors froma given quality trail.")] [StorableClass] public class RuggednessCalculator : SingleSuccessorOperator { #region Parameters public LookupParameter QualityTrailParameter { get { return (LookupParameter)Parameters["QualityTrail"]; } } public LookupParameter CorrelationLengthParameter { get { return (LookupParameter)Parameters["CorrelationLength"]; } } public LookupParameter AutoCorrelationParameter { get { return (LookupParameter)Parameters["AutoCorrelation"]; } } #endregion #region Constructors & Cloning [StorableConstructor] protected RuggednessCalculator(bool deserializing) : base(deserializing) { } protected RuggednessCalculator(RuggednessCalculator original, Cloner cloner) : base(original, cloner) { } public RuggednessCalculator() { Parameters.Add(new LookupParameter("QualityTrail", "Historical values of walk qualities")); Parameters.Add(new LookupParameter("CorrelationLength", "Average maximum distances between correlated quality values.")); Parameters.Add(new LookupParameter("AutoCorrelation", "AutoCorrelation")); } public override IDeepCloneable Clone(Cloner cloner) { return new RuggednessCalculator(this, cloner); } #endregion public override IOperation Apply() { double[] qualities = QualityTrailParameter.ActualValue.Rows.First().Values.ToArray(); double[] autocorrelation; CorrelationLengthParameter.ActualValue = new IntValue(CalculateCorrelationLength(qualities, out autocorrelation)); AutoCorrelationParameter.ActualValue = new DoubleArray(autocorrelation); return base.Apply(); } public static int CalculateCorrelationLength(double[] qualities, out double[] acf) { double[] correlations = new double[qualities.Length]; alglib.corr.corrr1dcircular(qualities, qualities.Length, qualities, qualities.Length, ref correlations); double mean = 0; double variance = 0; double skewness = 0; double kurtosis = 0; alglib.basestat.samplemoments(qualities, qualities.Length, ref mean, ref variance, ref skewness, ref kurtosis); List autocorrelation = new List() { 1.0 }; int correlationLength = -1, counter = 1; for (; counter < qualities.Length / 2; counter++) { double value = correlations[counter] / qualities.Length - mean * mean; if (variance > 0) value = Math.Max(Math.Min(value / variance, 1.0), -1.0); else value = 1; autocorrelation.Add(value); if (value < 0 && correlationLength < 0) correlationLength = counter; } acf = autocorrelation.ToArray(); return correlationLength - 1; } public static bool AnyGreaterOne(double[] values) { return values.Any(d => d > 1); } } }