Index: /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/HeuristicLab.Problems.Instances.TSPLIB-3.3.csproj
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/HeuristicLab.Problems.Instances.TSPLIB-3.3.csproj	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/HeuristicLab.Problems.Instances.TSPLIB-3.3.csproj	(revision 13470)
@@ -123,8 +123,8 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="MarsagliaRandom.cs" />
     <Compile Include="TSPLIBHeterogeneousPTSPDataDescriptor.cs" />
     <Compile Include="TSPLIBHomogeneousPTSPDataDescriptor.cs" />
     <Compile Include="TSPLIBHeterogeneousPTSPInstanceProvider.cs" />
+    <Compile Include="TSPLIBPTSPInstanceProvider.cs" />
     <Compile Include="TSPLIBInstanceProvider.cs" />
     <Compile Include="TSPLIBATSPInstanceProvider.cs" />
Index: anches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/MarsagliaRandom.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/MarsagliaRandom.cs	(revision 13469)
+++ 	(revision )
@@ -1,56 +1,0 @@
-﻿
-namespace HeuristicLab.Problems.Instances.TSPLIB {
-  /// <summary>
-  /// This class is used to randomly generate PTSP instances given the TSPLIB instances.
-  /// An own implementation of a RNG was used in order to avoid possible implementation changes
-  /// in future .NET versions which would result in entirely different instances.
-  /// </summary>
-  internal class MarsagliaRandom {
-    /*
-     * S = 2111111111*X[n-4] + 1492*X[n-3] + 1776*X[n-2] + 5115*X[n-1] + C
-     * X[n] = S modulo 2^32
-     * C = floor(S / 2^32)
-     * 
-     */
-    private readonly uint[] mem = new uint[4];
-    private uint c;
-
-    public MarsagliaRandom(uint s) {
-      Seed(s);
-    }
-
-    private uint Next() {
-      unchecked {
-        ulong wsum = 2111111111 * mem[0]
-                    + 1492 * mem[1]
-                    + 1776 * mem[2]
-                    + 5115 * mem[3]
-                    + c;
-
-        mem[0] = mem[1];
-        mem[1] = mem[2];
-        mem[2] = mem[3];
-        mem[3] = (uint)wsum;
-        c = (uint)(wsum >> 32);
-        return mem[3];
-      }
-    }
-
-    public double NextDouble() {
-      return (double)Next() / uint.MaxValue;
-    }
-
-    public void Seed(uint seed) {
-      int i;
-      for (i = 0; i < mem.Length; i++) {
-        unchecked {
-          seed = seed * 31294061 + 1;
-        }
-        mem[i] = seed;
-      }
-      unchecked {
-        c = seed * 31294061 + 1;
-      }
-    }
-  }
-}
Index: /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBHeterogeneousPTSPInstanceProvider.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBHeterogeneousPTSPInstanceProvider.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBHeterogeneousPTSPInstanceProvider.cs	(revision 13470)
@@ -22,9 +22,8 @@
 using System;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 
 namespace HeuristicLab.Problems.Instances.TSPLIB {
-  public class TSPLIBHeterogeneousPTSPInstanceProvider : TSPLIBInstanceProvider<PTSPData> {
+  public class TSPLIBHeterogeneousPTSPInstanceProvider : TSPLIBPTSPInstanceProvider {
 
     public override string Name {
@@ -32,13 +31,6 @@
     }
 
-    public override string Description {
-      get { return "Traveling Salesman Problem Library"; }
-    }
-
-    protected override string FileExtension { get { return "tsp"; } }
-
     public override IEnumerable<IDataDescriptor> GetDataDescriptors() {
       foreach (var desc in base.GetDataDescriptors().OfType<TSPLIBDataDescriptor>()) {
-        desc.Name += " [0.1;0.9]";
         desc.SolutionIdentifier = null;
         yield return desc;
@@ -46,63 +38,66 @@
     }
 
-    protected override PTSPData LoadInstance(TSPLIBParser parser, IDataDescriptor descriptor = null) {
-      parser.Parse();
-      if (parser.FixedEdges != null) throw new InvalidDataException("TSP instance " + parser.Name + " contains fixed edges which are not supported by HeuristicLab.");
-      var instance = new PTSPData();
-      instance.Dimension = parser.Dimension;
-      instance.Coordinates = parser.Vertices != null ? parser.Vertices : parser.DisplayVertices;
-      instance.Distances = parser.Distances;
-      switch (parser.EdgeWeightType) {
-        case TSPLIBEdgeWeightTypes.ATT:
-          instance.DistanceMeasure = DistanceMeasure.Att; break;
-        case TSPLIBEdgeWeightTypes.CEIL_2D:
-          instance.DistanceMeasure = DistanceMeasure.UpperEuclidean; break;
-        case TSPLIBEdgeWeightTypes.EUC_2D:
-          instance.DistanceMeasure = DistanceMeasure.RoundedEuclidean; break;
-        case TSPLIBEdgeWeightTypes.EUC_3D:
-          throw new InvalidDataException("3D coordinates are not supported.");
-        case TSPLIBEdgeWeightTypes.EXPLICIT:
-          instance.DistanceMeasure = DistanceMeasure.Direct; break;
-        case TSPLIBEdgeWeightTypes.GEO:
-          instance.DistanceMeasure = DistanceMeasure.Geo; break;
-        case TSPLIBEdgeWeightTypes.MAN_2D:
-          instance.DistanceMeasure = DistanceMeasure.Manhattan; break;
-        case TSPLIBEdgeWeightTypes.MAN_3D:
-          throw new InvalidDataException("3D coordinates are not supported.");
-        case TSPLIBEdgeWeightTypes.MAX_2D:
-          instance.DistanceMeasure = DistanceMeasure.Maximum; break;
-        case TSPLIBEdgeWeightTypes.MAX_3D:
-          throw new InvalidDataException("3D coordinates are not supported.");
-        default:
-          throw new InvalidDataException("The given edge weight is not supported by HeuristicLab.");
+    protected override double[] GetProbabilities(IDataDescriptor descriptor, PTSPData instance) {
+      var random = new MarsagliaRandom(GetInstanceHash(instance.Name));
+      return Enumerable.Range(0, instance.Dimension).Select(_ => (int)Math.Round((0.1 + 0.9 * random.NextDouble()) * 100) / 100.0).ToArray();
+    }
+
+    // Bernstein's hash function
+    private uint GetInstanceHash(string name) {
+      uint hash = 5381;
+      var len = name.Length;
+      for (var i = 0; i < len; i++)
+        unchecked { hash = ((hash * 33) + name[i]); }
+      return hash;
+    }
+
+    /// <summary>
+    /// This class is used to randomly generate PTSP instances given the TSPLIB instances.
+    /// An own implementation of a RNG was used in order to avoid possible implementation changes
+    /// in future .NET versions which would result in entirely different instances.
+    /// </summary>
+    /// <remarks>
+    /// RNG is implemented according to George Marsaglia https://en.wikipedia.org/wiki/Multiply-with-carry
+    /// </remarks>
+    private class MarsagliaRandom {
+      /*
+       * S = 2111111111*X[n-4] + 1492*X[n-3] + 1776*X[n-2] + 5115*X[n-1] + C
+       * X[n] = S modulo 2^32
+       * C = floor(S / 2^32)
+       * 
+       */
+      private readonly uint[] mem = new uint[4];
+      private uint c;
+
+      public MarsagliaRandom(uint s) {
+        int i;
+        for (i = 0; i < mem.Length; i++) {
+          unchecked { s = s * 31294061 + 1; }
+          mem[i] = s;
+        }
+        unchecked { c = s * 31294061 + 1; }
       }
 
-      instance.Name = parser.Name;
-      instance.Description = parser.Comment
-        + Environment.NewLine + Environment.NewLine
-        + GetInstanceDescription();
+      private uint Next() {
+        unchecked {
+          ulong wsum = 2111111111 * mem[0]
+                      + 1492 * mem[1]
+                      + 1776 * mem[2]
+                      + 5115 * mem[3]
+                      + c;
 
-      var random = new MarsagliaRandom((uint)(descriptor != null ? descriptor.Name : instance.Name).GetHashCode());
-      instance.Probabilities = Enumerable.Range(0, instance.Dimension).Select(_ => 0.1 + 0.9 * random.NextDouble()).ToArray();
+          mem[0] = mem[1];
+          mem[1] = mem[2];
+          mem[2] = mem[3];
+          mem[3] = (uint)wsum;
+          c = (uint)(wsum >> 32);
+          return mem[3];
+        }
+      }
 
-      return instance;
+      public double NextDouble() {
+        return (double)Next() / uint.MaxValue;
+      }
     }
-
-    protected override void LoadSolution(TSPLIBParser parser, PTSPData instance) {
-      parser.Parse();
-      instance.BestKnownTour = parser.Tour.FirstOrDefault();
-    }
-
-    public PTSPData LoadData(string tspFile, string tourFile, double? bestQuality) {
-      var data = LoadInstance(new TSPLIBParser(tspFile));
-      if (!String.IsNullOrEmpty(tourFile)) {
-        var tourParser = new TSPLIBParser(tourFile);
-        LoadSolution(tourParser, data);
-      }
-      if (bestQuality.HasValue)
-        data.BestKnownQuality = bestQuality.Value;
-      return data;
-    }
-
   }
 }
Index: /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBHomogeneousPTSPInstanceProvider.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBHomogeneousPTSPInstanceProvider.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBHomogeneousPTSPInstanceProvider.cs	(revision 13470)
@@ -20,13 +20,11 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.IO;
 using System.Linq;
 
 namespace HeuristicLab.Problems.Instances.TSPLIB {
-  public class TSPLIBHomogeneousPTSPInstanceProvider : TSPLIBInstanceProvider<PTSPData> {
-    private static readonly double[] probabilities = new[] { 0.1, 0.2, 0.4, 0.5, 0.6, 0.8, 0.9, 1.0 };
+  public class TSPLIBHomogeneousPTSPInstanceProvider : TSPLIBPTSPInstanceProvider {
+    private static readonly double[] Probabilities = new[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };
 
     public override string Name {
@@ -34,14 +32,8 @@
     }
 
-    public override string Description {
-      get { return "Traveling Salesman Problem Library"; }
-    }
-
-    protected override string FileExtension { get { return "tsp"; } }
-
     public override IEnumerable<IDataDescriptor> GetDataDescriptors() {
       var tspDescriptors = base.GetDataDescriptors().OfType<TSPLIBDataDescriptor>();
       foreach (var desc in tspDescriptors) {
-        foreach (var p in probabilities) {
+        foreach (var p in Probabilities) {
           yield return new TSPLIBHomogeneousPTSPDataDescriptor(
             desc.Name + "-" + p.ToString(CultureInfo.InvariantCulture.NumberFormat),
@@ -54,63 +46,9 @@
     }
 
-    protected override PTSPData LoadInstance(TSPLIBParser parser, IDataDescriptor descriptor = null) {
-      parser.Parse();
-      if (parser.FixedEdges != null) throw new InvalidDataException("TSP instance " + parser.Name + " contains fixed edges which are not supported by HeuristicLab.");
-      var instance = new PTSPData();
-      instance.Dimension = parser.Dimension;
-      instance.Coordinates = parser.Vertices != null ? parser.Vertices : parser.DisplayVertices;
-      instance.Distances = parser.Distances;
-      switch (parser.EdgeWeightType) {
-        case TSPLIBEdgeWeightTypes.ATT:
-          instance.DistanceMeasure = DistanceMeasure.Att; break;
-        case TSPLIBEdgeWeightTypes.CEIL_2D:
-          instance.DistanceMeasure = DistanceMeasure.UpperEuclidean; break;
-        case TSPLIBEdgeWeightTypes.EUC_2D:
-          instance.DistanceMeasure = DistanceMeasure.RoundedEuclidean; break;
-        case TSPLIBEdgeWeightTypes.EUC_3D:
-          throw new InvalidDataException("3D coordinates are not supported.");
-        case TSPLIBEdgeWeightTypes.EXPLICIT:
-          instance.DistanceMeasure = DistanceMeasure.Direct; break;
-        case TSPLIBEdgeWeightTypes.GEO:
-          instance.DistanceMeasure = DistanceMeasure.Geo; break;
-        case TSPLIBEdgeWeightTypes.MAN_2D:
-          instance.DistanceMeasure = DistanceMeasure.Manhattan; break;
-        case TSPLIBEdgeWeightTypes.MAN_3D:
-          throw new InvalidDataException("3D coordinates are not supported.");
-        case TSPLIBEdgeWeightTypes.MAX_2D:
-          instance.DistanceMeasure = DistanceMeasure.Maximum; break;
-        case TSPLIBEdgeWeightTypes.MAX_3D:
-          throw new InvalidDataException("3D coordinates are not supported.");
-        default:
-          throw new InvalidDataException("The given edge weight is not supported by HeuristicLab.");
-      }
-
-      instance.Name = parser.Name;
-      instance.Description = parser.Comment
-        + Environment.NewLine + Environment.NewLine
-        + GetInstanceDescription();
+    protected override double[] GetProbabilities(IDataDescriptor descriptor, PTSPData instance) {
       var ptspDesc = descriptor as TSPLIBHomogeneousPTSPDataDescriptor;
-      instance.Probabilities = ptspDesc != null ? Enumerable.Range(0, instance.Dimension).Select(_ => ptspDesc.Probability).ToArray()
-                                                : Enumerable.Range(0, instance.Dimension).Select(_ => 0.5).ToArray();
-
-      return instance;
+      return ptspDesc != null ? Enumerable.Range(0, instance.Dimension).Select(_ => ptspDesc.Probability).ToArray()
+                              : Enumerable.Range(0, instance.Dimension).Select(_ => 0.5).ToArray();
     }
-
-    protected override void LoadSolution(TSPLIBParser parser, PTSPData instance) {
-      parser.Parse();
-      instance.BestKnownTour = parser.Tour.FirstOrDefault();
-    }
-
-    public PTSPData LoadData(string tspFile, string tourFile, double? bestQuality) {
-      var data = LoadInstance(new TSPLIBParser(tspFile));
-      if (!String.IsNullOrEmpty(tourFile)) {
-        var tourParser = new TSPLIBParser(tourFile);
-        LoadSolution(tourParser, data);
-      }
-      if (bestQuality.HasValue)
-        data.BestKnownQuality = bestQuality.Value;
-      return data;
-    }
-
   }
 }
Index: /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBPTSPInstanceProvider.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBPTSPInstanceProvider.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBPTSPInstanceProvider.cs	(revision 13470)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.IO;
+using System.Linq;
+
+namespace HeuristicLab.Problems.Instances.TSPLIB {
+  public abstract class TSPLIBPTSPInstanceProvider : TSPLIBInstanceProvider<PTSPData> {
+
+    public override string Description {
+      get { return "Traveling Salesman Problem Library (adapted for generating PTSP instances)"; }
+    }
+
+    protected override string FileExtension { get { return "tsp"; } }
+
+    protected override PTSPData LoadInstance(TSPLIBParser parser, IDataDescriptor descriptor = null) {
+      parser.Parse();
+      if (parser.FixedEdges != null) throw new InvalidDataException("TSP instance " + parser.Name + " contains fixed edges which are not supported by HeuristicLab.");
+      var instance = new PTSPData();
+      instance.Dimension = parser.Dimension;
+      instance.Coordinates = parser.Vertices != null ? parser.Vertices : parser.DisplayVertices;
+      instance.Distances = parser.Distances;
+      switch (parser.EdgeWeightType) {
+        case TSPLIBEdgeWeightTypes.ATT:
+          instance.DistanceMeasure = DistanceMeasure.Att; break;
+        case TSPLIBEdgeWeightTypes.CEIL_2D:
+          instance.DistanceMeasure = DistanceMeasure.UpperEuclidean; break;
+        case TSPLIBEdgeWeightTypes.EUC_2D:
+          instance.DistanceMeasure = DistanceMeasure.RoundedEuclidean; break;
+        case TSPLIBEdgeWeightTypes.EUC_3D:
+          throw new InvalidDataException("3D coordinates are not supported.");
+        case TSPLIBEdgeWeightTypes.EXPLICIT:
+          instance.DistanceMeasure = DistanceMeasure.Direct; break;
+        case TSPLIBEdgeWeightTypes.GEO:
+          instance.DistanceMeasure = DistanceMeasure.Geo; break;
+        case TSPLIBEdgeWeightTypes.MAN_2D:
+          instance.DistanceMeasure = DistanceMeasure.Manhattan; break;
+        case TSPLIBEdgeWeightTypes.MAN_3D:
+          throw new InvalidDataException("3D coordinates are not supported.");
+        case TSPLIBEdgeWeightTypes.MAX_2D:
+          instance.DistanceMeasure = DistanceMeasure.Maximum; break;
+        case TSPLIBEdgeWeightTypes.MAX_3D:
+          throw new InvalidDataException("3D coordinates are not supported.");
+        default:
+          throw new InvalidDataException("The given edge weight is not supported by HeuristicLab.");
+      }
+
+      instance.Name = parser.Name;
+      instance.Description = parser.Comment
+        + Environment.NewLine + Environment.NewLine
+        + GetInstanceDescription();
+
+      instance.Probabilities = GetProbabilities(descriptor, instance);
+      return instance;
+    }
+
+    protected abstract double[] GetProbabilities(IDataDescriptor descriptor, PTSPData instance);
+
+    protected override void LoadSolution(TSPLIBParser parser, PTSPData instance) {
+      parser.Parse();
+      instance.BestKnownTour = parser.Tour.FirstOrDefault();
+    }
+
+    public PTSPData LoadData(string tspFile, string tourFile, double? bestQuality) {
+      var data = LoadInstance(new TSPLIBParser(tspFile));
+      if (!String.IsNullOrEmpty(tourFile)) {
+        var tourParser = new TSPLIBParser(tourFile);
+        LoadSolution(tourParser, data);
+      }
+      if (bestQuality.HasValue)
+        data.BestKnownQuality = bestQuality.Value;
+      return data;
+    }
+
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP.Tests-3.3/HeuristicLab.Problems.PTSP.Tests-3.3.csproj
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP.Tests-3.3/HeuristicLab.Problems.PTSP.Tests-3.3.csproj	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP.Tests-3.3/HeuristicLab.Problems.PTSP.Tests-3.3.csproj	(revision 13470)
@@ -34,4 +34,40 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
Index: /branches/PTSP/HeuristicLab.Problems.PTSP.Tests-3.3/PTSPMoveEvaluatorTest.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP.Tests-3.3/PTSPMoveEvaluatorTest.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP.Tests-3.3/PTSPMoveEvaluatorTest.cs	(revision 13470)
@@ -85,11 +85,13 @@
     [TestProperty("Time", "short")]
     public void InversionMoveEvaluatorTest() {
-      var beforeMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distances, realizations)[0];
+      Func<int, int, double> distance = (a, b) => distances[a, b];
+      double variance;
+      var beforeMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distance, realizations, out variance);
 
       for (var i = 0; i < 500; i++) {
         var move = StochasticInversionSingleMoveGenerator.Apply(tour, random);
-        var moveMatrix = PTSPEstimatedInversionMoveEvaluator.EvaluateByDistanceMatrix(tour, move, distances, realizations);
+        var moveMatrix = PTSPEstimatedInversionMoveEvaluator.EvaluateMove(tour, move, distance, realizations);
         InversionManipulator.Apply(tour, move.Index1, move.Index2);
-        var afterMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distances, realizations)[0];
+        var afterMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distance, realizations, out variance);
 
         Assert.IsTrue(Math.Abs(moveMatrix).IsAlmost(Math.Abs(afterMatrix - beforeMatrix)),
@@ -106,11 +108,12 @@
     [TestProperty("Time", "short")]
     public void InsertionMoveEvaluatorTest() {
-      var beforeMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distances, realizations)[0];
-
+      Func<int, int, double> distance = (a, b) => distances[a, b];
+      double variance;
+      var beforeMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distance, realizations, out variance);
       for (var i = 0; i < 500; i++) {
         var move = StochasticTranslocationSingleMoveGenerator.Apply(tour, random);
-        var moveMatrix = PTSPEstimatedInsertionMoveEvaluator.EvaluateByDistanceMatrix(tour, move, distances, realizations);
+        var moveMatrix = PTSPEstimatedInsertionMoveEvaluator.EvaluateMove(tour, move, distance, realizations);
         TranslocationManipulator.Apply(tour, move.Index1, move.Index1, move.Index3);
-        var afterMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distances, realizations)[0];
+        var afterMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distance, realizations, out variance);
 
         Assert.IsTrue(Math.Abs(moveMatrix).IsAlmost(Math.Abs(afterMatrix - beforeMatrix)),
@@ -122,17 +125,4 @@
       }
     }
-
-    [TestMethod]
-    [TestCategory("Problems.ProbabilisticTravelingSalesman")]
-    [TestProperty("Time", "short")]
-    public void AnalyticalTest() {
-      for (var i = 0; i < 10; i++) {
-        var perm = new Permutation(PermutationTypes.RelativeUndirected, ProblemSize, random);
-        var estimated = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(perm, distances, realizations)[0];
-
-        var analytical = AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(perm, distances, probabilities);
-        Console.WriteLine(Math.Abs(analytical - estimated));
-      }
-    }
   }
 }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/HeuristicLab.Problems.PTSP.Views-3.3.csproj
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/HeuristicLab.Problems.PTSP.Views-3.3.csproj	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/HeuristicLab.Problems.PTSP.Views-3.3.csproj	(revision 13470)
@@ -30,4 +30,40 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
Index: /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/ProbabilisticTravelingSalesmanProblemView.Designer.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/ProbabilisticTravelingSalesmanProblemView.Designer.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/ProbabilisticTravelingSalesmanProblemView.Designer.cs	(revision 13470)
@@ -77,7 +77,7 @@
       // 
       this.tabControl.AllowDrop = true;
-      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-                  | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.tabControl.Controls.Add(this.parametersTabPage);
       this.tabControl.Controls.Add(this.visualizationTabPage);
@@ -112,7 +112,7 @@
       // pathPTSPTourView
       // 
-      this.pathPTSPTourView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-                  | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.pathPTSPTourView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.pathPTSPTourView.Caption = "PathPTSPTour View";
       this.pathPTSPTourView.Content = null;
@@ -123,9 +123,8 @@
       this.pathPTSPTourView.TabIndex = 0;
       // 
-      // TravelingSalesmanProblemView
+      // ProbabilisticTravelingSalesmanProblemView
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
-      this.Name = "TravelingSalesmanProblemView";
+      this.Name = "ProbabilisticTravelingSalesmanProblemView";
       this.problemInstanceSplitContainer.Panel1.ResumeLayout(false);
       this.problemInstanceSplitContainer.Panel1.PerformLayout();
Index: /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/ProbabilisticTravelingSalesmanProblemView.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/ProbabilisticTravelingSalesmanProblemView.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/ProbabilisticTravelingSalesmanProblemView.cs	(revision 13470)
@@ -79,5 +79,7 @@
     private void BestKnownSolutionParameter_ValueChanged(object sender, EventArgs e) {
       pathPTSPTourView.Content.Permutation = Content.BestKnownSolution;
-      pathPTSPTourView.Content.Quality = new DoubleValue(Content.Evaluate(Content.BestKnownSolution, new MersenneTwister()));
+      if (Content.BestKnownSolution != null)
+        pathPTSPTourView.Content.Quality = new DoubleValue(Content.Evaluate(Content.BestKnownSolution, new MersenneTwister(13)));
+      else pathPTSPTourView.Content.Quality = null;
     }
   }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 13470)
@@ -34,3 +34,3 @@
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("3.3.0.0")]
-[assembly: AssemblyFileVersion("3.3.11.$WCREV$")]
+[assembly: AssemblyFileVersion("3.3.13.$WCREV$")]
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/AnalyticalPTSP.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/AnalyticalPTSP.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/AnalyticalPTSP.cs	(revision 13470)
@@ -20,8 +20,11 @@
 #endregion
 
+using System;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -37,4 +40,25 @@
     public AnalyticalProbabilisticTravelingSalesmanProblem() {
       Operators.Add(new BestPTSPSolutionAnalyzer());
+
+      Operators.Add(new PTSPAnalyticalInversionMoveEvaluator());
+      Operators.Add(new PTSPAnalyticalInsertionMoveEvaluator());
+      Operators.Add(new PTSPAnalyticalInversionLocalImprovement());
+      Operators.Add(new PTSPAnalyticalInsertionLocalImprovement());
+      Operators.Add(new PTSPAnalyticalTwoPointFiveLocalImprovement());
+
+      Operators.Add(new ExhaustiveTwoPointFiveMoveGenerator());
+      Operators.Add(new StochasticTwoPointFiveMultiMoveGenerator());
+      Operators.Add(new StochasticTwoPointFiveSingleMoveGenerator());
+      Operators.Add(new TwoPointFiveMoveMaker());
+      Operators.Add(new PTSPAnalyticalTwoPointFiveMoveEvaluator());
+
+      Operators.RemoveAll(x => x is SingleObjectiveMoveGenerator);
+      Operators.RemoveAll(x => x is SingleObjectiveMoveMaker);
+      Operators.RemoveAll(x => x is SingleObjectiveMoveEvaluator);
+
+      Encoding.ConfigureOperators(Operators.OfType<IOperator>());
+      foreach (var twopointfiveMoveOperator in Operators.OfType<ITwoPointFiveMoveOperator>()) {
+        twopointfiveMoveOperator.TwoPointFiveMoveParameter.ActualName = "Permutation.TwoPointFiveMove";
+      }
     }
 
@@ -44,26 +68,32 @@
 
     public override double Evaluate(Permutation tour, IRandom random) {
+      // abeham: Cache in local variable for performance reasons
+      var distanceMatrix = DistanceMatrix;
+      return Evaluate(tour, (a, b) => distanceMatrix[a, b], Probabilities);
+    }
+
+    public static double Evaluate(Permutation tour, Func<int, int, double> distance, DoubleArray probabilities) {
       // Analytical evaluation
-      double firstSum = 0;
-      for (int i = 0; i < tour.Length - 1; i++) {
-        for (int j = i + 1; j < tour.Length - 1; j++) {
-          double sum1 = DistanceMatrix[tour[i], tour[j]] * Probabilities[tour[i]] * Probabilities[tour[j]];
-          for (int k = i + 1; k < j; k++) {
-            sum1 = sum1 * (1 - Probabilities[tour[k]]);
+      var firstSum = 0.0;
+      for (var i = 0; i < tour.Length - 1; i++) {
+        for (var j = i + 1; j < tour.Length; j++) {
+          var prod1 = distance(tour[i], tour[j]) * probabilities[tour[i]] * probabilities[tour[j]];
+          for (var k = i + 1; k < j; k++) {
+            prod1 = prod1 * (1 - probabilities[tour[k]]);
           }
-          firstSum += sum1;
+          firstSum += prod1;
         }
       }
-      double secondSum = 0;
-      for (int j = 0; j < tour.Length - 1; j++) {
-        for (int i = 0; i < j; i++) {
-          double sum2 = DistanceMatrix[tour[j], tour[i]] * Probabilities[tour[i]] * Probabilities[tour[j]];
-          for (int k = j + 1; k < tour.Length - 1; k++) {
-            sum2 = sum2 * (1 - Probabilities[tour[k]]);
+      var secondSum = 0.0;
+      for (var j = 0; j < tour.Length; j++) {
+        for (var i = 0; i < j; i++) {
+          var prod2 = distance(tour[j], tour[i]) * probabilities[tour[i]] * probabilities[tour[j]];
+          for (var k = j + 1; k < tour.Length; k++) {
+            prod2 = prod2 * (1 - probabilities[tour[k]]);
           }
-          for (int k = 1; k < i; k++) {
-            sum2 = sum2 * (1 - Probabilities[tour[k]]);
+          for (var k = 0; k < i; k++) {
+            prod2 = prod2 * (1 - probabilities[tour[k]]);
           }
-          secondSum += sum2;
+          secondSum += prod2;
         }
       }
@@ -72,29 +102,5 @@
 
     public static double Evaluate(Permutation tour, DistanceMatrix distanceMatrix, DoubleArray probabilities) {
-      // Analytical evaluation
-      var firstSum = 0.0;
-      for (var i = 0; i < tour.Length; i++) {
-        for (var j = i + 1; j < tour.Length; j++) {
-          var sum1 = distanceMatrix[tour[i], tour[j]] * probabilities[tour[i]] * probabilities[tour[j]];
-          for (var k = i + 1; k < j; k++) {
-            sum1 = sum1 * (1 - probabilities[tour[k]]);
-          }
-          firstSum += sum1;
-        }
-      }
-      var secondSum = 0.0;
-      for (var j = 0; j < tour.Length; j++) {
-        for (var i = 0; i < j; i++) {
-          var sum2 = distanceMatrix[tour[j], tour[i]] * probabilities[tour[i]] * probabilities[tour[j]];
-          for (var k = j + 1; k < tour.Length; k++) {
-            sum2 = sum2 * (1 - probabilities[tour[k]]);
-          }
-          for (var k = 0; k < i; k++) {
-            sum2 = sum2 * (1 - probabilities[tour[k]]);
-          }
-          secondSum += sum2;
-        }
-      }
-      return firstSum + secondSum;
+      return Evaluate(tour, (a, b) => distanceMatrix[a, b], probabilities);
     }
   }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs	(revision 13470)
@@ -26,4 +26,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -72,6 +73,7 @@
       Operators.Add(new PTSPEstimatedInversionMoveEvaluator());
       Operators.Add(new PTSPEstimatedInsertionMoveEvaluator());
-      Operators.Add(new PTSPExhaustiveInversionLocalImprovement());
-      Operators.Add(new PTSPExhaustiveInsertionLocalImprovement());
+      Operators.Add(new PTSPEstimatedInversionLocalImprovement());
+      Operators.Add(new PTSPEstimatedInsertionLocalImprovement());
+      Operators.Add(new PTSPEstimatedTwoPointFiveLocalImprovement());
 
       Operators.Add(new ExhaustiveTwoPointFiveMoveGenerator());
@@ -79,5 +81,9 @@
       Operators.Add(new StochasticTwoPointFiveSingleMoveGenerator());
       Operators.Add(new TwoPointFiveMoveMaker());
-      Operators.Add(new PTSPTwoPointFiveMoveEvaluator());
+      Operators.Add(new PTSPEstimatedTwoPointFiveMoveEvaluator());
+
+      Operators.RemoveAll(x => x is SingleObjectiveMoveGenerator);
+      Operators.RemoveAll(x => x is SingleObjectiveMoveMaker);
+      Operators.RemoveAll(x => x is SingleObjectiveMoveEvaluator);
 
       Encoding.ConfigureOperators(Operators.OfType<IOperator>());
@@ -86,4 +92,5 @@
       }
 
+      UpdateRealizations();
       RegisterEventHandlers();
     }
@@ -107,12 +114,20 @@
 
     public override double Evaluate(Permutation tour, IRandom random) {
-      // Estimation-based evaluation
+      // abeham: Cache parameters in local variables for performance reasons
+      var realizations = Realizations;
+      var realizationsSize = RealizationsSize;
+      var useDistanceMatrix = UseDistanceMatrix;
+      var distanceMatrix = DistanceMatrix;
+      var distanceCalculator = DistanceCalculator;
+      var coordinates = Coordinates;
+
+      // Estimation-based evaluation, here without calculating variance for faster evaluation
       var estimatedSum = 0.0;
-      for (var i = 0; i < Realizations.Count; i++) {
+      for (var i = 0; i < realizations.Count; i++) {
         int singleRealization = -1, firstNode = -1;
-        for (var j = 0; j < Realizations[i].Length; j++) {
-          if (Realizations[i][tour[j]]) {
+        for (var j = 0; j < realizations[i].Length; j++) {
+          if (realizations[i][tour[j]]) {
             if (singleRealization != -1) {
-              estimatedSum += GetDistance(singleRealization, tour[j]);
+              estimatedSum += useDistanceMatrix ? distanceMatrix[singleRealization, tour[j]] : distanceCalculator.Calculate(singleRealization, tour[j], coordinates);
             } else {
               firstNode = tour[j];
@@ -122,8 +137,8 @@
         }
         if (singleRealization != -1) {
-          estimatedSum += GetDistance(singleRealization, firstNode);
-        }
-      }
-      return estimatedSum / RealizationsSize;
+          estimatedSum += useDistanceMatrix ? distanceMatrix[singleRealization, firstNode] : distanceCalculator.Calculate(singleRealization, firstNode, coordinates);
+        }
+      }
+      return estimatedSum / realizationsSize;
     }
 
@@ -134,6 +149,19 @@
     /// <param name="distanceMatrix">The distances between the cities.</param>
     /// <param name="realizations">A sample of realizations of the stochastic instance</param>
+    /// <param name="variance">The estimated variance will be returned in addition to the mean.</param>
     /// <returns>A vector with length two containing mean and variance.</returns>
-    public static double[] Evaluate(Permutation tour, DistanceMatrix distanceMatrix, ItemList<BoolArray> realizations) {
+    public static double Evaluate(Permutation tour, DistanceMatrix distanceMatrix, ItemList<BoolArray> realizations, out double variance) {
+      return Evaluate(tour, (a, b) => distanceMatrix[a, b], realizations, out variance);
+    }
+
+    /// <summary>
+    /// An evaluate method that can be used if mean as well as variance should be calculated
+    /// </summary>
+    /// <param name="tour">The tour between all cities.</param>
+    /// <param name="distance">A func that accepts the index of two cities and returns the distance as a double.</param>
+    /// <param name="realizations">A sample of realizations of the stochastic instance</param>
+    /// <param name="variance">The estimated variance will be returned in addition to the mean.</param>
+    /// <returns>A vector with length two containing mean and variance.</returns>
+    public static double Evaluate(Permutation tour, Func<int, int, double> distance, ItemList<BoolArray> realizations, out double variance) {
       // Estimation-based evaluation
       var estimatedSum = 0.0;
@@ -145,5 +173,5 @@
           if (realizations[i][tour[j]]) {
             if (singleRealization != -1) {
-              partialSums[i] += distanceMatrix[singleRealization, tour[j]];
+              partialSums[i] += distance(singleRealization, tour[j]);
             } else {
               firstNode = tour[j];
@@ -153,20 +181,24 @@
         }
         if (singleRealization != -1) {
-          partialSums[i] += distanceMatrix[singleRealization, firstNode];
+          partialSums[i] += distance(singleRealization, firstNode);
         }
         estimatedSum += partialSums[i];
       }
       var mean = estimatedSum / realizations.Count;
-      var variance = 0.0;
+      variance = 0.0;
       for (var i = 0; i < realizations.Count; i++) {
         variance += Math.Pow((partialSums[i] - mean), 2);
       }
       variance = variance / realizations.Count;
-      return new[] { mean, variance };
-    }
-
-    public double GetDistance(int from, int to) {
-      if (UseDistanceMatrix) return DistanceMatrix[from, to];
-      return DistanceCalculator.Calculate(from, to, Coordinates);
+      return mean;
+    }
+
+    public override void Load(PTSPData data) {
+      base.Load(data);
+      UpdateRealizations();
+
+      foreach (var op in Operators.OfType<IEstimatedPTSPOperator>()) {
+        op.RealizationsParameter.ActualName = RealizationsParameter.Name;
+      }
     }
 
@@ -177,5 +209,5 @@
         var newRealization = new BoolArray(Probabilities.Length);
         var countOnes = 0;
-        while (countOnes < 4) { // only generate realizations with at least 4 cities visited
+        do {
           countOnes = 0;
           for (var j = 0; j < Probabilities.Length; j++) {
@@ -183,17 +215,9 @@
             if (newRealization[j]) countOnes++;
           }
-        }
-        Realizations.Add(newRealization);
+          // only generate realizations with at least 4 cities visited
+        } while (countOnes < 4 && Probabilities.Length > 3);
+        realizations.Add(newRealization);
       }
       Realizations = realizations;
-    }
-
-    public override void Load(PTSPData data) {
-      base.Load(data);
-      UpdateRealizations();
-
-      foreach (var op in Operators.OfType<IEstimatedPTSPOperator>()) {
-        op.RealizationsParameter.ActualName = RealizationsParameter.Name;
-      }
     }
   }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/HeuristicLab.Problems.PTSP-3.3.csproj
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/HeuristicLab.Problems.PTSP-3.3.csproj	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/HeuristicLab.Problems.PTSP-3.3.csproj	(revision 13470)
@@ -36,4 +36,40 @@
   <PropertyGroup>
     <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
@@ -123,13 +159,23 @@
     <Compile Include="DistanceMatrix.cs" />
     <Compile Include="EstimatedPTSP.cs" />
-    <Compile Include="Improvers\PTSPExhaustiveInsertionLocalImprovement.cs" />
-    <Compile Include="Improvers\PTSPExhaustiveInversionLocalImprovement.cs" />
+    <Compile Include="Improvers\PTSPAnalyticalInsertionLocalImprovement.cs" />
+    <Compile Include="Improvers\PTSPAnalyticalTwoPointFiveLocalImprovement.cs" />
+    <Compile Include="Improvers\PTSPEstimatedInsertionLocalImprovement.cs" />
+    <Compile Include="Improvers\PTSPAnalyticalInversionLocalImprovement.cs" />
+    <Compile Include="Improvers\PTSPEstimatedTwoPointFiveLocalImprovement.cs" />
+    <Compile Include="Improvers\PTSPEstimatedInversionLocalImprovement.cs" />
+    <Compile Include="Interfaces\IAnalyticalPTSPMoveEvaluator.cs" />
+    <Compile Include="Interfaces\IAnalyticalPTSPOperator.cs" />
     <Compile Include="Interfaces\IEstimatedPTSPOperator.cs" />
     <Compile Include="Interfaces\ITwoPointFiveMoveOperator.cs" />
     <Compile Include="Interfaces\IEstimatedPTSPMoveEvaluator.cs" />
+    <Compile Include="Moves\AnalyticalPTSPMoveEvaluator.cs" />
+    <Compile Include="Moves\OneShift\PTSPAnalyticalInsertionMoveEvaluator.cs" />
     <Compile Include="Moves\OneShift\PTSPEstimatedInsertionMoveEvaluator.cs" />
     <Compile Include="Moves\EstimatedPTSPMoveEvaluator.cs" />
+    <Compile Include="Moves\TwoOpt\PTSPAnalyticalInversionMoveEvaluator.cs" />
     <Compile Include="Moves\TwoOpt\PTSPEstimatedInversionMoveEvaluator.cs" />
-    <Compile Include="Moves\TwoPointFiveOpt\PTSPTwoPointFiveMoveEvaluator.cs" />
+    <Compile Include="Moves\TwoPointFiveOpt\PTSPAnalyticalTwoPointFiveMoveEvaluator.cs" />
+    <Compile Include="Moves\TwoPointFiveOpt\PTSPEstimatedTwoPointFiveMoveEvaluator.cs" />
     <Compile Include="Moves\TwoPointFiveOpt\ExhaustiveTwoPointFiveMoveGenerator.cs" />
     <Compile Include="Moves\TwoPointFiveOpt\StochasticTwoPointFiveMultiMoveGenerator.cs" />
@@ -158,7 +204,12 @@
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
-set Outdir=$(Outdir)
 
 call PreBuildEvent.cmd</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+      export ProjectDir=$(ProjectDir)
+      export SolutionDir=$(SolutionDir)
+
+      $SolutionDir/PreBuildEvent.sh
+    </PreBuildEvent>
   </PropertyGroup>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInsertionLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInsertionLocalImprovement.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInsertionLocalImprovement.cs	(revision 13470)
@@ -0,0 +1,145 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  /// <summary>
+  /// An operator that improves probabilistic traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator tries to improve the probabilistic traveling salesman solution by inserting a city in the tour between two other cities for a certain number of times.
+  /// </remarks>
+  [Item("PTSP Analytical Insertion Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
+  [StorableClass]
+  public sealed class PTSPAnalyticalInsertionLocalImprovement : SingleSuccessorOperator, IAnalyticalPTSPOperator, ILocalImprovementOperator {
+
+    public ILookupParameter<IntValue> LocalIterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
+    }
+
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    }
+
+    [StorableConstructor]
+    private PTSPAnalyticalInsertionLocalImprovement(bool deserializing) : base(deserializing) { }
+    private PTSPAnalyticalInsertionLocalImprovement(PTSPAnalyticalInsertionLocalImprovement original, Cloner cloner) : base(original, cloner) { }
+    public PTSPAnalyticalInsertionLocalImprovement()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities of the cities to appear."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPAnalyticalInsertionLocalImprovement(this, cloner);
+    }
+
+    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation) {
+      var distanceM = (DistanceMatrix)distances;
+      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+      for (var i = localIterations.Value; i < maxIterations; i++) {
+        TranslocationMove bestMove = null;
+        var bestQuality = quality.Value; // we have to make an improvement, so current quality is the baseline
+        var evaluations = 0.0;
+        foreach (var move in ExhaustiveInsertionMoveGenerator.Generate(assignment)) {
+          var moveQuality = PTSPAnalyticalInsertionMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
+          evaluations++;
+          if (maximization && moveQuality > bestQuality
+            || !maximization && moveQuality < bestQuality) {
+            bestQuality = moveQuality;
+            bestMove = move;
+          }
+        }
+        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
+        if (bestMove == null) break;
+        TranslocationManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2, bestMove.Index3);
+        quality.Value = bestQuality;
+        localIterations.Value++;
+        cancellation.ThrowIfCancellationRequested();
+      }
+    }
+
+    public override IOperation Apply() {
+      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
+      var assignment = PermutationParameter.ActualValue;
+      var maximization = MaximizationParameter.ActualValue.Value;
+      var distances = DistanceMatrixParameter.ActualValue;
+      var quality = QualityParameter.ActualValue;
+      var localIterations = LocalIterationsParameter.ActualValue;
+      var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var probabilities = ProbabilitiesParameter.ActualValue;
+      if (localIterations == null) {
+        localIterations = new IntValue(0);
+        LocalIterationsParameter.ActualValue = localIterations;
+      }
+
+      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, probabilities, CancellationToken);
+
+      localIterations.Value = 0;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInversionLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInversionLocalImprovement.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInversionLocalImprovement.cs	(revision 13470)
@@ -0,0 +1,145 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  /// <summary>
+  /// An operator that improves probabilistic traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.
+  /// </remarks>
+  [Item("PTSP Analytical Inversion Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
+  [StorableClass]
+  public sealed class PTSPAnalyticalInversionLocalImprovement : SingleSuccessorOperator, IAnalyticalPTSPOperator, ILocalImprovementOperator {
+
+    public ILookupParameter<IntValue> LocalIterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
+    }
+
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    }
+
+    [StorableConstructor]
+    private PTSPAnalyticalInversionLocalImprovement(bool deserializing) : base(deserializing) { }
+    private PTSPAnalyticalInversionLocalImprovement(PTSPAnalyticalInversionLocalImprovement original, Cloner cloner) : base(original, cloner) { }
+    public PTSPAnalyticalInversionLocalImprovement()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities of the cities to appear."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPAnalyticalInversionLocalImprovement(this, cloner);
+    }
+
+    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation) {
+      var distanceM = (DistanceMatrix)distances;
+      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+      for (var i = localIterations.Value; i < maxIterations; i++) {
+        InversionMove bestMove = null;
+        var bestQuality = quality.Value; // we have to make an improvement, so current quality is the baseline
+        var evaluations = 0.0;
+        foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment)) {
+          var moveQuality = PTSPAnalyticalInversionMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
+          evaluations++;
+          if (maximization && moveQuality > bestQuality
+            || !maximization && moveQuality < bestQuality) {
+            bestQuality = moveQuality;
+            bestMove = move;
+          }
+        }
+        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
+        if (bestMove == null) break;
+        InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2);
+        quality.Value = bestQuality;
+        localIterations.Value++;
+        cancellation.ThrowIfCancellationRequested();
+      }
+    }
+
+    public override IOperation Apply() {
+      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
+      var assignment = PermutationParameter.ActualValue;
+      var maximization = MaximizationParameter.ActualValue.Value;
+      var distances = DistanceMatrixParameter.ActualValue;
+      var quality = QualityParameter.ActualValue;
+      var localIterations = LocalIterationsParameter.ActualValue;
+      var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var probabilities = ProbabilitiesParameter.ActualValue;
+      if (localIterations == null) {
+        localIterations = new IntValue(0);
+        LocalIterationsParameter.ActualValue = localIterations;
+      }
+
+      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, probabilities, CancellationToken);
+
+      localIterations.Value = 0;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalTwoPointFiveLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalTwoPointFiveLocalImprovement.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalTwoPointFiveLocalImprovement.cs	(revision 13470)
@@ -0,0 +1,145 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  /// <summary>
+  /// An operator that improves probabilistic traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.
+  /// </remarks>
+  [Item("PTSP Analytical 2.5 Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
+  [StorableClass]
+  public sealed class PTSPAnalyticalTwoPointFiveLocalImprovement : SingleSuccessorOperator, IAnalyticalPTSPOperator, ILocalImprovementOperator {
+
+    public ILookupParameter<IntValue> LocalIterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
+    }
+
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    }
+
+    [StorableConstructor]
+    private PTSPAnalyticalTwoPointFiveLocalImprovement(bool deserializing) : base(deserializing) { }
+    private PTSPAnalyticalTwoPointFiveLocalImprovement(PTSPAnalyticalTwoPointFiveLocalImprovement original, Cloner cloner) : base(original, cloner) { }
+    public PTSPAnalyticalTwoPointFiveLocalImprovement()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities of the cities to appear."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPAnalyticalTwoPointFiveLocalImprovement(this, cloner);
+    }
+
+    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation) {
+      var distanceM = (DistanceMatrix)distances;
+      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+      for (var i = localIterations.Value; i < maxIterations; i++) {
+        TwoPointFiveMove bestMove = null;
+        var bestQuality = quality.Value; // we have to make an improvement, so current quality is the baseline
+        var evaluations = 0.0;
+        foreach (var move in ExhaustiveTwoPointFiveMoveGenerator.Generate(assignment)) {
+          var moveQuality = PTSPAnalyticalTwoPointFiveMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
+          evaluations++;
+          if (maximization && moveQuality > bestQuality
+            || !maximization && moveQuality < bestQuality) {
+            bestQuality = moveQuality;
+            bestMove = move;
+          }
+        }
+        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
+        if (bestMove == null) break;
+        TwoPointFiveMoveMaker.Apply(assignment, bestMove);
+        quality.Value = bestQuality;
+        localIterations.Value++;
+        cancellation.ThrowIfCancellationRequested();
+      }
+    }
+
+    public override IOperation Apply() {
+      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
+      var assignment = PermutationParameter.ActualValue;
+      var maximization = MaximizationParameter.ActualValue.Value;
+      var distances = DistanceMatrixParameter.ActualValue;
+      var quality = QualityParameter.ActualValue;
+      var localIterations = LocalIterationsParameter.ActualValue;
+      var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var probabilities = ProbabilitiesParameter.ActualValue;
+      if (localIterations == null) {
+        localIterations = new IntValue(0);
+        LocalIterationsParameter.ActualValue = localIterations;
+      }
+
+      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, probabilities, CancellationToken);
+
+      localIterations.Value = 0;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInsertionLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInsertionLocalImprovement.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInsertionLocalImprovement.cs	(revision 13470)
@@ -0,0 +1,145 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  /// <summary>
+  /// An operator that improves probabilistic traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator tries to improve the probabilistic traveling salesman solution by inserting a city in the tour between two other cities for a certain number of times.
+  /// </remarks>
+  [Item("PTSP Estimated Insertion Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
+  [StorableClass]
+  public sealed class PTSPEstimatedInsertionLocalImprovement : SingleSuccessorOperator, IEstimatedPTSPOperator, ILocalImprovementOperator {
+
+    public ILookupParameter<IntValue> LocalIterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
+    }
+
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
+      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
+    }
+
+    [StorableConstructor]
+    private PTSPEstimatedInsertionLocalImprovement(bool deserializing) : base(deserializing) { }
+    private PTSPEstimatedInsertionLocalImprovement(PTSPEstimatedInsertionLocalImprovement original, Cloner cloner) : base(original, cloner) { }
+    public PTSPEstimatedInsertionLocalImprovement()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPEstimatedInsertionLocalImprovement(this, cloner);
+    }
+
+    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, ItemList<BoolArray> realizations, CancellationToken cancellation) {
+      var distanceM = (DistanceMatrix)distances;
+      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+      for (var i = localIterations.Value; i < maxIterations; i++) {
+        TranslocationMove bestMove = null;
+        double bestQuality = 0; // we have to make an improvement, so 0 is the baseline
+        double evaluations = 0.0;
+        foreach (var move in ExhaustiveInsertionMoveGenerator.Generate(assignment)) {
+          double moveQuality = PTSPEstimatedInsertionMoveEvaluator.EvaluateMove(assignment, move, distance, realizations);
+          evaluations += realizations.Count * 6.0 / (assignment.Length * assignment.Length);
+          if (maximization && moveQuality > bestQuality
+            || !maximization && moveQuality < bestQuality) {
+            bestQuality = moveQuality;
+            bestMove = move;
+          }
+        }
+        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
+        if (bestMove == null) break;
+        TranslocationManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2, bestMove.Index3);
+        quality.Value += bestQuality;
+        localIterations.Value++;
+        cancellation.ThrowIfCancellationRequested();
+      }
+    }
+
+    public override IOperation Apply() {
+      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
+      var assignment = PermutationParameter.ActualValue;
+      var maximization = MaximizationParameter.ActualValue.Value;
+      var distances = DistanceMatrixParameter.ActualValue;
+      var quality = QualityParameter.ActualValue;
+      var localIterations = LocalIterationsParameter.ActualValue;
+      var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var realizations = RealizationsParameter.ActualValue;
+      if (localIterations == null) {
+        localIterations = new IntValue(0);
+        LocalIterationsParameter.ActualValue = localIterations;
+      }
+
+      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
+
+      localIterations.Value = 0;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInversionLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInversionLocalImprovement.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInversionLocalImprovement.cs	(revision 13470)
@@ -0,0 +1,145 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  /// <summary>
+  /// An operator that improves probabilistic traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.
+  /// </remarks>
+  [Item("PTSP Estimated Inversion Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
+  [StorableClass]
+  public sealed class PTSPEstimatedInversionLocalImprovement : SingleSuccessorOperator, IEstimatedPTSPOperator, ILocalImprovementOperator {
+
+    public ILookupParameter<IntValue> LocalIterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
+    }
+
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
+      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
+    }
+
+    [StorableConstructor]
+    private PTSPEstimatedInversionLocalImprovement(bool deserializing) : base(deserializing) { }
+    private PTSPEstimatedInversionLocalImprovement(PTSPEstimatedInversionLocalImprovement original, Cloner cloner) : base(original, cloner) { }
+    public PTSPEstimatedInversionLocalImprovement()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPEstimatedInversionLocalImprovement(this, cloner);
+    }
+
+    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, ItemList<BoolArray> realizations, CancellationToken cancellation) {
+      var distanceM = (DistanceMatrix)distances;
+      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+      for (var i = localIterations.Value; i < maxIterations; i++) {
+        InversionMove bestMove = null;
+        double bestQuality = 0; // we have to make an improvement, so 0 is the baseline
+        double evaluations = 0.0;
+        foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment)) {
+          double moveQuality = PTSPEstimatedInversionMoveEvaluator.EvaluateMove(assignment, move, distance, realizations);
+          evaluations += realizations.Count * 4.0 / (assignment.Length * assignment.Length);
+          if (maximization && moveQuality > bestQuality
+            || !maximization && moveQuality < bestQuality) {
+            bestQuality = moveQuality;
+            bestMove = move;
+          }
+        }
+        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
+        if (bestMove == null) break;
+        InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2);
+        quality.Value += bestQuality;
+        localIterations.Value++;
+        cancellation.ThrowIfCancellationRequested();
+      }
+    }
+
+    public override IOperation Apply() {
+      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
+      var assignment = PermutationParameter.ActualValue;
+      var maximization = MaximizationParameter.ActualValue.Value;
+      var distances = DistanceMatrixParameter.ActualValue;
+      var quality = QualityParameter.ActualValue;
+      var localIterations = LocalIterationsParameter.ActualValue;
+      var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var realizations = RealizationsParameter.ActualValue;
+      if (localIterations == null) {
+        localIterations = new IntValue(0);
+        LocalIterationsParameter.ActualValue = localIterations;
+      }
+
+      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
+
+      localIterations.Value = 0;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedTwoPointFiveLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedTwoPointFiveLocalImprovement.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedTwoPointFiveLocalImprovement.cs	(revision 13470)
@@ -0,0 +1,146 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  /// <summary>
+  /// An operator that improves probabilistic traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.
+  /// </remarks>
+  [Item("PTSP Estimated 2.5 Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
+  [StorableClass]
+  public sealed class PTSPEstimatedTwoPointFiveLocalImprovement : SingleSuccessorOperator, IEstimatedPTSPOperator, ILocalImprovementOperator {
+
+    public ILookupParameter<IntValue> LocalIterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
+    }
+
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
+      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
+    }
+
+    [StorableConstructor]
+    private PTSPEstimatedTwoPointFiveLocalImprovement(bool deserializing) : base(deserializing) { }
+    private PTSPEstimatedTwoPointFiveLocalImprovement(PTSPEstimatedTwoPointFiveLocalImprovement original, Cloner cloner) : base(original, cloner) { }
+    public PTSPEstimatedTwoPointFiveLocalImprovement()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPEstimatedTwoPointFiveLocalImprovement(this, cloner);
+    }
+
+    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, ItemList<BoolArray> realizations, CancellationToken cancellation) {
+      var distanceM = (DistanceMatrix)distances;
+      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+      for (var i = localIterations.Value; i < maxIterations; i++) {
+        TwoPointFiveMove bestMove = null;
+        var bestQuality = 0.0; // we have to make an improvement, so 0 is the baseline
+        var evaluations = 0.0;
+        foreach (var move in ExhaustiveTwoPointFiveMoveGenerator.Generate(assignment)) {
+          var moveQuality = PTSPEstimatedTwoPointFiveMoveEvaluator.EvaluateMove(assignment, move, distance, realizations);
+          if (move.IsInvert) evaluations += realizations.Count * 4.0 / (assignment.Length * assignment.Length);
+          else evaluations += realizations.Count * 6.0 / (assignment.Length * assignment.Length);
+          if (maximization && moveQuality > bestQuality
+            || !maximization && moveQuality < bestQuality) {
+            bestQuality = moveQuality;
+            bestMove = move;
+          }
+        }
+        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
+        if (bestMove == null) break;
+        TwoPointFiveMoveMaker.Apply(assignment, bestMove);
+        quality.Value += bestQuality;
+        localIterations.Value++;
+        cancellation.ThrowIfCancellationRequested();
+      }
+    }
+
+    public override IOperation Apply() {
+      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
+      var assignment = PermutationParameter.ActualValue;
+      var maximization = MaximizationParameter.ActualValue.Value;
+      var distances = DistanceMatrixParameter.ActualValue;
+      var quality = QualityParameter.ActualValue;
+      var localIterations = LocalIterationsParameter.ActualValue;
+      var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var realizations = RealizationsParameter.ActualValue;
+      if (localIterations == null) {
+        localIterations = new IntValue(0);
+        LocalIterationsParameter.ActualValue = localIterations;
+      }
+
+      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
+
+      localIterations.Value = 0;
+      return base.Apply();
+    }
+  }
+}
Index: anches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPExhaustiveInsertionLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPExhaustiveInsertionLocalImprovement.cs	(revision 13469)
+++ 	(revision )
@@ -1,147 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Threading;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.PTSP {
-  /// <summary>
-  /// An operator that improves probabilistic traveling salesman solutions.
-  /// </summary>
-  /// <remarks>
-  /// The operator tries to improve the probabilistic traveling salesman solution by inserting a city in the tour between two other cities for a certain number of times.
-  /// </remarks>
-  [Item("PTSPExhaustiveInsertionLocalImprovement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
-  [StorableClass]
-  public sealed class PTSPExhaustiveInsertionLocalImprovement : SingleSuccessorOperator, IEstimatedPTSPOperator, ILocalImprovementOperator {
-
-    public ILookupParameter<IntValue> LocalIterationsParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
-    }
-
-    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
-    }
-
-    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
-    }
-
-    public ILookupParameter<ResultCollection> ResultsParameter {
-      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
-    }
-
-    public ILookupParameter<Permutation> PermutationParameter {
-      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
-    }
-
-    public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-
-    public ILookupParameter<BoolValue> MaximizationParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-
-    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
-      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
-    }
-
-    [StorableConstructor]
-    private PTSPExhaustiveInsertionLocalImprovement(bool deserializing) : base(deserializing) { }
-    private PTSPExhaustiveInsertionLocalImprovement(PTSPExhaustiveInsertionLocalImprovement original, Cloner cloner) : base(original, cloner) { }
-    public PTSPExhaustiveInsertionLocalImprovement()
-      : base() {
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
-      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
-      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PTSPExhaustiveInsertionLocalImprovement(this, cloner);
-    }
-
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, CancellationToken cancellation, ItemList<BoolArray> realizations) {
-      var distanceM = (DistanceMatrix)distances;
-      for (var i = localIterations.Value; i < maxIterations; i++) {
-        TranslocationMove bestMove = null;
-        double bestQuality = 0; // we have to make an improvement, so 0 is the baseline
-        double evaluations = 0.0;
-        foreach (var move in ExhaustiveInsertionMoveGenerator.Generate(assignment)) {
-          double moveQuality = PTSPEstimatedInsertionMoveEvaluator.EvaluateByDistanceMatrix(assignment, move, distanceM, realizations);
-          int min = Math.Min(move.Index1, move.Index3);
-          int max = Math.Max(move.Index2, move.Index3 + (move.Index2 - move.Index1));
-          evaluations += 2.0 * (max - min + 1) / assignment.Length
-            + 4.0 * (assignment.Length - (max - min + 1)) / assignment.Length;
-          if (maximization && moveQuality > bestQuality
-            || !maximization && moveQuality < bestQuality) {
-            bestQuality = moveQuality;
-            bestMove = move;
-          }
-        }
-        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
-        if (bestMove == null) break;
-        TranslocationManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2, bestMove.Index3);
-        quality.Value += bestQuality;
-        localIterations.Value++;
-        cancellation.ThrowIfCancellationRequested();
-      }
-    }
-
-    public override IOperation Apply() {
-      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
-      var assignment = PermutationParameter.ActualValue;
-      var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
-      var quality = QualityParameter.ActualValue;
-      var localIterations = LocalIterationsParameter.ActualValue;
-      var evaluations = EvaluatedSolutionsParameter.ActualValue;
-      var realizations = RealizationsParameter.ActualValue;
-      if (localIterations == null) {
-        localIterations = new IntValue(0);
-        LocalIterationsParameter.ActualValue = localIterations;
-      }
-
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, CancellationToken, realizations);
-
-      localIterations.Value = 0;
-      return base.Apply();
-    }
-  }
-}
Index: anches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPExhaustiveInversionLocalImprovement.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPExhaustiveInversionLocalImprovement.cs	(revision 13469)
+++ 	(revision )
@@ -1,144 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Threading;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.PTSP {
-  /// <summary>
-  /// An operator that improves probabilistic traveling salesman solutions.
-  /// </summary>
-  /// <remarks>
-  /// The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.
-  /// </remarks>
-  [Item("PTSPExhaustiveInversionLocalImprovement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
-  [StorableClass]
-  public sealed class PTSPExhaustiveInversionLocalImprovement : SingleSuccessorOperator, IEstimatedPTSPOperator, ILocalImprovementOperator {
-
-    public ILookupParameter<IntValue> LocalIterationsParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["LocalIterations"]; }
-    }
-
-    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
-    }
-
-    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
-    }
-
-    public ILookupParameter<ResultCollection> ResultsParameter {
-      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
-    }
-
-    public ILookupParameter<Permutation> PermutationParameter {
-      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
-    }
-
-    public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-
-    public ILookupParameter<BoolValue> MaximizationParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-
-    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
-      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
-    }
-
-    [StorableConstructor]
-    private PTSPExhaustiveInversionLocalImprovement(bool deserializing) : base(deserializing) { }
-    private PTSPExhaustiveInversionLocalImprovement(PTSPExhaustiveInversionLocalImprovement original, Cloner cloner) : base(original, cloner) { }
-    public PTSPExhaustiveInversionLocalImprovement()
-      : base() {
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum amount of iterations that should be performed (note that this operator will abort earlier when a local optimum is reached).", new IntValue(10000)));
-      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The amount of evaluated solutions (here a move is counted only as 4/n evaluated solutions with n being the length of the permutation)."));
-      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The collection where to store results."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PTSPExhaustiveInversionLocalImprovement(this, cloner);
-    }
-
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, CancellationToken cancellation, ItemList<BoolArray> realizations) {
-      var distanceM = (DistanceMatrix)distances;
-      for (var i = localIterations.Value; i < maxIterations; i++) {
-        InversionMove bestMove = null;
-        double bestQuality = 0; // we have to make an improvement, so 0 is the baseline
-        double evaluations = 0.0;
-        foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment)) {
-          double moveQuality = PTSPEstimatedInversionMoveEvaluator.EvaluateByDistanceMatrix(assignment, move, distanceM, realizations);
-          evaluations += 2 * (move.Index2 - move.Index1 + 1) / (double)assignment.Length;
-          if (maximization && moveQuality > bestQuality
-            || !maximization && moveQuality < bestQuality) {
-            bestQuality = moveQuality;
-            bestMove = move;
-          }
-        }
-        evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
-        if (bestMove == null) break;
-        InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2);
-        quality.Value += bestQuality;
-        localIterations.Value++;
-        cancellation.ThrowIfCancellationRequested();
-      }
-    }
-
-    public override IOperation Apply() {
-      var maxIterations = MaximumIterationsParameter.ActualValue.Value;
-      var assignment = PermutationParameter.ActualValue;
-      var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
-      var quality = QualityParameter.ActualValue;
-      var localIterations = LocalIterationsParameter.ActualValue;
-      var evaluations = EvaluatedSolutionsParameter.ActualValue;
-      var realizations = RealizationsParameter.ActualValue;
-      if (localIterations == null) {
-        localIterations = new IntValue(0);
-        LocalIterationsParameter.ActualValue = localIterations;
-      }
-
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, CancellationToken, realizations);
-
-      localIterations.Value = 0;
-      return base.Apply();
-    }
-  }
-}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPMoveEvaluator.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPMoveEvaluator.cs	(revision 13470)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.PTSP {
+  public interface IAnalyticalPTSPMoveEvaluator : IAnalyticalPTSPOperator, ISingleObjectiveMoveEvaluator, IPermutationMoveOperator {
+    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
+    ILookupParameter<DistanceCalculator> DistanceCalculatorParameter { get; }
+    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
+    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPOperator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPOperator.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPOperator.cs	(revision 13470)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.PTSP {
+  public interface IAnalyticalPTSPOperator : IItem {
+    ILookupParameter<DoubleArray> ProbabilitiesParameter { get; }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPMoveEvaluator.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPMoveEvaluator.cs	(revision 13470)
@@ -28,4 +28,5 @@
   public interface IEstimatedPTSPMoveEvaluator : IEstimatedPTSPOperator, ISingleObjectiveMoveEvaluator, IPermutationMoveOperator {
     ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
+    ILookupParameter<DistanceCalculator> DistanceCalculatorParameter { get; }
     ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
     ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/AnalyticalPTSPMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/AnalyticalPTSPMoveEvaluator.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/AnalyticalPTSPMoveEvaluator.cs	(revision 13470)
@@ -0,0 +1,106 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  [Item("AnalyticalPTSPMoveEvaluator", "A base class for operators which evaluate PTSP moves.")]
+  [StorableClass]
+  public abstract class AnalyticalPTSPMoveEvaluator : SingleSuccessorOperator, IAnalyticalPTSPMoveEvaluator {
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
+    }
+    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<DistanceCalculator> DistanceCalculatorParameter {
+      get { return (ILookupParameter<DistanceCalculator>)Parameters["DistanceCalculator"]; }
+    }
+
+    [StorableConstructor]
+    protected AnalyticalPTSPMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected AnalyticalPTSPMoveEvaluator(AnalyticalPTSPMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    protected AnalyticalPTSPMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The city's coordinates."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated (if it does not exist already) and used for evaluation, otherwise false."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities for each city to appear."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a TSP solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The evaluated quality of a move on a TSP solution."));
+      Parameters.Add(new LookupParameter<DistanceCalculator>("DistanceCalculator", "The class that can compute distances between coordinates."));
+    }
+
+    public override IOperation Apply() {
+      var permutation = PermutationParameter.ActualValue;
+      var coordinates = CoordinatesParameter.ActualValue;
+      var probabilities = ProbabilitiesParameter.ActualValue;
+      Func<int, int, double> distance = null;
+      if (UseDistanceMatrixParameter.ActualValue.Value) {
+        var distanceMatrix = DistanceMatrixParameter.ActualValue;
+        if (distanceMatrix == null) throw new InvalidOperationException("The distance matrix has not been calculated.");
+        distance = (a, b) => distanceMatrix[a, b];
+      } else {
+        if (coordinates == null) throw new InvalidOperationException("No coordinates were given.");
+        var distanceCalculator = DistanceCalculatorParameter.ActualValue;
+        if (distanceCalculator == null) throw new InvalidOperationException("Distance calculator is null!");
+        distance = (a, b) => distanceCalculator.Calculate(a, b, coordinates);
+      }
+      // here moves are not delta-evaluated
+      var newQuality = EvaluateMove(permutation, distance, probabilities);
+      var moveQuality = MoveQualityParameter.ActualValue;
+      if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(newQuality);
+      else moveQuality.Value = newQuality;
+
+      return base.Apply();
+    }
+
+    protected abstract double EvaluateMove(Permutation permutation, Func<int, int, double> distance, DoubleArray probabilities);
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/EstimatedPTSPMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/EstimatedPTSPMoveEvaluator.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/EstimatedPTSPMoveEvaluator.cs	(revision 13470)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Problems.PTSP {
-  [Item("EstimatedPTSPMoveEvaluator", "A base class for operators which evaluate TSP moves.")]
+  [Item("EstimatedPTSPMoveEvaluator", "A base class for operators which evaluate PTSP moves.")]
   [StorableClass]
   public abstract class EstimatedPTSPMoveEvaluator : SingleSuccessorOperator, IEstimatedPTSPMoveEvaluator {
@@ -81,15 +81,17 @@
       var permutation = PermutationParameter.ActualValue;
       var coordinates = CoordinatesParameter.ActualValue;
-      double relativeQualityDifference = 0;
+      var realizations = RealizationsParameter.ActualValue;
+      Func<int, int, double> distance = null;
       if (UseDistanceMatrixParameter.ActualValue.Value) {
         var distanceMatrix = DistanceMatrixParameter.ActualValue;
         if (distanceMatrix == null) throw new InvalidOperationException("The distance matrix has not been calculated.");
-        relativeQualityDifference = EvaluateByDistanceMatrix(permutation, distanceMatrix);
+        distance = (a, b) => distanceMatrix[a, b];
       } else {
         if (coordinates == null) throw new InvalidOperationException("No coordinates were given.");
         var distanceCalculator = DistanceCalculatorParameter.ActualValue;
         if (distanceCalculator == null) throw new InvalidOperationException("Distance calculator is null!");
-        relativeQualityDifference = EvaluateByCoordinates(permutation, coordinates, distanceCalculator);
+        distance = (a, b) => distanceCalculator.Calculate(a, b, coordinates);
       }
+      var relativeQualityDifference = EvaluateMove(permutation, distance, realizations);
       var moveQuality = MoveQualityParameter.ActualValue;
       if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(QualityParameter.ActualValue.Value + relativeQualityDifference);
@@ -98,6 +100,5 @@
     }
 
-    protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix);
-    protected abstract double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator);
+    protected abstract double EvaluateMove(Permutation permutation, Func<int, int, double> distance, ItemList<BoolArray> realizations);
   }
 }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPAnalyticalInsertionMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPAnalyticalInsertionMoveEvaluator.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPAnalyticalInsertionMoveEvaluator.cs	(revision 13470)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  [Item("PTSP Analytical Insertion Move Evaluator", "Evaluates an insertion move (1-shift) by a full solution evaluation")]
+  [StorableClass]
+  public class PTSPAnalyticalInsertionMoveEvaluator : AnalyticalPTSPMoveEvaluator, IPermutationTranslocationMoveOperator {
+
+    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
+      get { return (ILookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
+    }
+
+    [StorableConstructor]
+    protected PTSPAnalyticalInsertionMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected PTSPAnalyticalInsertionMoveEvaluator(PTSPAnalyticalInsertionMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public PTSPAnalyticalInsertionMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move to evaluate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPAnalyticalInsertionMoveEvaluator(this, cloner);
+    }
+
+    public static double EvaluateMove(Permutation tour, TranslocationMove move, Func<int, int, double> distance, DoubleArray probabilities) {
+      var afterMove = (Permutation)tour.Clone();
+      TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
+      return AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities);
+    }
+
+    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, DoubleArray probabilities) {
+      return EvaluateMove(tour, TranslocationMoveParameter.ActualValue, distance, probabilities);
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs	(revision 13470)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Problems.PTSP {
-  [Item("PTSPEstimatedInsertionMoveEvaluator", "Evaluates an insertion move (1-shift)")]
+  [Item("PTSP Estimated Insertion Move Evaluator", "Evaluates an insertion move (1-shift)")]
   [StorableClass]
   public class PTSPEstimatedInsertionMoveEvaluator : EstimatedPTSPMoveEvaluator, IPermutationTranslocationMoveOperator {
@@ -49,18 +49,18 @@
     }
 
-    public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, DistanceCalculator distanceCalculator, ItemList<BoolArray> realizations) {
-      var afterMove = new Permutation(PermutationTypes.RelativeUndirected, permutation);
+    public static double EvaluateMove(Permutation tour, TranslocationMove move, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+      var afterMove = (Permutation)tour.Clone();
       TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
       double moveQuality = 0;
       var edges = new int[12];
       var indices = new int[12];
-      edges[0] = permutation.GetCircular(move.Index1 - 1);
-      indices[0] = DecreaseCircularIndex(permutation.Length, move.Index1);
-      edges[1] = permutation[move.Index1];
+      edges[0] = tour.GetCircular(move.Index1 - 1);
+      indices[0] = DecreaseCircularIndex(tour.Length, move.Index1);
+      edges[1] = tour[move.Index1];
       indices[1] = move.Index1;
-      edges[2] = permutation[move.Index1];
+      edges[2] = tour[move.Index1];
       indices[2] = move.Index1;
-      edges[3] = permutation.GetCircular(move.Index1 + 1);
-      indices[3] = IncreaseCircularIndex(permutation.Length, move.Index1);
+      edges[3] = tour.GetCircular(move.Index1 + 1);
+      indices[3] = IncreaseCircularIndex(tour.Length, move.Index1);
 
       edges[6] = afterMove.GetCircular(move.Index3 - 1);
@@ -74,7 +74,7 @@
 
       if (move.Index3 > move.Index1) {
-        edges[4] = permutation[move.Index3];
+        edges[4] = tour[move.Index3];
         indices[4] = move.Index3;
-        edges[5] = permutation.GetCircular(move.Index3 + 1);
+        edges[5] = tour.GetCircular(move.Index3 + 1);
         indices[5] = indices[9];
         edges[10] = afterMove.GetCircular(move.Index1 - 1);
@@ -83,7 +83,7 @@
         indices[11] = move.Index1;
       } else {
-        edges[4] = permutation.GetCircular(move.Index3 - 1);
+        edges[4] = tour.GetCircular(move.Index3 - 1);
         indices[4] = indices[6];
-        edges[5] = permutation[move.Index3];
+        edges[5] = tour[move.Index3];
         indices[5] = move.Index3;
         edges[10] = afterMove[move.Index1];
@@ -97,5 +97,5 @@
           Permutation tempPermutation;
           if (i < 6) {
-            tempPermutation = permutation;
+            tempPermutation = tour;
           } else {
             tempPermutation = afterMove;
@@ -124,95 +124,6 @@
           !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5])) {
           // compute cost difference between the two a posteriori solutions
-
-          moveQuality += distanceCalculator.Calculate(aPosteriori[6], aPosteriori[7], coordinates)
-                       + distanceCalculator.Calculate(aPosteriori[8], aPosteriori[9], coordinates)
-                       + distanceCalculator.Calculate(aPosteriori[10], aPosteriori[11], coordinates)
-                       - distanceCalculator.Calculate(aPosteriori[0], aPosteriori[1], coordinates)
-                       - distanceCalculator.Calculate(aPosteriori[2], aPosteriori[3], coordinates)
-                       - distanceCalculator.Calculate(aPosteriori[4], aPosteriori[5], coordinates);
-        }
-        Array.Clear(aPosteriori, 0, aPosteriori.Length);
-      }
-      // return average of cost differences
-      return moveQuality / realizations.Count;
-    }
-
-    public static double EvaluateByDistanceMatrix(Permutation permutation, TranslocationMove move, DistanceMatrix distanceMatrix, ItemList<BoolArray> realizations) {
-      var afterMove = new Permutation(PermutationTypes.RelativeUndirected, permutation);
-      TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
-      double moveQuality = 0;
-      var edges = new int[12];
-      var indices = new int[12];
-      edges[0] = permutation.GetCircular(move.Index1 - 1);
-      indices[0] = DecreaseCircularIndex(permutation.Length, move.Index1);
-      edges[1] = permutation[move.Index1];
-      indices[1] = move.Index1;
-      edges[2] = permutation[move.Index1];
-      indices[2] = move.Index1;
-      edges[3] = permutation.GetCircular(move.Index1 + 1);
-      indices[3] = IncreaseCircularIndex(permutation.Length, move.Index1);
-
-      edges[6] = afterMove.GetCircular(move.Index3 - 1);
-      indices[6] = DecreaseCircularIndex(afterMove.Length, move.Index3);
-      edges[7] = afterMove[move.Index3];
-      indices[7] = move.Index3;
-      edges[8] = afterMove[move.Index3];
-      indices[8] = move.Index3;
-      edges[9] = afterMove.GetCircular(move.Index3 + 1);
-      indices[9] = IncreaseCircularIndex(afterMove.Length, move.Index3);
-
-      if (move.Index3 > move.Index1) {
-        edges[4] = permutation[move.Index3];
-        indices[4] = move.Index3;
-        edges[5] = permutation.GetCircular(move.Index3 + 1);
-        indices[5] = indices[9];
-        edges[10] = afterMove.GetCircular(move.Index1 - 1);
-        indices[10] = indices[0];
-        edges[11] = afterMove[move.Index1];
-        indices[11] = move.Index1;
-      } else {
-        edges[4] = permutation.GetCircular(move.Index3 - 1);
-        indices[4] = indices[6];
-        edges[5] = permutation[move.Index3];
-        indices[5] = move.Index3;
-        edges[10] = afterMove[move.Index1];
-        indices[10] = move.Index1;
-        edges[11] = afterMove.GetCircular(move.Index1 + 1);
-        indices[11] = indices[3];
-      }
-      int[] aPosteriori = new int[12];
-      foreach (var realization in realizations) {
-        for (int i = 0; i < edges.Length; i++) {
-          Permutation tempPermutation;
-          if (i < 6) {
-            tempPermutation = permutation;
-          } else {
-            tempPermutation = afterMove;
-          }
-          if (realization[edges[i]]) {
-            aPosteriori[i] = edges[i];
-          } else {
-            int j = 1;
-            if (i % 2 == 0) {
-              // find nearest predecessor in realization if source edge
-              while (!realization[tempPermutation.GetCircular(indices[i] - j)]) {
-                j++;
-              }
-              aPosteriori[i] = tempPermutation.GetCircular(indices[i] - j);
-            } else {
-              // find nearest successor in realization if target edge
-              while (!realization[tempPermutation.GetCircular(indices[i] + j)]) {
-                j++;
-              }
-              aPosteriori[i] = tempPermutation.GetCircular(indices[i] + j);
-            }
-          }
-        }
-        if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3]) &&
-          !(aPosteriori[0] == aPosteriori[4] && aPosteriori[1] == aPosteriori[5]) &&
-          !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5])) {
-          // compute cost difference between the two a posteriori solutions
-          moveQuality = moveQuality + distanceMatrix[aPosteriori[6], aPosteriori[7]] + distanceMatrix[aPosteriori[8], aPosteriori[9]] + distanceMatrix[aPosteriori[10], aPosteriori[11]];
-          moveQuality = moveQuality - distanceMatrix[aPosteriori[0], aPosteriori[1]] - distanceMatrix[aPosteriori[2], aPosteriori[3]] - distanceMatrix[aPosteriori[4], aPosteriori[5]];
+          moveQuality = moveQuality + distance(aPosteriori[6], aPosteriori[7]) + distance(aPosteriori[8], aPosteriori[9]) + distance(aPosteriori[10], aPosteriori[11]);
+          moveQuality = moveQuality - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]) - distance(aPosteriori[4], aPosteriori[5]);
         }
         Array.Clear(aPosteriori, 0, aPosteriori.Length);
