Index: branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/ProblemCharacteristicAnalysis/QAP/QAPDirectedWalk.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/ProblemCharacteristicAnalysis/QAP/QAPDirectedWalk.cs	(revision 14690)
+++ branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/ProblemCharacteristicAnalysis/QAP/QAPDirectedWalk.cs	(revision 14691)
@@ -79,5 +79,5 @@
     private QAPDirectedWalk(QAPDirectedWalk original, Cloner cloner) : base(original, cloner) { }
     public QAPDirectedWalk() {
-      characteristics.AddRange(new[] { "Swap2.Sharpness", "Swap2.Bumpiness", "Swap2.Flatness", "Swap2.Steadiness" }
+      characteristics.AddRange(new[] { "Swap2.Sharpness", "Swap2.Bumpiness", "Swap2.Flatness", /*"Swap2.Steadiness"*/ }
         .Select(x => new StringValue(x)).ToList());
       Parameters.Add(new FixedValueParameter<IntValue>("Paths", "The number of paths to explore (a path is a set of solutions that connect two randomly chosen solutions).", new IntValue(50)));
@@ -118,25 +118,11 @@
 
       var trajectories = Run(random, (QuadraticAssignmentProblem)Problem, permutations, BestImprovement).ToList();
-      var firstDerivatives = trajectories.Select(path => ApproximateDerivative(path).ToList()).ToList();
-      var secondDerivatives = firstDerivatives.Select(d1 => ApproximateDerivative(d1).ToList()).ToList();
+      var result = PermutationPathAnalysis.GetCharacteristics(trajectories);
       
-      var props = GetCharacteristics(trajectories, firstDerivatives, secondDerivatives).ToDictionary(x => x.Item1, x => x.Item2);
       foreach (var chara in characteristics.CheckedItems.Select(x => x.Value.Value)) {
-        if (chara == "Swap2.Sharpness") yield return new Result("Swap2.Sharpness", new DoubleValue(props["Sharpness"]));
-        if (chara == "Swap2.Bumpiness") yield return new Result("Swap2.Bumpiness", new DoubleValue(props["Bumpiness"]));
-        if (chara == "Swap2.Flatness") yield return new Result("Swap2.Flatness", new DoubleValue(props["Flatness"]));
-        if (chara == "Swap2.Steadiness") yield return new Result("Swap2.Steadiness", new DoubleValue(props["Steadiness"]));
-      }
-    }
-
-    public static IEnumerable<IResult> Calculate(List<List<Tuple<Permutation, double>>> trajectories) {
-      var firstDerivatives = trajectories.Select(path => ApproximateDerivative(path).ToList()).ToList();
-      var secondDerivatives = firstDerivatives.Select(d1 => ApproximateDerivative(d1).ToList()).ToList();
-
-      var props = GetCharacteristics(trajectories, firstDerivatives, secondDerivatives).ToDictionary(x => x.Item1, x => x.Item2);
-      yield return new Result("Swap2.Sharpness", new DoubleValue(props["Sharpness"]));
-      yield return new Result("Swap2.Bumpiness", new DoubleValue(props["Bumpiness"]));
-      yield return new Result("Swap2.Flatness", new DoubleValue(props["Flatness"]));
-      yield return new Result("Swap2.Steadiness", new DoubleValue(props["Steadiness"]));
+        if (chara == "Swap2.Sharpness") yield return new Result("Swap2.Sharpness", new DoubleValue(result.Sharpness));
+        if (chara == "Swap2.Bumpiness") yield return new Result("Swap2.Bumpiness", new DoubleValue(result.Bumpiness));
+        if (chara == "Swap2.Flatness") yield return new Result("Swap2.Flatness", new DoubleValue(result.Flatness));
+      }
     }
 
@@ -158,41 +144,5 @@
     }
 
