Index: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 3208)
+++ trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 3209)
@@ -108,7 +108,10 @@
     <Compile Include="Manipulators\TranslocationManipulator.cs" />
     <Compile Include="Moves\ThreeIndexMove.cs" />
+    <Compile Include="Moves\ThreeOpt\StochasticThreeOptMultiMoveGenerator.cs" />
     <Compile Include="Moves\ThreeOpt\ThreeOptMove.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Moves\ThreeOpt\ThreeOptMoveGenerator.cs" />
+    <Compile Include="Moves\ThreeOpt\ThreeOptMoveMaker.cs" />
     <Compile Include="Moves\TwoOpt\PreventReaddTwoOptTabuMoveEvaluator.cs" />
     <Compile Include="Moves\TwoOpt\StochasticTwoOptSingleMoveGenerator.cs" />
Index: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ExhaustiveThreeOptMoveGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ExhaustiveThreeOptMoveGenerator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ExhaustiveThreeOptMoveGenerator.cs	(revision 3209)
@@ -0,0 +1,55 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("ExhaustiveThreeOptMoveGenerator", "Generates all possible 3-opt moves from a given permutation.")]
+  [StorableClass]
+  public class ExhaustiveThreeOptMoveGenerator : ThreeOptMoveGenerator, IExhaustiveMoveGenerator {
+    public static ThreeOptMove[] Apply(Permutation permutation) {
+      int length = permutation.Length;
+      ThreeOptMove[] moves = new ThreeOptMove[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        int index1, index2, index3;
+        index1 = random.Next(length - 1);
+        do {
+          index2 = random.Next(index1 + 1, length);
+        } while (index2 - index1 >= length - 2);
+        do {
+          index3 = random.Next(length - index2 + index1 - 1);
+        } while (index3 == index1);
+        
+        moves[i] = new ThreeOptMove(index1, index2, index3);
+      }
+      return moves;
+    }
+
+    protected override ThreeOptMove[] GenerateMoves(Permutation permutation) {
+      return Apply(permutation);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMoveGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMoveGenerator.cs	(revision 3208)
+++ 	(revision )
@@ -1,73 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Encodings.PermutationEncoding {
-  [Item("StochasticThreeOptMoveGenerator", "Randomly samples n from all possible 3-opt moves from a given permutation.")]
-  [StorableClass]
-  public class StochasticThreeOptMultiMoveGenerator : ThreeOptMoveGenerator, IStochasticOperator, IMultiMoveGenerator {
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
-    public IValueLookupParameter<IntValue> SampleSizeParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
-    }
-
-    public IntValue SampleSize {
-      get { return SampleSizeParameter.Value; }
-      set { SampleSizeParameter.Value = value; }
-    }
-
-    public StochasticThreeOptMultiMoveGenerator()
-      : base() {
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
-    }
-
-    public static ThreeOptMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
-      int length = permutation.Length;
-      ThreeOptMove[] moves = new ThreeOptMove[sampleSize];
-      for (int i = 0; i < sampleSize; i++) {
-        int index1, index2, index3;
-        index1 = random.Next(length - 1);
-        index2 = random.Next(index1 + 1, length);
-        index3 = length - index2 + index1 - 1;  // get insertion point in remaining part
-        if (index3 > 0)
-          index3 = random.Next(index3);
-        else
-          index3 = 0;
-        moves[i] = new ThreeOptMove(index1, index2, index3);
-      }
-      return moves;
-    }
-
-    protected override ThreeOptMove[] GenerateMoves(Permutation permutation) {
-      IRandom random = RandomParameter.ActualValue;
-      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMultiMoveGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMultiMoveGenerator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMultiMoveGenerator.cs	(revision 3209)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticThreeOptMultiMoveGenerator", "Randomly samples n from all possible 3-opt moves from a given permutation.")]
+  [StorableClass]
+  public class StochasticThreeOptMultiMoveGenerator : ThreeOptMoveGenerator, IStochasticOperator, IMultiMoveGenerator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public IntValue SampleSize {
+      get { return SampleSizeParameter.Value; }
+      set { SampleSizeParameter.Value = value; }
+    }
+
+    public StochasticThreeOptMultiMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
+    }
+
+    public static ThreeOptMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      ThreeOptMove[] moves = new ThreeOptMove[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        int index1, index2, index3;
+        index1 = random.Next(length - 1);
+        do {
+          index2 = random.Next(index1, length);
+        } while (index2 - index1 >= length - 2);
+        do {
+          index3 = random.Next(length - index2 + index1 - 1);
+        } while (index3 == index1);
+        
+        moves[i] = new ThreeOptMove(index1, index2, index3);
+      }
+      return moves;
+    }
+
+    protected override ThreeOptMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs	(revision 3208)
+++ trunk/sources/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs	(revision 3209)
@@ -252,10 +252,7 @@
     private void InitializeOperators() {
       operators = new List<IOperator>();
-      if (ApplicationManager.Manager != null) {
-        foreach (IRealVectorOperator op in ApplicationManager.Manager.GetInstances<IRealVectorOperator>())
-          operators.Add(op);
-        UpdateMoveEvaluators();
-        ParameterizeOperators();
-      }
+      if (ApplicationManager.Manager != null) operators.AddRange(ApplicationManager.Manager.GetInstances<IRealVectorOperator>().Cast<IOperator>());
+      UpdateMoveEvaluators();
+      ParameterizeOperators();
       InitializeMoveGenerators();
     }
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj	(revision 3208)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj	(revision 3209)
@@ -87,6 +87,11 @@
     <Compile Include="Evaluators\TSPGeoPathEvaluator.cs" />
     <Compile Include="HeuristicLabProblemsTravelingSalesmanPlugin.cs" />
-    <Compile Include="MoveEvaluators\ThreeOptMoveTSPCoordinatesPathEvaluator.cs" />
-    <Compile Include="MoveEvaluators\ThreeOptMoveTSPRoundedEuclideanPathEvaluator.cs" />
+    <Compile Include="MoveEvaluators\ThreeOpt\TSPThreeOptRoundedEuclideanPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\ThreeOpt\TSPThreeOptEuclideanPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\ThreeOpt\TSPThreeOptGeoPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TwoOpt\TSPTwoOptEuclideanPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TwoOpt\TSPTwoOptGeoPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TwoOpt\TSPTwoOptPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TwoOpt\TSPTwoOptRoundedEuclideanPathMoveEvaluator.cs" />
     <Compile Include="TravelingSalesmanProblem.cs" />
     <Compile Include="TSPLIBTourParser.cs" />
@@ -104,10 +109,7 @@
     <Compile Include="Interfaces\ITSPPathEvaluator.cs" />
     <Compile Include="Interfaces\ITSPPathMoveEvaluator.cs" />
-    <Compile Include="MoveEvaluators\TwoOptMoveTSPRoundedEuclideanPathEvaluator.cs" />
+    <Compile Include="MoveEvaluators\ThreeOpt\TSPThreeOptPathMoveEvaluator.cs" />
     <Compile Include="MoveEvaluators\TSPPathMoveEvaluator.cs" />
     <Compile Include="MoveEvaluators\TSPMoveEvaluator.cs" />
-    <Compile Include="MoveEvaluators\TwoOptMoveTSPCoordinatesPathEvaluator.cs">
-      <SubType>Code</SubType>
-    </Compile>
     <Compile Include="TSPLIBParser.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 3208)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 3209)
@@ -23,7 +23,9 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
+using System;
 
 namespace HeuristicLab.Problems.TravelingSalesman {
   public interface ITSPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator {
+    Type EvaluatorType { get; }
   }
 }
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 3208)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 3209)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -34,4 +35,6 @@
   [StorableClass]
   public abstract class TSPMoveEvaluator : SingleSuccessorOperator, ITSPMoveEvaluator, IMoveOperator {
+    public abstract Type EvaluatorType { get; }
+
     public ILookupParameter<DoubleValue> QualityParameter {
       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 3208)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 3209)