@@ -238,10 +149,6 @@
     }
 
-    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator) {
-      return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, distanceCalculator, RealizationsParameter.ActualValue);
-    }
-
-    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
-      return EvaluateByDistanceMatrix(permutation, TranslocationMoveParameter.ActualValue, distanceMatrix, RealizationsParameter.ActualValue);
+    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+      return EvaluateMove(tour, TranslocationMoveParameter.ActualValue, distance, realizations);
     }
   }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPAnalyticalInversionMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPAnalyticalInversionMoveEvaluator.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPAnalyticalInversionMoveEvaluator.cs	(revision 13470)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  [Item("PTSP Analytical Inversion Move Evaluator", "Evaluates an inversion move (2-opt) by a full solution evaluation.")]
+  [StorableClass]
+  public class PTSPAnalyticalInversionMoveEvaluator : AnalyticalPTSPMoveEvaluator, IPermutationInversionMoveOperator {
+
+    public ILookupParameter<InversionMove> InversionMoveParameter {
+      get { return (ILookupParameter<InversionMove>)Parameters["InversionMove"]; }
+    }
+
+    [StorableConstructor]
+    protected PTSPAnalyticalInversionMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected PTSPAnalyticalInversionMoveEvaluator(PTSPAnalyticalInversionMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public PTSPAnalyticalInversionMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPAnalyticalInversionMoveEvaluator(this, cloner);
+    }
+
+    public static double EvaluateMove(Permutation tour, InversionMove move, Func<int, int, double> distance, DoubleArray probabilities) {
+      var afterMove = (Permutation)tour.Clone();
+      InversionManipulator.Apply(afterMove, move.Index1, move.Index2);
+      return AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities);
+    }
+
+    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, DoubleArray probabilities) {
+      return EvaluateMove(tour, InversionMoveParameter.ActualValue, distance, probabilities);
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPEstimatedInversionMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPEstimatedInversionMoveEvaluator.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPEstimatedInversionMoveEvaluator.cs	(revision 13470)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Problems.PTSP {
-  [Item("PTSPEstimatedInversionMoveEvaluator", "Evaluates an inversion move (2-opt) over several realizations of tours by summing up the length of all added edges and subtracting the length of all deleted edges.")]
+  [Item("PTSP Estimated Inversion Move Evaluator", "Evaluates an inversion move (2-opt) over several realizations of tours by summing up the length of all added edges and subtracting the length of all deleted edges.")]
   [StorableClass]
   public class PTSPEstimatedInversionMoveEvaluator : EstimatedPTSPMoveEvaluator, IPermutationInversionMoveOperator {
@@ -49,18 +49,18 @@
     }
 
-    public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, DistanceCalculator distanceCalculator, ItemList<BoolArray> realizations) {
+    public static double EvaluateMove(Permutation tour, InversionMove move, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
       double moveQuality = 0;
       var edges = new int[4];
       var indices = new int[4];
-      edges[0] = permutation.GetCircular(move.Index1 - 1);
+      edges[0] = tour.GetCircular(move.Index1 - 1);
       indices[0] = move.Index1 - 1;
-      if (indices[0] == -1) indices[0] = permutation.Length - 1;
-      edges[1] = permutation[move.Index1];
+      if (indices[0] == -1) indices[0] = tour.Length - 1;
+      edges[1] = tour[move.Index1];
       indices[1] = move.Index1;
-      edges[2] = permutation[move.Index2];
+      edges[2] = tour[move.Index2];
       indices[2] = move.Index2;
-      edges[3] = permutation.GetCircular(move.Index2 + 1);
+      edges[3] = tour.GetCircular(move.Index2 + 1);
       indices[3] = move.Index2 + 1;
-      if (indices[3] == permutation.Length + 1) indices[3] = 0;
+      if (indices[3] == tour.Length + 1) indices[3] = 0;
       var aPosteriori = new int[4];
       foreach (var realization in realizations) {
@@ -72,14 +72,14 @@
             if (i % 2 == 0) {
               // find nearest predecessor in realization if source edge
-              while (!realization[permutation.GetCircular(indices[i] - j)]) {
+              while (!realization[tour.GetCircular(indices[i] - j)]) {
                 j++;
               }
-              aPosteriori[i] = permutation.GetCircular(indices[i] - j);
+              aPosteriori[i] = tour.GetCircular(indices[i] - j);
             } else {
               // find nearest successor in realization if target edge
-              while (!realization[permutation.GetCircular(indices[i] + j)]) {
+              while (!realization[tour.GetCircular(indices[i] + j)]) {
                 j++;
               }
-              aPosteriori[i] = permutation.GetCircular(indices[i] + j);
+              aPosteriori[i] = tour.GetCircular(indices[i] + j);
             }
           }
@@ -87,9 +87,6 @@
         // compute cost difference between the two a posteriori solutions
         if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3])) {
-          moveQuality = moveQuality
-            + distanceCalculator.Calculate(0, 2, coordinates)
-            + distanceCalculator.Calculate(1, 3, coordinates)
-            - distanceCalculator.Calculate(0, 1, coordinates)
-            - distanceCalculator.Calculate(2, 3, coordinates);
+          moveQuality = moveQuality + distance(aPosteriori[0], aPosteriori[2]) + distance(aPosteriori[1], aPosteriori[3])
+            - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]);
         }
         Array.Clear(aPosteriori, 0, aPosteriori.Length);