-    private static IEnumerable<Tuple<string, double>> GetCharacteristics(List<List<Tuple<Permutation, double>>> f, List<List<Tuple<Permutation, double>>> f1, List<List<Tuple<Permutation, double>>> f2) {
-      var sharpness = f2.Average(x => Area(x));
-      var bumpiness = 0.0;
-      var flatness = 0.0;
-      var downPointing = f1.Where(x => x.Min(y => y.Item2) < 0).ToList();
-
-      var steadiness = 0.0;
-      foreach (var path in downPointing) {
-        steadiness += ComBelowZero(path);
-      }
-      if (downPointing.Count > 0) steadiness /= downPointing.Count;
-
-      for (var p = 0; p < f2.Count; p++) {
-        if (f2[p].Count <= 2) continue;
-        var bump = 0;
-        var flat = 0;
-        for (var i = 0; i < f2[p].Count - 1; i++) {
-          if ((f2[p][i].Item2 > 0 && f2[p][i + 1].Item2 < 0) || (f2[p][i].Item2 < 0 && f2[p][i + 1].Item2 > 0)) {
-            bump++;
-          } else if (f2[p][i].Item2 == 0) {
-            flat++;
-          }
-        }
-        bumpiness += bump / (f2[p].Count - 1.0);
-        flatness += flat / (f2[p].Count - 1.0);
-      }
-      bumpiness /= f2.Count;
-      flatness /= f2.Count;
-      return new[] {
-      Tuple.Create("Sharpness", sharpness),
-      Tuple.Create("Bumpiness", bumpiness),
-      Tuple.Create("Flatness", flatness),
-      Tuple.Create("Steadiness", steadiness)
-    };
-    }
-
-    public static IEnumerable<Tuple<Permutation, double>> BestDirectedWalk(QuadraticAssignmentProblem qap, Permutation start, Permutation end) {
+    private static IEnumerable<Tuple<Permutation, double>> BestDirectedWalk(QuadraticAssignmentProblem qap, Permutation start, Permutation end) {
       var N = qap.Weights.Rows;
       var sol = start;
@@ -225,5 +175,5 @@
     }
 
-    public static IEnumerable<Tuple<Permutation, double>> FirstDirectedWalk(IRandom random, QuadraticAssignmentProblem qap, Permutation start, Permutation end) {
+    private static IEnumerable<Tuple<Permutation, double>> FirstDirectedWalk(IRandom random, QuadraticAssignmentProblem qap, Permutation start, Permutation end) {
       var N = qap.Weights.Rows;
       var sol = start;
@@ -260,80 +210,4 @@
     }
 
-    private static double Area(IEnumerable<Tuple<Permutation, double>> path) {
-      var iter = path.GetEnumerator();
-      if (!iter.MoveNext()) return 0.0;
-      var area = 0.0;
-      var prev = iter.Current;
-      while (iter.MoveNext()) {
-        area += TrapezoidArea(prev, iter.Current);
-        prev = iter.Current;
-      }
-      return area;
-    }
-
-    private static double TrapezoidArea(Tuple<Permutation, double> a, Tuple<Permutation, double> b) {
-      var area = 0.0;
-      var dist = Dist(a.Item1, b.Item1);
-      if ((a.Item2 <= 0 && b.Item2 <= 0) || (a.Item2 >= 0 && b.Item2 >= 0))
-        area += dist * (Math.Abs(a.Item2) + Math.Abs(b.Item2)) / 2.0;
-      else {
-        var k = (b.Item2 - a.Item2) / dist;
-        var d = a.Item2;
-        var x = -d / k;
-        area += Math.Abs(x * a.Item2 / 2.0);
-        area += Math.Abs((dist - x) * b.Item2 / 2.0);
-      }
-      return area;
-    }
-
-    // Center-of-Mass
-    private static double ComBelowZero(IEnumerable<Tuple<Permutation, double>> path) {
-      var area = 0.0;
-      var com = 0.0;
-      var nwalkDist = 0.0;
-      Tuple<Permutation, double> prev = null;
-      var iter = path.GetEnumerator();
-      while (iter.MoveNext()) {
-        var c = iter.Current;
-        if (prev != null) {
-          var ndist = Dist(prev.Item1, c.Item1) / (double)c.Item1.Length;
-          nwalkDist += ndist;
-          if (prev.Item2 < 0 || c.Item2 < 0) {
-            var a = TrapezoidArea(prev, c) / (double)c.Item1.Length;
-            area += a;
-            com += (nwalkDist - (ndist / 2.0)) * a;
-          }
-        }
-        prev = c;
-      }
-      return com / area;
-    }
-
-    private static IEnumerable<Tuple<Permutation, double>> ApproximateDerivative(IEnumerable<Tuple<Permutation, double>> data) {
-      Tuple<Permutation, double> prev = null, prev2 = null;
-      foreach (var d in data) {
-        if (prev == null) {
-          prev = d;
-          continue;
-        }
-        if (prev2 == null) {
-          prev2 = prev;
-          prev = d;
-          continue;
-        }
-        var dist = Dist(prev2.Item1, d.Item1);
-        yield return Tuple.Create(prev.Item1, (d.Item2 - prev2.Item2) / (double)dist);
-        prev2 = prev;
-        prev = d;
-      }
-    }
-
-    private static double Dist(Permutation a, Permutation b) {
-      var dist = 0;
-      for (var i = 0; i < a.Length; i++)
-        if (a[i] != b[i]) dist++;
-      return dist;
-    }
-
     private static int[] GetInverse(Permutation p) {
       var inv = new int[p.Length];
