Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/29/18 18:16:05 (6 years ago)
Author:
abeham
Message:

#2457:

  • Changed calculation of correlation length (using limit introduced Hordijk 1996)
  • Changed RuggednessCalculator (no more a HL item)
  • Added additional, information-analysis-based features for directed walks
  • Added generic DirectedWalk algorithm (as described in thesis)
  • Made OneSizeInstanceProvider parametrizable
  • Adapted program for analyzing problem instance reidentification
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2457_ExpertSystem/HeuristicLab.Analysis.FitnessLandscape/3.3/ProblemCharacteristicAnalysis/CurveAnalysis.cs

    r14691 r16096  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System;
    223using System.Collections.Generic;
    324using System.Linq;
     
    728    public static CurveAnalysisResult GetCharacteristics(List<List<Tuple<T, double>>> trajectories, Func<T, T, double> distFunc) {
    829      trajectories = trajectories.Where(x => x.Count > 5).ToList();
     30      var symbols = GetSymbols(trajectories);
    931      var f1 = trajectories.Select(path => ApproximateDerivative(path, distFunc).ToList()).ToList();
    1032      var f2 = f1.Select(d1 => ApproximateDerivative(d1, distFunc).ToList()).ToList();
    1133
    12       var sharpness = f1.Average(x => x.Average(y => Math.Abs(y.Item2)));//f2.Average(x => Area(x, distFunc));
     34      var sharpness = f1.Average(x => x.Average(y => Math.Abs(y.Item2)));
    1335      var bumpiness = 0.0;
    1436      var flatness = 0.0;
    15 
     37      var count = 0;
    1638      for (var p = 0; p < f2.Count; p++) {
    1739        if (f2[p].Count <= 2) continue;
     40        count++;
    1841        var bump = 0;
    1942        var flat = 0;
     
    2851        flatness += flat / (f2[p].Count - 1.0);
    2952      }
    30       bumpiness /= f2.Count;
    31       flatness /= f2.Count;
    32       return new CurveAnalysisResult(sharpness, bumpiness, flatness);
     53      bumpiness /= count;
     54      flatness /= count;
     55      var per = new[] { 25, 50, 75 };
     56      return new CurveAnalysisResult(sharpness, bumpiness, flatness,
     57        per.Select(p => symbols.Downward.GetPercentileOrDefault(p, 0)).ToArray(),
     58        per.Select(p => symbols.Neutral.GetPercentileOrDefault(p, 0)).ToArray(),
     59        per.Select(p => symbols.Upward.GetPercentileOrDefault(p, 0)).ToArray());
    3360    }
    3461
    35     private static double Area(IEnumerable<Tuple<T, double>> path, Func<T, T, double> distFunc) {
    36       var iter = path.GetEnumerator();
    37       if (!iter.MoveNext()) return 0.0;
    38       var area = 0.0;
    39       var prev = iter.Current;
    40       while (iter.MoveNext()) {
    41         area += TrapezoidArea(prev, iter.Current, distFunc);
    42         prev = iter.Current;
     62    private static Symbols GetSymbols(List<List<Tuple<T, double>>> trajectories) {
     63      var sym = new Symbols();
     64      foreach (var t in trajectories) {
     65        var prev = t[0];
     66        for (var i = 1; i < t.Count; i++) {
     67          sym.Add(i / (double)t.Count, t[i].Item2, prev.Item2);
     68          prev = t[i];
     69        }
    4370      }
    44       return area;
    45     }
    46 
    47     private static double TrapezoidArea(Tuple<T, double> a, Tuple<T, double> b, Func<T, T, double> distFunc) {
    48       var area = 0.0;
    49       var dist = distFunc(a.Item1, b.Item1);
    50       if ((a.Item2 <= 0 && b.Item2 <= 0) || (a.Item2 >= 0 && b.Item2 >= 0))
    51         area += dist * (Math.Abs(a.Item2) + Math.Abs(b.Item2)) / 2.0;
    52       else {
    53         var k = (b.Item2 - a.Item2) / dist;
    54         var d = a.Item2;
    55         var x = -d / k;
    56         area += Math.Abs(x * a.Item2 / 2.0);
    57         area += Math.Abs((dist - x) * b.Item2 / 2.0);
    58       }
    59       return area;
     71      return sym;
    6072    }
    6173
     
    8092  }
    8193
     94  public enum CurveAnalysisFeature { Sharpness, Bumpiness, Flatness,
     95                                     DownQ1, DownQ2, DownQ3,
     96                                     NeutQ1, NeutQ2, NeutQ3,
     97                                     UpQ1, UpQ2, UpQ3 }
     98
    8299  public class CurveAnalysisResult {
    83     public double Sharpness { get; private set; }
    84     public double Bumpiness { get; private set; }
    85     public double Flatness { get; private set; }
     100    private Dictionary<CurveAnalysisFeature, double> results = new Dictionary<CurveAnalysisFeature, double>();
    86101
    87     public string[] GetNames() {
    88       return new[] { "Sharpness", "Bumpiness", "Flatness" };
     102    public double GetValue(CurveAnalysisFeature name) {
     103      return results[name];
     104    }
     105
     106    public static IEnumerable<CurveAnalysisFeature> AllFeatures {
     107      get { return Enum.GetValues(typeof(CurveAnalysisFeature)).Cast<CurveAnalysisFeature>(); }
    89108    }
    90109
    91110    public double[] GetValues() {
    92       return new[] { Sharpness, Bumpiness, Flatness };
     111      return AllFeatures.Select(x => results[x]).ToArray();
    93112    }
    94113
    95     public CurveAnalysisResult(double sharpness, double bumpiness, double flatness) {
    96       Sharpness = sharpness;
    97       Bumpiness = bumpiness;
    98       Flatness = flatness;
     114    public CurveAnalysisResult(double sharpness, double bumpiness, double flatness, double[] down, double[] neut, double[] up) {
     115      foreach (var v in AllFeatures.Zip(new[] { sharpness, bumpiness, flatness }.Concat(down).Concat(neut).Concat(up), (n, v) => Tuple.Create(n, v))) {
     116        results[v.Item1] = v.Item2;
     117      }
     118    }
     119  }
     120
     121  public class Symbols {
     122    public Statistics Downward { get; } = new Statistics();
     123    public Statistics Neutral { get; } = new Statistics();
     124    public Statistics Upward { get; } = new Statistics();
     125
     126    public void Add(double step, double fit, double prev) {
     127      if (fit < prev) Downward.Add(step);
     128      else if (fit > prev) Upward.Add(step);
     129      else Neutral.Add(step);
     130    }
     131  }
     132
     133  public sealed class Statistics {
     134    private List<double> values = new List<double>();
     135
     136    public int Count { get { return values.Count; } }
     137
     138    public double Min { get; private set; }
     139    public double Max { get; private set; }
     140    public double Total { get; private set; }
     141    public double Mean { get; private set; }
     142    public double StdDev { get { return Math.Sqrt(Variance); } }
     143    public double Variance { get { return Count > 0 ? variance / Count : 0.0; } }
     144   
     145    private double variance;
     146    private bool sorted = false;
     147   
     148    public double GetPercentileOrDefault(int p, double @default = default(double)) {
     149      if (p < 0 || p > 100) throw new ArgumentOutOfRangeException(nameof(p), p, "Must be in range [0;100]");
     150      SortIfNecessary();
     151      if (Count == 0) return @default;
     152      else if (Count == 1) return values[0];
     153      if (p == 100) return values[Count - 1];
     154
     155      var x = p / 100.0 * (Count - 1);
     156      var inte = (int)x;
     157      var frac = x - inte;
     158
     159      return values[inte] + frac * (values[inte + 1] - values[inte]);
     160    }
     161
     162    public void Add(double value) {
     163      sorted = false;
     164      values.Add(value);
     165
     166      if (Count == 1) {
     167        Min = Max = Mean = Total = value;
     168      } else {
     169        if (value < Min) Min = value;
     170        if (value > Max) Max = value;
     171
     172        Total += value;
     173        var oldMean = Mean;
     174        Mean = oldMean + (value - oldMean) / Count;
     175        variance = variance + (value - oldMean) * (value - Mean);
     176      }
     177    }
     178
     179    public void AddRange(IEnumerable<double> values) {
     180      foreach (var v in values) Add(v);
     181    }
     182
     183    private void SortIfNecessary() {
     184      if (!sorted) {
     185        values.Sort();
     186        sorted = true;
     187      }
    99188    }
    100189  }
Note: See TracChangeset for help on using the changeset viewer.