@@ -99,56 +96,6 @@
     }
 
-    public static double EvaluateByDistanceMatrix(Permutation permutation, InversionMove move, DistanceMatrix distanceMatrix, ItemList<BoolArray> realizations) {
-      double moveQuality = 0;
-      var edges = new int[4];
-      var indices = new int[4];
-      edges[0] = permutation.GetCircular(move.Index1 - 1);
-      indices[0] = move.Index1 - 1;
-      if (indices[0] == -1) indices[0] = permutation.Length - 1;
-      edges[1] = permutation[move.Index1];
-      indices[1] = move.Index1;
-      edges[2] = permutation[move.Index2];
-      indices[2] = move.Index2;
-      edges[3] = permutation.GetCircular(move.Index2 + 1);
-      indices[3] = move.Index2 + 1;
-      if (indices[3] == permutation.Length + 1) indices[3] = 0;
-      var aPosteriori = new int[4];
-      foreach (var realization in realizations) {
-        for (var i = 0; i < edges.Length; i++) {
-          if (realization[edges[i]]) {
-            aPosteriori[i] = edges[i];
-          } else {
-            var j = 1;
-            if (i % 2 == 0) {
-              // find nearest predecessor in realization if source edge
-              while (!realization[permutation.GetCircular(indices[i] - j)]) {
-                j++;
-              }
-              aPosteriori[i] = permutation.GetCircular(indices[i] - j);
-            } else {
-              // find nearest successor in realization if target edge
-              while (!realization[permutation.GetCircular(indices[i] + j)]) {
-                j++;
-              }
-              aPosteriori[i] = permutation.GetCircular(indices[i] + j);
-            }
-          }
-        }
-        // compute cost difference between the two a posteriori solutions
-        if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3])) {
-          moveQuality = moveQuality + distanceMatrix[aPosteriori[0], aPosteriori[2]] + distanceMatrix[aPosteriori[1], aPosteriori[3]] - distanceMatrix[aPosteriori[0], aPosteriori[1]] - distanceMatrix[aPosteriori[2], aPosteriori[3]];
-        }
-        Array.Clear(aPosteriori, 0, aPosteriori.Length);
-      }
-      // return average of cost differences
-      return moveQuality / realizations.Count;
-    }
-
-    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator) {
-      return EvaluateByCoordinates(permutation, InversionMoveParameter.ActualValue, coordinates, distanceCalculator, RealizationsParameter.ActualValue);
-    }
-
-    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
-      return EvaluateByDistanceMatrix(permutation, InversionMoveParameter.ActualValue, distanceMatrix, RealizationsParameter.ActualValue);
+    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+      return EvaluateMove(tour, InversionMoveParameter.ActualValue, distance, realizations);
     }
   }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPAnalyticalTwoPointFiveMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPAnalyticalTwoPointFiveMoveEvaluator.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPAnalyticalTwoPointFiveMoveEvaluator.cs	(revision 13470)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  [Item("PTSP Analytical 2.5-MoveEvaluator", "Operator that evaluates 2.5-p-opt moves of PTSP by a full solution evaluation.")]