@@ -54,4 +54,35 @@
       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."));
     }
+
+    public override IOperation Apply() {
+      Permutation permutation = PermutationParameter.ActualValue;
+      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
+      double relativeQualityDifference = 0;
+      if (UseDistanceMatrixParameter.ActualValue.Value) {
+        DoubleMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
+        if (distanceMatrix == null) {
+          distanceMatrix = CalculateDistanceMatrix(coordinates);
+          DistanceMatrixParameter.ActualValue = distanceMatrix;
+        }
+        relativeQualityDifference = EvaluateByDistanceMatrix(permutation, distanceMatrix);
+      } else relativeQualityDifference = EvaluateByCoordinates(permutation, coordinates);
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(QualityParameter.ActualValue.Value + relativeQualityDifference);
+      else moveQuality.Value = QualityParameter.ActualValue.Value + relativeQualityDifference;
+      return base.Apply();
+    }
+
+    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
+    protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DoubleMatrix distanceMatrix);
+    protected abstract double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates);
+
+    private DoubleMatrix CalculateDistanceMatrix(DoubleMatrix c) {
+      DoubleMatrix distanceMatrix = new DoubleMatrix(c.Rows, c.Rows);
+      for (int i = 0; i < distanceMatrix.Rows; i++) {
+        for (int j = 0; j < distanceMatrix.Columns; j++)
+          distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);
+      }
+      return distanceMatrix;
+    }
   }
 }
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptEuclideanPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptEuclideanPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptEuclideanPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 3-opt moves.
+  /// </summary>
+  [Item("TSPThreeOptEuclideanPathMoveEvaluator", "Operator for evaluating a 3-opt move based on euclidean distances.")]
+  [StorableClass]
+  public class TSPThreeOptEuclideanPathMoveEvaluator : TSPThreeOptPathMoveEvaluator {
+    public override Type EvaluatorType {
+      get { return typeof(TSPEuclideanPathEvaluator); }
+    }
+
+    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
+      return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptGeoPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptGeoPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptGeoPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 3-opt moves.
+  /// </summary>
+  [Item("TSPThreeOptGeoPathMoveEvaluator", "Operator for evaluating a 3-opt move based on geo (world) distances.")]
+  [StorableClass]
+  public class TSPThreeOptGeoPathMoveEvaluator : TSPThreeOptPathMoveEvaluator {
+    public override Type EvaluatorType {
+      get { return typeof(TSPGeoPathEvaluator); }
+    }
+
+    private const double PI = 3.141592;
+    private const double RADIUS = 6378.388;
+
+    /// <summary>
+    /// Calculates the distance between two points using the GEO distance metric (globe coordinates).
+    /// </summary>
+    /// <param name="x1">The x-coordinate of point 1.</param>
+    /// <param name="y1">The y-coordinate of point 1.</param>
+    /// <param name="x2">The x-coordinate of point 2.</param>
+    /// <param name="y2">The y-coordinate of point 2.</param>
+    /// <returns>The calculated distance.</returns>
+    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
+      double latitude1, longitude1, latitude2, longitude2;
+      double q1, q2, q3;
+      double length;
+
+      latitude1 = ConvertToRadian(x1);
+      longitude1 = ConvertToRadian(y1);
+      latitude2 = ConvertToRadian(x2);
+      longitude2 = ConvertToRadian(y2);
+
+      q1 = Math.Cos(longitude1 - longitude2);
+      q2 = Math.Cos(latitude1 - latitude2);
+      q3 = Math.Cos(latitude1 + latitude2);
+
+      length = (int)(RADIUS * Math.Acos(0.5 * ((1.0 + q1) * q2 - (1.0 - q1) * q3)) + 1.0);
+      return (length);
+    }
+
+    private double ConvertToRadian(double x) {
+      return PI * (Math.Truncate(x) + 5.0 * (x - Math.Truncate(x)) / 3.0) / 180.0;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,106 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+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.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 3-opt moves.
+  /// </summary>
+  [Item("TSPThreeOptPathMoveEvaluator", "Evaluates a 3-opt move by summing up the length of all added edges and subtracting the length of all deleted edges.")]
+  [StorableClass]
+  public abstract class TSPThreeOptPathMoveEvaluator : TSPPathMoveEvaluator, IThreeOptPermutationMoveOperator {
+    public ILookupParameter<ThreeOptMove> ThreeOptMoveParameter {
+      get { return (ILookupParameter<ThreeOptMove>)Parameters["ThreeOptMove"]; }
+    }
+
+    public TSPThreeOptPathMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<ThreeOptMove>("ThreeOptMove", "The move to evaluate."));
+    }
+
+    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates) {
+      ThreeOptMove move = ThreeOptMoveParameter.ActualValue;
+      int edge1source = permutation.GetCircular(move.Index1 - 1);
+      int edge1target = permutation[move.Index1];
+      int edge2source = permutation[move.Index2];
+      int edge2target = permutation.GetCircular(move.Index2 + 1);
+      int edge3source, edge3target;
+      if (move.Index3 > move.Index1) {
+        edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+        edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+      } else {
+        edge3source = permutation.GetCircular(move.Index3 - 1);
+        edge3target = permutation[move.Index3];
+      }
+      double moveQuality = 0;
+      // remove three edges
+      moveQuality -= CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+        coordinates[edge1target, 0], coordinates[edge1target, 1]);
+      moveQuality -= CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      moveQuality -= CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
+        coordinates[edge3target, 0], coordinates[edge3target, 1]);
+      // add three edges
+      moveQuality += CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
+        coordinates[edge1target, 0], coordinates[edge1target, 1]);
+      moveQuality += CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+        coordinates[edge3target, 0], coordinates[edge3target, 1]);
+      moveQuality += CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      return moveQuality;
+    }
+
+    protected override double EvaluateByDistanceMatrix(Permutation permutation, DoubleMatrix distanceMatrix) {
+      ThreeOptMove move = ThreeOptMoveParameter.ActualValue;
+      int edge1source = permutation.GetCircular(move.Index1 - 1);
+      int edge1target = permutation[move.Index1];
+      int edge2source = permutation[move.Index2];
+      int edge2target = permutation.GetCircular(move.Index2 + 1);
+      int edge3source, edge3target;
+      if (move.Index3 > move.Index1) {
+        edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+        edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+      } else {
+        edge3source = permutation.GetCircular(move.Index3 - 1);
+        edge3target = permutation[move.Index3];
+      }
+      if (move.Index1 == move.Index3
+        || move.Index2 - move.Index1 >= permutation.Length - 2) return 0;
+      double moveQuality = 0;
+      // remove three edges
+      moveQuality -= distanceMatrix[edge1source, edge1target];
+      moveQuality -= distanceMatrix[edge2source, edge2target];
+      moveQuality -= distanceMatrix[edge3source, edge3target];
+      // add three edges
+      moveQuality += distanceMatrix[edge3source, edge1target];
+      moveQuality += distanceMatrix[edge2source, edge3target];
+      moveQuality += distanceMatrix[edge1source, edge2target];
+      return moveQuality;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptRoundedEuclideanPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptRoundedEuclideanPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPThreeOptRoundedEuclideanPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 3-opt moves.
+  /// </summary>
+  [Item("TSPThreeOptRoundedEuclideanPathMoveEvaluator", "Operator for evaluating a 3-opt move based on rounded euclidean distances.")]
+  [StorableClass]
+  public class TSPThreeOptRoundedEuclideanPathMoveEvaluator : TSPThreeOptPathMoveEvaluator {
+    public override Type EvaluatorType {
+      get { return typeof(TSPRoundedEuclideanPathEvaluator); }
+    }
+
+    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
+      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOptMoveTSPCoordinatesPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOptMoveTSPCoordinatesPathEvaluator.cs	(revision 3208)
+++ 	(revision )
@@ -1,106 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate 3-opt moves.
-  /// </summary>
-  [Item("ThreeOptMoveTSPCoordinatesPathEvaluator", "Base class for evaluating 3-opt moves given the cities' coordinates.")]
-  [StorableClass]
-  public abstract class ThreeOptMoveTSPCoordinatesPathEvaluator : TSPPathMoveEvaluator, IThreeOptPermutationMoveOperator {
-    public ILookupParameter<ThreeOptMove> ThreeOptMoveParameter {
-      get { return (ILookupParameter<ThreeOptMove>)Parameters["ThreeOptMove"]; }
-    }
-
-    public ThreeOptMoveTSPCoordinatesPathEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<ThreeOptMove>("ThreeOptMove", "The move to evaluate."));
-    }
-
-    public override IOperation Apply() {
-      Permutation permutation = PermutationParameter.ActualValue;
-      ThreeOptMove move = ThreeOptMoveParameter.ActualValue;
-      double moveQuality = QualityParameter.ActualValue.Value;
-      int edge1source = permutation.GetCircular(move.Index1 - 1);
-      int edge1target = permutation[move.Index1];
-      int edge2source = permutation[move.Index2];
-      int edge2target = permutation.GetCircular(move.Index2 + 1);
-      int edge3source = permutation.GetCircular(move.Index3 - 1);
-      int edge3target = permutation[move.Index3];
-
-      if (!(move.Index1 == 0 && move.Index2 == permutation.Length - 1)) { // a change like this would break the calculation (it doesn't actually change the quality anyway)
-        if (UseDistanceMatrixParameter.ActualValue.Value) {
-          DoubleMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
-          if (distanceMatrix == null) {
-            distanceMatrix = CalculateDistanceMatrix(CoordinatesParameter.ActualValue);
-            DistanceMatrixParameter.ActualValue = distanceMatrix;
-          }
-          // remove three edges
-          moveQuality -= distanceMatrix[edge1source, edge1target];
-          moveQuality -= distanceMatrix[edge2source, edge2target];
-          moveQuality -= distanceMatrix[edge3source, edge3target];
-          // add three edges
-          moveQuality += distanceMatrix[edge3source, edge1target];
-          moveQuality += distanceMatrix[edge2source, edge3target];
-          moveQuality += distanceMatrix[edge1source, edge2target];
-        } else {
-          DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
-          // remove three edges
-          moveQuality -= CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
-            coordinates[edge1target, 0], coordinates[edge1target, 1]);
-          moveQuality -= CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
-            coordinates[edge2target, 0], coordinates[edge2target, 1]);
-          moveQuality -= CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
-            coordinates[edge3target, 0], coordinates[edge3target, 1]);
-          // add three edges
-          moveQuality += CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
-            coordinates[edge1target, 0], coordinates[edge1target, 1]);
-          moveQuality += CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
-            coordinates[edge3target, 0], coordinates[edge3target, 1]);
-          moveQuality += CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
-            coordinates[edge2target, 0], coordinates[edge2target, 1]);
-        }
-      }
-      if (MoveQualityParameter.ActualValue == null) MoveQualityParameter.ActualValue = new DoubleValue(moveQuality);
-      else MoveQualityParameter.ActualValue.Value = moveQuality;
-      return base.Apply();
-    }
-
-    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
-
-    protected DoubleMatrix CalculateDistanceMatrix(DoubleMatrix c) {
-      DoubleMatrix distanceMatrix = new DoubleMatrix(c.Rows, c.Rows);
-      for (int i = 0; i < distanceMatrix.Rows; i++) {
-        for (int j = 0; j < distanceMatrix.Columns; j++)
-          distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);
-      }
-      return distanceMatrix;
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOptMoveTSPRoundedEuclideanPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOptMoveTSPRoundedEuclideanPathEvaluator.cs	(revision 3208)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate 3-opt moves.
-  /// </summary>
-  [Item("ThreeOptMoveTSPRoundedEuclideanPathEvaluator", "Evaluates a 3-opt move (rounded euclidean distances) by summing up the length of all added edges and subtracting the length of all deleted edges.")]
-  [StorableClass]
-  public class ThreeOptMoveTSPRoundedEuclideanPathEvaluator : ThreeOptMoveTSPCoordinatesPathEvaluator {
-    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
-      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptEuclideanPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptEuclideanPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptEuclideanPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 2-opt moves.
+  /// </summary>
+  [Item("TSPTwoOptEuclideanPathMoveEvaluator", "Operator for evaluating a 2-opt move based on euclidean distances.")]
+  [StorableClass]
+  public class TSPTwoOptEuclideanPathMoveEvaluator : TSPTwoOptPathMoveEvaluator {
+    public override Type EvaluatorType {
+      get { return typeof(TSPEuclideanPathEvaluator); }
+    }
+
+    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
+      return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptGeoPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptGeoPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptGeoPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 2-opt moves.
+  /// </summary>
+  [Item("TSPTwoOptGeoPathMoveEvaluator", "Operator for evaluating a 2-opt move based on geo (world) distances.")]
+  [StorableClass]
+  public class TSPTwoOptGeoPathMoveEvaluator : TSPTwoOptPathMoveEvaluator {
+    public override Type EvaluatorType {
+      get { return typeof(TSPGeoPathEvaluator); }
+    }
+
+    private const double PI = 3.141592;
+    private const double RADIUS = 6378.388;
+
+    /// <summary>
+    /// Calculates the distance between two points using the GEO distance metric (globe coordinates).
+    /// </summary>
+    /// <param name="x1">The x-coordinate of point 1.</param>
+    /// <param name="y1">The y-coordinate of point 1.</param>
+    /// <param name="x2">The x-coordinate of point 2.</param>
+    /// <param name="y2">The y-coordinate of point 2.</param>
+    /// <returns>The calculated distance.</returns>
+    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
+      double latitude1, longitude1, latitude2, longitude2;
+      double q1, q2, q3;
+      double length;
+
+      latitude1 = ConvertToRadian(x1);
+      longitude1 = ConvertToRadian(y1);
+      latitude2 = ConvertToRadian(x2);
+      longitude2 = ConvertToRadian(y2);
+
+      q1 = Math.Cos(longitude1 - longitude2);
+      q2 = Math.Cos(latitude1 - latitude2);
+      q3 = Math.Cos(latitude1 + latitude2);
+
+      length = (int)(RADIUS * Math.Acos(0.5 * ((1.0 + q1) * q2 - (1.0 - q1) * q3)) + 1.0);
+      return (length);
+    }
+
+    private double ConvertToRadian(double x) {
+      return PI * (Math.Truncate(x) + 5.0 * (x - Math.Truncate(x)) / 3.0) / 180.0;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,82 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+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.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 2-opt moves.
+  /// </summary>
+  [Item("TSPTwoOptPathMoveEvaluator", "Evaluates a 2-opt move by summing up the length of all added edges and subtracting the length of all deleted edges.")]
+  [StorableClass]
+  public abstract class TSPTwoOptPathMoveEvaluator : TSPPathMoveEvaluator, ITwoOptPermutationMoveOperator {
+    public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
+      get { return (ILookupParameter<TwoOptMove>)Parameters["TwoOptMove"]; }
+    }
+
+    public TSPTwoOptPathMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<TwoOptMove>("TwoOptMove", "The move to evaluate."));
+    }
+
+    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates) {
+      TwoOptMove m = TwoOptMoveParameter.ActualValue;
+      int edge1source = permutation.GetCircular(m.Index1 - 1);
+      int edge1target = permutation[m.Index1];
+      int edge2source = permutation[m.Index2];
+      int edge2target = permutation.GetCircular(m.Index2 + 1);
+      double moveQuality = 0;
+      // remove two edges
+      moveQuality -= CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+            coordinates[edge1target, 0], coordinates[edge1target, 1]);
+      moveQuality -= CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      // add two edges
+      moveQuality += CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+        coordinates[edge2source, 0], coordinates[edge2source, 1]);
+      moveQuality += CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      return moveQuality;
+    }
+
+    protected override double EvaluateByDistanceMatrix(Permutation permutation, DoubleMatrix distanceMatrix) {
+      TwoOptMove m = TwoOptMoveParameter.ActualValue;
+      int edge1source = permutation.GetCircular(m.Index1 - 1);
+      int edge1target = permutation[m.Index1];
+      int edge2source = permutation[m.Index2];
+      int edge2target = permutation.GetCircular(m.Index2 + 1);
+      double moveQuality = 0;
+      // remove two edges
+      moveQuality -= distanceMatrix[edge1source, edge1target];
+      moveQuality -= distanceMatrix[edge2source, edge2target];
+      // add two edges
+      moveQuality += distanceMatrix[edge1source, edge2source];
+      moveQuality += distanceMatrix[edge1target, edge2target];
+      return moveQuality;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptRoundedEuclideanPathMoveEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptRoundedEuclideanPathMoveEvaluator.cs	(revision 3209)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPTwoOptRoundedEuclideanPathMoveEvaluator.cs	(revision 3209)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate 2-opt moves.
+  /// </summary>
+  [Item("TSPTwoOptRoundedEuclideanPathMoveEvaluator", "Operator for evaluating a 2-opt move based on rounded euclidean distances.")]
+  [StorableClass]
+  public class TSPTwoOptRoundedEuclideanPathMoveEvaluator : TSPTwoOptPathMoveEvaluator {
+    public override Type EvaluatorType {
+      get { return typeof(TSPRoundedEuclideanPathEvaluator); }
+    }
+
+    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
+      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOptMoveTSPCoordinatesPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOptMoveTSPCoordinatesPathEvaluator.cs	(revision 3208)
+++ 	(revision )
@@ -1,98 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate 2-opt moves.
-  /// </summary>
-  [Item("TwoOptMoveTSPCoordinatesPathEvaluator", "Base class for evaluating 2-opt moves given the cities' coordinates.")]
-  [StorableClass]
-  public abstract class TwoOptMoveTSPCoordinatesPathEvaluator : TSPPathMoveEvaluator, ITwoOptPermutationMoveOperator {
-    public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
-      get { return (ILookupParameter<TwoOptMove>)Parameters["TwoOptMove"]; }
-    }
-
-    public TwoOptMoveTSPCoordinatesPathEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<TwoOptMove>("TwoOptMove", "The move to evaluate."));
-    }
-
-    public override IOperation Apply() {
-      Permutation permutation = PermutationParameter.ActualValue;
-      TwoOptMove move = TwoOptMoveParameter.ActualValue;
-      double moveQuality = QualityParameter.ActualValue.Value;
-      int edge1source = permutation.GetCircular(move.Index1 - 1);
-      int edge1target = permutation[move.Index1];
-      int edge2source = permutation[move.Index2];
-      int edge2target = permutation.GetCircular(move.Index2 + 1);
-
-      if (!(move.Index1 == 0 && move.Index2 == permutation.Length - 1)) { // a change like this would break the calculation (it doesn't actually change the quality anyway)
-        if (UseDistanceMatrixParameter.ActualValue.Value) {
-          DoubleMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
-          if (distanceMatrix == null) {
-            distanceMatrix = CalculateDistanceMatrix(CoordinatesParameter.ActualValue);
-            DistanceMatrixParameter.ActualValue = distanceMatrix;
-          }
-          // remove two edges
-          moveQuality -= distanceMatrix[edge1source, edge1target];
-          moveQuality -= distanceMatrix[edge2source, edge2target];
-          // add two edges
-          moveQuality += distanceMatrix[edge1source, edge2source];
-          moveQuality += distanceMatrix[edge1target, edge2target];
-        } else {
-          DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
-          // remove two edges
-          moveQuality -= CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
-            coordinates[edge1target, 0], coordinates[edge1target, 1]);
-          moveQuality -= CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
-            coordinates[edge2target, 0], coordinates[edge2target, 1]);
-          // add two edges
-          moveQuality += CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
-            coordinates[edge2source, 0], coordinates[edge2source, 1]);
-          moveQuality += CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
-            coordinates[edge2target, 0], coordinates[edge2target, 1]);
-        }
-      }
-      if (MoveQualityParameter.ActualValue == null) MoveQualityParameter.ActualValue = new DoubleValue(moveQuality);
-      else MoveQualityParameter.ActualValue.Value = moveQuality;
-      return base.Apply();
-    }
-
-    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
-
-    protected DoubleMatrix CalculateDistanceMatrix(DoubleMatrix c) {
-      DoubleMatrix distanceMatrix = new DoubleMatrix(c.Rows, c.Rows);
-      for (int i = 0; i < distanceMatrix.Rows; i++) {
-        for (int j = 0; j < distanceMatrix.Columns; j++)
-          distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);
-      }
-      return distanceMatrix;
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOptMoveTSPRoundedEuclideanPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOptMoveTSPRoundedEuclideanPathEvaluator.cs	(revision 3208)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate 2-opt moves.
-  /// </summary>
-  [Item("TwoOptMoveTSPRoundedEuclideanPathEvaluator", "Evaluates a 2-opt move (rounded euclidean distances) by summing up the length of all added edges and subtracting the length of all deleted edges.")]
-  [StorableClass]
-  public class TwoOptMoveTSPRoundedEuclideanPathEvaluator : TwoOptMoveTSPCoordinatesPathEvaluator {
-    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
-      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 3208)
+++ trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 3209)
@@ -253,4 +253,5 @@
       Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       ParameterizeEvaluator();
+      UpdateMoveEvaluators();
       ParameterizeVisualizer();
       ClearDistanceMatrix();
@@ -296,4 +297,5 @@
       if (ApplicationManager.Manager != null) operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>());
       ParameterizeOperators();
+      UpdateMoveEvaluators();
       InitializeMoveGenerators();
     }
@@ -308,4 +310,16 @@
           op.ThreeOptMoveParameter.ActualNameChanged += new EventHandler(MoveGenerator_ThreeOptMoveParameter_ActualNameChanged);
         }
+      }
+    }
+    private void UpdateMoveEvaluators() {
+      if (ApplicationManager.Manager != null) {
+        foreach (ITSPPathMoveEvaluator op in Operators.OfType<ITSPPathMoveEvaluator>().ToList())
+          operators.Remove(op);
+        foreach (ITSPPathMoveEvaluator op in ApplicationManager.Manager.GetInstances<ITSPPathMoveEvaluator>())
+          if (op.EvaluatorType == Evaluator.GetType()) {
+            operators.Add(op);
+          }
+        ParameterizeOperators();
+        OnOperatorsChanged();
       }
     }
@@ -347,4 +361,6 @@
         op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
         op.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
+        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
       }
     }