+  [StorableClass]
+  public class PTSPAnalyticalTwoPointFiveMoveEvaluator : AnalyticalPTSPMoveEvaluator, ITwoPointFiveMoveOperator {
+
+    public ILookupParameter<TwoPointFiveMove> TwoPointFiveMoveParameter {
+      get { return (ILookupParameter<TwoPointFiveMove>)Parameters["TwoPointFiveMove"]; }
+    }
+
+    [StorableConstructor]
+    protected PTSPAnalyticalTwoPointFiveMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected PTSPAnalyticalTwoPointFiveMoveEvaluator(PTSPAnalyticalTwoPointFiveMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public PTSPAnalyticalTwoPointFiveMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<TwoPointFiveMove>("TwoPointFiveMove", "The move to evaluate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPAnalyticalTwoPointFiveMoveEvaluator(this, cloner);
+    }
+
+    protected override double EvaluateMove(Permutation permutation, Func<int, int, double> distance, DoubleArray probabilities) {
+      return EvaluateMove(permutation, TwoPointFiveMoveParameter.ActualValue, distance, probabilities);
+    }
+
+    public static double EvaluateMove(Permutation permutation, TwoPointFiveMove move, Func<int, int, double> distance, DoubleArray probabilities) {
+      if (move.IsInvert) {
+        return PTSPAnalyticalInversionMoveEvaluator.EvaluateMove(permutation,
+          new InversionMove(move.Index1, move.Index2, move.Permutation), distance, probabilities);
+      } else {
+        return PTSPAnalyticalInsertionMoveEvaluator.EvaluateMove(permutation,
+          new TranslocationMove(move.Index1, move.Index1, move.Index2), distance, probabilities);
+      }
+    }
+  }
+}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPEstimatedTwoPointFiveMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPEstimatedTwoPointFiveMoveEvaluator.cs	(revision 13470)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPEstimatedTwoPointFiveMoveEvaluator.cs	(revision 13470)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.PTSP {
+  [Item("PTSP Estimated 2.5-MoveEvaluator", "Operator that evaluates 2.5-p-opt moves of PTSP")]
+  [StorableClass]
+  public class PTSPEstimatedTwoPointFiveMoveEvaluator : EstimatedPTSPMoveEvaluator, ITwoPointFiveMoveOperator {
+
+    public ILookupParameter<TwoPointFiveMove> TwoPointFiveMoveParameter {
+      get { return (ILookupParameter<TwoPointFiveMove>)Parameters["TwoPointFiveMove"]; }
+    }
+
+    [StorableConstructor]
+    protected PTSPEstimatedTwoPointFiveMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected PTSPEstimatedTwoPointFiveMoveEvaluator(PTSPEstimatedTwoPointFiveMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public PTSPEstimatedTwoPointFiveMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<TwoPointFiveMove>("TwoPointFiveMove", "The move to evaluate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PTSPEstimatedTwoPointFiveMoveEvaluator(this, cloner);
+    }
+
+    protected override double EvaluateMove(Permutation permutation, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+      return EvaluateMove(permutation, TwoPointFiveMoveParameter.ActualValue, distance, realizations);
+    }
+
+    public static double EvaluateMove(Permutation permutation, TwoPointFiveMove move, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+      if (move.IsInvert) {
+        return PTSPEstimatedInversionMoveEvaluator.EvaluateMove(permutation,
+          new InversionMove(move.Index1, move.Index2, move.Permutation), distance, realizations);
+      } else {
+        return PTSPEstimatedInsertionMoveEvaluator.EvaluateMove(permutation,
+          new TranslocationMove(move.Index1, move.Index1, move.Index2), distance, realizations);
+      }
+    }
+  }
+}
Index: anches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPTwoPointFiveMoveEvaluator.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPTwoPointFiveMoveEvaluator.cs	(revision 13469)
+++ 	(revision )
@@ -1,86 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.PTSP {
-  [Item("PTSP 2.5-MoveEvaluator", "Operator that evaluates 2.5-p-opt moves of PTSP")]
-  [StorableClass]
-  public class PTSPTwoPointFiveMoveEvaluator : EstimatedPTSPMoveEvaluator, ITwoPointFiveMoveOperator {
-
-    public ILookupParameter<TwoPointFiveMove> TwoPointFiveMoveParameter {
-      get { return (ILookupParameter<TwoPointFiveMove>)Parameters["TwoPointFiveMove"]; }
-    }
-
-    [StorableConstructor]
-    protected PTSPTwoPointFiveMoveEvaluator(bool deserializing) : base(deserializing) { }
-    protected PTSPTwoPointFiveMoveEvaluator(PTSPTwoPointFiveMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public PTSPTwoPointFiveMoveEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<TwoPointFiveMove>("TwoPointFiveMove", "The move to evaluate."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PTSPTwoPointFiveMoveEvaluator(this, cloner);
-    }
-
-    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator) {
-      var move = TwoPointFiveMoveParameter.ActualValue;
-      var realizations = RealizationsParameter.ActualValue;
-      return EvaluateByCoordinates(permutation, coordinates, distanceCalculator, move, realizations);
-    }
-
-    public static double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator, TwoPointFiveMove move, ItemList<BoolArray> realizations) {
-      if (move.IsInvert) {
-        return PTSPEstimatedInversionMoveEvaluator.EvaluateByCoordinates(permutation,
-          new InversionMove(move.Index1, move.Index2, move.Permutation),
-          coordinates, distanceCalculator, realizations);
-      } else {
-        return PTSPEstimatedInsertionMoveEvaluator.EvaluateByCoordinates(permutation,
-          new TranslocationMove(move.Index1, move.Index1, move.Index2),
-          coordinates, distanceCalculator, realizations);
-      }
-    }
-
-    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
-      var move = TwoPointFiveMoveParameter.ActualValue;
-      var realizations = RealizationsParameter.ActualValue;
-      return EvaluateByDistanceMatrix(permutation, distanceMatrix, move, realizations);
-    }
-
-    public static double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix, TwoPointFiveMove move, ItemList<BoolArray> realizations) {
-      if (move.IsInvert) {
-        return PTSPEstimatedInversionMoveEvaluator.EvaluateByDistanceMatrix(permutation,
-          new InversionMove(move.Index1, move.Index2, move.Permutation),
-          distanceMatrix, realizations);
-      } else {
-        return PTSPEstimatedInsertionMoveEvaluator.EvaluateByDistanceMatrix(permutation,
-          new TranslocationMove(move.Index1, move.Index1, move.Index2),
-          distanceMatrix, realizations);
-      }
-    }
-  }
-}
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/TwoPointFiveMoveMaker.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/TwoPointFiveMoveMaker.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/TwoPointFiveMoveMaker.cs	(revision 13470)
@@ -71,4 +71,12 @@
       var quality = QualityParameter.ActualValue;
 
+      Apply(permutation, move);
+
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+
+    public static void Apply(Permutation permutation, TwoPointFiveMove move) {
       if (move.IsInvert) {
         InversionManipulator.Apply(permutation, move.Index1, move.Index2);
@@ -76,8 +84,4 @@
         TranslocationManipulator.Apply(permutation, move.Index1, move.Index1, move.Index2);
       }
-
-      quality.Value = moveQuality.Value;
-
-      return base.Apply();
     }
   }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/PTSP.cs
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/PTSP.cs	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/PTSP.cs	(revision 13470)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -35,4 +36,6 @@
   public abstract class ProbabilisticTravelingSalesmanProblem : SingleObjectiveBasicProblem<PermutationEncoding>,
   IProblemInstanceConsumer<PTSPData> {
+    protected bool SuppressEvents { get; set; }
+
     private static readonly int DistanceMatrixSizeLimit = 1000;
 
@@ -92,5 +95,8 @@
     [StorableConstructor]
     protected ProbabilisticTravelingSalesmanProblem(bool deserializing) : base(deserializing) { }
-    protected ProbabilisticTravelingSalesmanProblem(ProbabilisticTravelingSalesmanProblem original, Cloner cloner) : base(original, cloner) { }
+    protected ProbabilisticTravelingSalesmanProblem(ProbabilisticTravelingSalesmanProblem original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
     protected ProbabilisticTravelingSalesmanProblem() {
       Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
@@ -101,5 +107,5 @@
       Parameters.Add(new ValueParameter<DoubleArray>("Probabilities", "This list describes for each city the probability of appearing in a realized instance."));
 
-      Coordinates = new DoubleMatrix(new double[,] {
+      var coordinates = new DoubleMatrix(new double[,] {
         { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },
         { 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 },
@@ -107,6 +113,50 @@
         { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }
       });
-
-      Probabilities = new DoubleArray(new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
+      Coordinates = coordinates;
+      Encoding.Length = coordinates.Rows;
+      DistanceCalculator = new EuclideanDistance();
+      DistanceMatrix = new DistanceMatrix(CalculateDistances());
+      Probabilities = new DoubleArray(Enumerable.Range(0, coordinates.Rows).Select(x => 0.5).ToArray());
+
+      RegisterEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      CoordinatesParameter.ValueChanged += CoordinatesParameterOnValueChanged;
+      if (Coordinates != null) {
+        Coordinates.RowsChanged += CoordinatesOnChanged;
+        Coordinates.ItemChanged += CoordinatesOnChanged;
+      }
+      UseDistanceMatrixParameter.Value.ValueChanged += UseDistanceMatrixValueChanged;
+      DistanceCalculatorParameter.ValueChanged += DistanceCalculatorParameterOnValueChanged;
+    }
+
+    private void CoordinatesParameterOnValueChanged(object sender, EventArgs eventArgs) {
+      if (Coordinates != null) {
+        Coordinates.RowsChanged += CoordinatesOnChanged;
+        Coordinates.ItemChanged += CoordinatesOnChanged;
+      }
+      if (SuppressEvents) return;
+      UpdateInstance();
+    }
+
+    private void CoordinatesOnChanged(object sender, EventArgs eventArgs) {
+      if (SuppressEvents) return;
+      UpdateInstance();
+    }
+
+    private void UseDistanceMatrixValueChanged(object sender, EventArgs eventArgs) {
+      if (SuppressEvents) return;
+      UpdateInstance();
+    }
+
+    private void DistanceCalculatorParameterOnValueChanged(object sender, EventArgs eventArgs) {
+      if (SuppressEvents) return;
+      UpdateInstance();
     }
 
@@ -117,41 +167,72 @@
     public abstract double Evaluate(Permutation tour, IRandom random);
 
+    public double[,] CalculateDistances() {
+      var coords = Coordinates;
+      var len = coords.Rows;
+      var dist = DistanceCalculator;
+
+      var matrix = new double[len, len];
+      for (var i = 0; i < len - 1; i++)
+        for (var j = i + 1; j < len; j++)
+          matrix[i, j] = matrix[j, i] = dist.Calculate(i, j, coords);
+
+      return matrix;
+    }
+
     public virtual void Load(PTSPData data) {
-      if (data.Coordinates == null && data.Distances == null)
-        throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!");
-      if (data.Dimension > DistanceMatrixSizeLimit && (data.Coordinates == null || data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2))
-        throw new System.IO.InvalidDataException("The given instance is too large for using a distance matrix and there is a problem with the coordinates.");
-      if (data.Coordinates != null && (data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2))
-        throw new System.IO.InvalidDataException("The coordinates of the given instance are not in the right format, there need to be one row for each customer and two columns for the x and y coordinates respectively.");
-
-      switch (data.DistanceMeasure) {
-        case DistanceMeasure.Direct:
-          DistanceCalculator = null;
-          if (data.Dimension > DistanceMatrixSizeLimit && Coordinates != null) {
-            DistanceCalculator = new EuclideanDistance();
-            UseDistanceMatrix = false;
-          } else UseDistanceMatrix = true;
-          break;
-        case DistanceMeasure.Att: DistanceCalculator = new AttDistance(); break;
-        case DistanceMeasure.Euclidean: DistanceCalculator = new EuclideanDistance(); break;
-        case DistanceMeasure.Geo: DistanceCalculator = new GeoDistance(); break;
-        case DistanceMeasure.Manhattan: DistanceCalculator = new ManhattanDistance(); break;
-        case DistanceMeasure.Maximum: DistanceCalculator = new MaximumDistance(); break;
-        case DistanceMeasure.RoundedEuclidean: DistanceCalculator = new RoundedEuclideanDistance(); break;
-        case DistanceMeasure.UpperEuclidean: DistanceCalculator = new UpperEuclideanDistance(); break;
-        default: throw new ArgumentException("Distance measure is unknown");
-      }
-
-      Name = data.Name;
-      Description = data.Description;
-
-      Probabilities = new DoubleArray(data.Probabilities);
-      BestKnownSolution = data.BestKnownTour != null ? new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour) : null;
-      Coordinates = data.Coordinates != null && data.Coordinates.GetLength(0) > 0 ? new DoubleMatrix(data.Coordinates) : null;
-      DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix());
-
-      Encoding.Length = data.Dimension;
-
+      try {
+        SuppressEvents = true;
+        if (data.Coordinates == null && data.Distances == null)
+          throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!");
+        if (data.Dimension > DistanceMatrixSizeLimit && (data.Coordinates == null || data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2))
+          throw new System.IO.InvalidDataException("The given instance is too large for using a distance matrix and there is a problem with the coordinates.");
+        if (data.Coordinates != null && (data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2))
+          throw new System.IO.InvalidDataException("The coordinates of the given instance are not in the right format, there need to be one row for each customer and two columns for the x and y coordinates respectively.");
+
+        switch (data.DistanceMeasure) {
+          case DistanceMeasure.Direct:
+            DistanceCalculator = null;
+            if (data.Dimension > DistanceMatrixSizeLimit && Coordinates != null) {
+              DistanceCalculator = new EuclideanDistance();
+              UseDistanceMatrix = false;
+            } else UseDistanceMatrix = true;
+            break;
+          case DistanceMeasure.Att: DistanceCalculator = new AttDistance(); break;
+          case DistanceMeasure.Euclidean: DistanceCalculator = new EuclideanDistance(); break;
+          case DistanceMeasure.Geo: DistanceCalculator = new GeoDistance(); break;
+          case DistanceMeasure.Manhattan: DistanceCalculator = new ManhattanDistance(); break;
+          case DistanceMeasure.Maximum: DistanceCalculator = new MaximumDistance(); break;
+          case DistanceMeasure.RoundedEuclidean: DistanceCalculator = new RoundedEuclideanDistance(); break;
+          case DistanceMeasure.UpperEuclidean: DistanceCalculator = new UpperEuclideanDistance(); break;
+          default: throw new ArgumentException("Distance measure is unknown");
+        }
+
+        Name = data.Name;
+        Description = data.Description;
+
+        Probabilities = new DoubleArray(data.Probabilities);
+        BestKnownSolution = data.BestKnownTour != null ? new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour) : null;
+        Coordinates = data.Coordinates != null && data.Coordinates.GetLength(0) > 0 ? new DoubleMatrix(data.Coordinates) : null;
+        DistanceMatrix = data.Dimension <= DistanceMatrixSizeLimit && UseDistanceMatrix ? new DistanceMatrix(data.GetDistanceMatrix()) : null;
+
+        Encoding.Length = data.Dimension;
+      } finally { SuppressEvents = false; }
       OnReset();
+    }
+
+    private void UpdateInstance() {
+      var len = GetProblemDimension();
+      if (Coordinates != null && Coordinates.Rows <= DistanceMatrixSizeLimit
+        && DistanceCalculator != null && UseDistanceMatrix)
+        DistanceMatrix = new DistanceMatrix(CalculateDistances());
+      if (!UseDistanceMatrix) DistanceMatrix = null;
+      Encoding.Length = len;
+
+      OnReset();
+    }
+
+    private int GetProblemDimension() {
+      if (Coordinates == null && DistanceMatrix == null) throw new InvalidOperationException("Both coordinates and distance matrix are null, please specify at least one of them.");
+      return Coordinates != null ? Coordinates.Rows : DistanceMatrix.Rows;
     }
   }
Index: /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Properties/AssemblyInfo.cs.frame	(revision 13469)
+++ /branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Properties/AssemblyInfo.cs.frame	(revision 13470)
@@ -34,3 +34,3 @@
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("3.3.0.0")]
-[assembly: AssemblyFileVersion("3.3.11.$WCREV$")]
+[assembly: AssemblyFileVersion("3.3.13.$WCREV$")]
Index: /branches/PTSP/PTSP.sln
===================================================================
--- /branches/PTSP/PTSP.sln	(revision 13469)
+++ /branches/PTSP/PTSP.sln	(revision 13470)
@@ -26,26 +26,38 @@
 		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|x64.ActiveCfg = Debug|x64
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|x64.Build.0 = Debug|x64
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|x86.ActiveCfg = Debug|x86
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Debug|x86.Build.0 = Debug|x86
 		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|Any CPU.Build.0 = Release|Any CPU
-		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|x64.ActiveCfg = Release|Any CPU
-		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|x86.ActiveCfg = Release|Any CPU
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|x64.ActiveCfg = Release|x64
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|x64.Build.0 = Release|x64
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|x86.ActiveCfg = Release|x86
+		{97198965-AFEA-496B-B3B1-316905C43FD6}.Release|x86.Build.0 = Release|x86
 		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|x64.ActiveCfg = Debug|x64
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|x64.Build.0 = Debug|x64
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|x86.ActiveCfg = Debug|x86
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Debug|x86.Build.0 = Debug|x86
 		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|x64.ActiveCfg = Release|Any CPU
-		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|x86.ActiveCfg = Release|Any CPU
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|x64.ActiveCfg = Release|x64
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|x64.Build.0 = Release|x64
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|x86.ActiveCfg = Release|x86
+		{90B6CA12-9791-4430-B2D7-CD3ED7F75E2B}.Release|x86.Build.0 = Release|x86
 		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|x64.ActiveCfg = Debug|x64
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|x64.Build.0 = Debug|x64
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|x86.ActiveCfg = Debug|x86
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Debug|x86.Build.0 = Debug|x86
 		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|Any CPU.Build.0 = Release|Any CPU
-		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|x64.ActiveCfg = Release|Any CPU
-		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|x86.ActiveCfg = Release|Any CPU
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|x64.ActiveCfg = Release|x64
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|x64.Build.0 = Release|x64
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|x86.ActiveCfg = Release|x86
+		{CBEC171A-F7EC-460D-94E2-D58625811D99}.Release|x86.Build.0 = Release|x86
 		{CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
