Index: /branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRAlgorithm.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRAlgorithm.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRAlgorithm.cs	(revision 14454)
@@ -557,5 +557,7 @@
         || Context.Population.Any(p => IsBetter(offspring, p))) return offspring;
 
-      if (HillclimbingSuited(offspring))
+      if (IsBetter(offspring.Fitness, Context.BestQuality))
+        HillClimb(offspring, token); // perform hillclimb in full solution space
+      else if (HillclimbingSuited(offspring))
         HillClimb(offspring, token, subspace); // perform hillclimb in the solution sub-space
       return offspring;
@@ -587,6 +589,8 @@
       if (dist1 > 0 && dist2 > 0) {
         var subspace = CalculateSubspace(new[] { a.Solution, b.Solution }, inverse: true);
-        if (HillclimbingSuited(child)) {
-          HillClimb(child, token, subspace);
+        if (IsBetter(child.Fitness, Context.BestQuality))
+          HillClimb(child, token); // perform hillclimb in full solution space
+        else if (HillclimbingSuited(child)) {
+          HillClimb(child, token, subspace); // perform hillclimb in solution sub-space
         }
       }
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/HeuristicLab.Problems.TravelingSalesman.Views-3.3.csproj
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/HeuristicLab.Problems.TravelingSalesman.Views-3.3.csproj	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/HeuristicLab.Problems.TravelingSalesman.Views-3.3.csproj	(revision 14454)
@@ -230,4 +230,9 @@
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="TravelingSalesmanProblemView.resx">
+      <DependentUpon>TravelingSalesmanProblemView.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.Designer.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.Designer.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.Designer.cs	(revision 14454)
@@ -45,4 +45,5 @@
       this.visualizationTabPage = new System.Windows.Forms.TabPage();
       this.pathTSPTourView = new HeuristicLab.Problems.TravelingSalesman.Views.PathTSPTourView();
+      this.updateDistanceMatrixButton = new System.Windows.Forms.Button();
       ((System.ComponentModel.ISupportInitialize)(this.problemInstanceSplitContainer)).BeginInit();
       this.problemInstanceSplitContainer.Panel1.SuspendLayout();
@@ -60,4 +61,5 @@
       // problemInstanceSplitContainer.Panel2
       // 
+      this.problemInstanceSplitContainer.Panel2.Controls.Add(this.updateDistanceMatrixButton);
       this.problemInstanceSplitContainer.Panel2.Controls.Add(this.tabControl);
       // 
@@ -67,5 +69,5 @@
       this.parameterCollectionView.Dock = System.Windows.Forms.DockStyle.Fill;
       this.parameterCollectionView.Location = new System.Drawing.Point(3, 3);
-      this.parameterCollectionView.Size = new System.Drawing.Size(497, 274);
+      this.parameterCollectionView.Size = new System.Drawing.Size(497, 245);
       // 
       // nameTextBox
@@ -77,13 +79,13 @@
       // 
       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);
-      this.tabControl.Location = new System.Drawing.Point(0, 27);
+      this.tabControl.Location = new System.Drawing.Point(0, 56);
       this.tabControl.Name = "tabControl";
       this.tabControl.SelectedIndex = 0;
-      this.tabControl.Size = new System.Drawing.Size(511, 306);
+      this.tabControl.Size = new System.Drawing.Size(511, 277);
       this.tabControl.TabIndex = 4;
       // 
@@ -94,5 +96,5 @@
       this.parametersTabPage.Name = "parametersTabPage";
       this.parametersTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.parametersTabPage.Size = new System.Drawing.Size(503, 280);
+      this.parametersTabPage.Size = new System.Drawing.Size(503, 251);
       this.parametersTabPage.TabIndex = 0;
       this.parametersTabPage.Text = "Parameters";
@@ -112,7 +114,7 @@
       // pathTSPTourView
       // 
-      this.pathTSPTourView.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.pathTSPTourView.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.pathTSPTourView.Caption = "PathTSPTour View";
       this.pathTSPTourView.Content = null;
@@ -123,7 +125,16 @@
       this.pathTSPTourView.TabIndex = 0;
       // 
+      // updateDistanceMatrixButton
+      // 
+      this.updateDistanceMatrixButton.Location = new System.Drawing.Point(3, 27);
+      this.updateDistanceMatrixButton.Name = "updateDistanceMatrixButton";
+      this.updateDistanceMatrixButton.Size = new System.Drawing.Size(133, 23);
+      this.updateDistanceMatrixButton.TabIndex = 5;
+      this.updateDistanceMatrixButton.Text = "Update Distance Matrix";
+      this.updateDistanceMatrixButton.UseVisualStyleBackColor = true;
+      this.updateDistanceMatrixButton.Click += new System.EventHandler(this.updateDistanceMatrixButton_Click);
+      // 
       // TravelingSalesmanProblemView
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
       this.Name = "TravelingSalesmanProblemView";
@@ -148,4 +159,5 @@
     private System.Windows.Forms.TabPage visualizationTabPage;
     private PathTSPTourView pathTSPTourView;
+    private System.Windows.Forms.Button updateDistanceMatrixButton;
   }
 }
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.cs	(revision 14454)
@@ -22,4 +22,5 @@
 using System;
 using System.Windows.Forms;
+using HeuristicLab.Data;
 using HeuristicLab.MainForm;
 using HeuristicLab.Optimization.Views;
@@ -46,5 +47,5 @@
     protected override void DeregisterContentEvents() {
       Content.CoordinatesParameter.ValueChanged -= new EventHandler(CoordinatesParameter_ValueChanged);
-      Content.BestKnownQualityParameter.ValueChanged -= new EventHandler(BestKnownQualityParameter_ValueChanged);
+      //Content.BestKnownQualityParameter.ValueChanged -= new EventHandler(BestKnownQualityParameter_ValueChanged);
       Content.BestKnownSolutionParameter.ValueChanged -= new EventHandler(BestKnownSolutionParameter_ValueChanged);
       base.DeregisterContentEvents();
@@ -53,5 +54,5 @@
       base.RegisterContentEvents();
       Content.CoordinatesParameter.ValueChanged += new EventHandler(CoordinatesParameter_ValueChanged);
-      Content.BestKnownQualityParameter.ValueChanged += new EventHandler(BestKnownQualityParameter_ValueChanged);
+      //Content.BestKnownQualityParameter.ValueChanged += new EventHandler(BestKnownQualityParameter_ValueChanged);
       Content.BestKnownSolutionParameter.ValueChanged += new EventHandler(BestKnownSolutionParameter_ValueChanged);
     }
@@ -62,5 +63,5 @@
         pathTSPTourView.Content = null;
       } else {
-        pathTSPTourView.Content = new PathTSPTour(Content.Coordinates, Content.BestKnownSolution, Content.BestKnownQuality);
+        pathTSPTourView.Content = new PathTSPTour(Content.Coordinates, Content.BestKnownSolution, new DoubleValue(Content.BestKnownQuality));
       }
     }
@@ -69,4 +70,5 @@
       base.SetEnabledStateOfControls();
       pathTSPTourView.Enabled = Content != null;
+      updateDistanceMatrixButton.Enabled = Content != null && !ReadOnly && !Locked;
     }
 
@@ -75,9 +77,13 @@
     }
     private void BestKnownQualityParameter_ValueChanged(object sender, EventArgs e) {
-      pathTSPTourView.Content.Quality = Content.BestKnownQuality;
+      pathTSPTourView.Content.Quality = new DoubleValue(Content.BestKnownQuality);
     }
     private void BestKnownSolutionParameter_ValueChanged(object sender, EventArgs e) {
       pathTSPTourView.Content.Permutation = Content.BestKnownSolution;
     }
+
+    private void updateDistanceMatrixButton_Click(object sender, EventArgs e) {
+      Content.UpdateDistanceMatrix();
+    }
   }
 }
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.resx
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.resx	(revision 14454)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TravelingSalesmanProblemView.resx	(revision 14454)
@@ -0,0 +1,126 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>140, 17</value>
+  </metadata>
+</root>
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/DistanceMatrix.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/DistanceMatrix.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/DistanceMatrix.cs	(revision 14454)
@@ -44,4 +44,7 @@
     public DistanceMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
     public DistanceMatrix(double[,] elements) : base(elements) { }
+    public DistanceMatrix(double[,] elements, bool readOnly) : base(elements) {
+      this.readOnly = readOnly;
+    }
     public DistanceMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
     public DistanceMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj	(revision 14454)
@@ -122,20 +122,8 @@
     <Compile Include="Analyzers\TSPAlleleFrequencyAnalyzer.cs" />
     <Compile Include="DistanceMatrix.cs" />
-    <Compile Include="Evaluators\TSPDistanceMatrixEvaluator.cs" />
-    <Compile Include="Evaluators\TSPEuclideanPathEvaluator.cs" />
-    <Compile Include="Evaluators\TSPGeoPathEvaluator.cs" />
-    <Compile Include="Evaluators\TSPUpperEuclideanPathEvaluator.cs" />
     <Compile Include="Improvers\TSPImprovementOperator.cs" />
     <Compile Include="Interfaces\ITSPDistanceMatrixEvaluator.cs" />
-    <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveDistanceMatrixEvaluator.cs" />
-    <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveEuclideanPathEvaluator.cs" />
-    <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveGeoPathEvaluator.cs" />
     <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMovePathEvaluator.cs" />
-    <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveRoundedEuclideanPathEvaluator.cs" />
-    <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveEuclideanPathEvaluator.cs" />
-    <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveGeoPathEvaluator.cs" />
-    <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveDistanceMatrixEvaluator.cs" />
     <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMovePathEvaluator.cs" />
-    <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveRoundedEuclideanPathEvaluator.cs" />
     <Compile Include="PathRelinkers\TSPMultipleGuidesPathRelinker.cs" />
     <Compile Include="PathRelinkers\TSPPathRelinker.cs" />
@@ -145,7 +133,4 @@
     <Compile Include="TravelingSalesmanProblem.cs" />
     <Compile Include="PathTSPTour.cs" />
-    <Compile Include="Evaluators\TSPCoordinatesPathEvaluator.cs" />
-    <Compile Include="Evaluators\TSPEvaluator.cs" />
-    <Compile Include="Evaluators\TSPRoundedEuclideanPathEvaluator.cs" />
     <Compile Include="Interfaces\ITSPCoordinatesPathEvaluator.cs" />
     <Compile Include="Interfaces\ITSPEvaluator.cs" />
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 14454)
@@ -24,6 +24,4 @@
 
 namespace HeuristicLab.Problems.TravelingSalesman {
-  public interface ITSPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator {
-    Type EvaluatorType { get; }
-  }
+  public interface ITSPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator { }
 }
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs	(revision 14454)
@@ -26,4 +26,5 @@
 namespace HeuristicLab.Problems.TravelingSalesman {
   public interface ITSPPathMoveEvaluator : ITSPMoveEvaluator, IPermutationMoveOperator {
+    ILookupParameter<EnumValue<TSPDistanceFunction>> DistanceFunctionParameter { get; }
     ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
     ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 14454)
@@ -36,6 +36,5 @@
   [StorableClass]
   public abstract class TSPMoveEvaluator : SingleSuccessorOperator, ITSPMoveEvaluator, IMoveOperator {
-
-    public abstract Type EvaluatorType { get; }
+    
     public override bool CanChangeName {
       get { return false; }
Index: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 14454)
@@ -47,4 +47,7 @@
       get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
     }
+    public ILookupParameter<EnumValue<TSPDistanceFunction>> DistanceFunctionParameter {
+      get { return (ILookupParameter<EnumValue<TSPDistanceFunction>>)Parameters["DistanceFunction"]; }
+    }
 
     [StorableConstructor]
@@ -57,34 +60,21 @@
       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."));
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      // BackwardsCompatibility3.3
-      #region Backwards compatible code (remove with 3.4)
-      LookupParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as LookupParameter<DoubleMatrix>;
-      if (oldDistanceMatrixParameter != null) {
-        Parameters.Remove(oldDistanceMatrixParameter);
-        Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-        DistanceMatrixParameter.ActualName = oldDistanceMatrixParameter.ActualName;
-      }
-      #endregion
+      Parameters.Add(new LookupParameter<EnumValue<TSPDistanceFunction>>("DistanceFunction", "The distance function to use when the distance matrix is not being used."));
     }
 
     public override IOperation Apply() {
-      Permutation permutation = PermutationParameter.ActualValue;
-      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
+      var permutation = PermutationParameter.ActualValue;
+      var coordinates = CoordinatesParameter.ActualValue;
+      var distanceFunction = DistanceFunctionParameter.ActualValue.Value;
       double relativeQualityDifference = 0;
       if (UseDistanceMatrixParameter.ActualValue.Value) {
         DistanceMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
         if (distanceMatrix == null) {
-          if (coordinates == null) throw new InvalidOperationException("Neither a distance matrix nor coordinates were given.");
-          distanceMatrix = CalculateDistanceMatrix(coordinates);
-          DistanceMatrixParameter.ActualValue = distanceMatrix;
+          throw new InvalidOperationException("Distance matrix is not given.");
         }
         relativeQualityDifference = EvaluateByDistanceMatrix(permutation, distanceMatrix);
       } else {
         if (coordinates == null) throw new InvalidOperationException("No coordinates were given.");
-        relativeQualityDifference = EvaluateByCoordinates(permutation, coordinates);
+        relativeQualityDifference = EvaluateByCoordinates(permutation, coordinates, distanceFunction);
       }
       DoubleValue moveQuality = MoveQualityParameter.ActualValue;
@@ -93,17 +83,6 @@
       return base.Apply();
     }
-
-    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
     protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix);
-    protected abstract double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates);
-
-    private DistanceMatrix CalculateDistanceMatrix(DoubleMatrix c) {
-      DistanceMatrix distanceMatrix = new DistanceMatrix(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)distanceMatrix.AsReadOnly();
-    }
+    protected abstract double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction);
   }
 }
Index: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveDistanceMatrixEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveDistanceMatrixEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,79 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <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.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate inversion moves (2-opt).
-  /// </summary>
-  [Item("TSPTranslocationMoveDistanceMatrixEvaluator", "Evaluates a translocation or insertion move (3-opt).")]
-  [StorableClass]
-  public class TSPTranslocationMoveDistanceMatrixEvaluator : TSPMoveEvaluator, IPermutationTranslocationMoveOperator {
-    public override Type EvaluatorType {
-      get { return typeof(TSPDistanceMatrixEvaluator); }
-    }
-
-    public ILookupParameter<Permutation> PermutationParameter {
-      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
-    }
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
-      get { return (ILookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
-    }
-
-    [StorableConstructor]
-    protected TSPTranslocationMoveDistanceMatrixEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPTranslocationMoveDistanceMatrixEvaluator(TSPTranslocationMoveDistanceMatrixEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPTranslocationMoveDistanceMatrixEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move to evaluate."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPTranslocationMoveDistanceMatrixEvaluator(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      var permutation = PermutationParameter.ActualValue;
-      double relativeQualityDifference = 0;
-      var distanceMatrix = DistanceMatrixParameter.ActualValue;
-      if (distanceMatrix == null) throw new InvalidOperationException("The distance matrix is not given.");
-      var move = TranslocationMoveParameter.ActualValue;
-      relativeQualityDifference = TSPTranslocationMovePathEvaluator.EvaluateByDistanceMatrix(permutation, move, distanceMatrix);
-
-      var moveQuality = MoveQualityParameter.ActualValue;
-      if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(QualityParameter.ActualValue.Value + relativeQualityDifference);
-      else moveQuality.Value = QualityParameter.ActualValue.Value + relativeQualityDifference;
-      return base.Apply();
-    }
-  }
-}
Index: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveEuclideanPathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveEuclideanPathEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,51 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate translocation or insertion moves (3-opt).
-  /// </summary>
-  [Item("TSPTranslocationMoveEuclideanPathEvaluator", "Operator for evaluating a translocation or insertion move (3-opt) based on euclidean distances.")]
-  [StorableClass]
-  public class TSPTranslocationMoveEuclideanPathEvaluator : TSPTranslocationMovePathEvaluator {
-    [StorableConstructor]
-    protected TSPTranslocationMoveEuclideanPathEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPTranslocationMoveEuclideanPathEvaluator(TSPTranslocationMoveEuclideanPathEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPTranslocationMoveEuclideanPathEvaluator() : base() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPTranslocationMoveEuclideanPathEvaluator(this, cloner);
-    }
-    
-    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: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveGeoPathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveGeoPathEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,81 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate translocation or insertion moves (3-opt).
-  /// </summary>
-  [Item("TSPTranslocationMoveGeoPathEvaluator", "Operator for evaluating a translocation or insertion move (3-opt) based on geo (world) distances.")]
-  [StorableClass]
-  public class TSPTranslocationMoveGeoPathEvaluator : TSPTranslocationMovePathEvaluator {
-    public override Type EvaluatorType {
-      get { return typeof(TSPGeoPathEvaluator); }
-    }
-
-    private const double PI = 3.141592;
-    private const double RADIUS = 6378.388;
-
-    [StorableConstructor]
-    protected TSPTranslocationMoveGeoPathEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPTranslocationMoveGeoPathEvaluator(TSPTranslocationMoveGeoPathEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPTranslocationMoveGeoPathEvaluator() : base() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPTranslocationMoveGeoPathEvaluator(this, cloner);
-    }
-    
-
-    /// <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: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs	(revision 14454)
@@ -46,5 +46,5 @@
     }
 
-    public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, TSPTranslocationMovePathEvaluator evaluator) {
+    public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) {
       if (move.Index1 == move.Index3
         || move.Index2 == permutation.Length - 1 && move.Index3 == 0
@@ -65,16 +65,16 @@
       double moveQuality = 0;
       // remove three edges
-      moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+      moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1],
         coordinates[edge1target, 0], coordinates[edge1target, 1]);
-      moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+      moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge2source, 0], coordinates[edge2source, 1],
         coordinates[edge2target, 0], coordinates[edge2target, 1]);
-      moveQuality -= evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
+      moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge3source, 0], coordinates[edge3source, 1],
         coordinates[edge3target, 0], coordinates[edge3target, 1]);
       // add three edges
-      moveQuality += evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
+      moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge3source, 0], coordinates[edge3source, 1],
         coordinates[edge1target, 0], coordinates[edge1target, 1]);
-      moveQuality += evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+      moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge2source, 0], coordinates[edge2source, 1],
         coordinates[edge3target, 0], coordinates[edge3target, 1]);
-      moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+      moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1],
         coordinates[edge2target, 0], coordinates[edge2target, 1]);
       return moveQuality;
@@ -110,6 +110,6 @@
     }
 
-    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates) {
-      return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, this);
+    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) {
+      return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, distanceFunction);
     }
 
Index: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveRoundedEuclideanPathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveRoundedEuclideanPathEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,51 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate translocation or insertion moves (3-opt).
-  /// </summary>
-  [Item("TSPTranslocationMoveRoundedEuclideanPathEvaluator", "Operator for evaluating a translocation or insertion move (3-opt) based on rounded euclidean distances.")]
-  [StorableClass]
-  public class TSPTranslocationMoveRoundedEuclideanPathEvaluator : TSPTranslocationMovePathEvaluator {
-    [StorableConstructor]
-    protected TSPTranslocationMoveRoundedEuclideanPathEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPTranslocationMoveRoundedEuclideanPathEvaluator(TSPTranslocationMoveRoundedEuclideanPathEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPTranslocationMoveRoundedEuclideanPathEvaluator() : base() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPTranslocationMoveRoundedEuclideanPathEvaluator(this, cloner);
-    }
-    
-    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: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveDistanceMatrixEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveDistanceMatrixEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,79 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <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.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate inversion moves (2-opt).
-  /// </summary>
-  [Item("TSPInversionMoveDistanceMatrixEvaluator", "Evaluates an inversion move (2-opt) by summing up the length of all added edges and subtracting the length of all deleted edges.")]
-  [StorableClass]
-  public class TSPInversionMoveDistanceMatrixEvaluator : TSPMoveEvaluator, IPermutationInversionMoveOperator {
-    public override Type EvaluatorType {
-      get { return typeof(TSPDistanceMatrixEvaluator); }
-    }
-
-    public ILookupParameter<Permutation> PermutationParameter {
-      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
-    }
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ILookupParameter<InversionMove> InversionMoveParameter {
-      get { return (ILookupParameter<InversionMove>)Parameters["InversionMove"]; }
-    }
-
-    [StorableConstructor]
-    protected TSPInversionMoveDistanceMatrixEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPInversionMoveDistanceMatrixEvaluator(TSPInversionMoveDistanceMatrixEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPInversionMoveDistanceMatrixEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPInversionMoveDistanceMatrixEvaluator(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      var permutation = PermutationParameter.ActualValue;
-      double relativeQualityDifference = 0;
-      var distanceMatrix = DistanceMatrixParameter.ActualValue;
-      if (distanceMatrix == null) throw new InvalidOperationException("The distance matrix is not given.");
-      var move = InversionMoveParameter.ActualValue;
-      relativeQualityDifference = TSPInversionMovePathEvaluator.EvaluateByDistanceMatrix(permutation, move, distanceMatrix);
-
-      var moveQuality = MoveQualityParameter.ActualValue;
-      if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(QualityParameter.ActualValue.Value + relativeQualityDifference);
-      else moveQuality.Value = QualityParameter.ActualValue.Value + relativeQualityDifference;
-      return base.Apply();
-    }
-  }
-}
Index: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveEuclideanPathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveEuclideanPathEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,51 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate 2-opt moves.
-  /// </summary>
-  [Item("TSPInversionMoveEuclideanPathEvaluator", "Operator for evaluating an inversion move (2-opt) based on euclidean distances.")]
-  [StorableClass]
-  public class TSPInversionMoveEuclideanPathEvaluator : TSPInversionMovePathEvaluator {
-    [StorableConstructor]
-    protected TSPInversionMoveEuclideanPathEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPInversionMoveEuclideanPathEvaluator(TSPInversionMoveEuclideanPathEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPInversionMoveEuclideanPathEvaluator() : base() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPInversionMoveEuclideanPathEvaluator(this, cloner);
-    }
-    
-    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: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveGeoPathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveGeoPathEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,80 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate inversion moves (2-opt).
-  /// </summary>
-  [Item("TSPInversionMoveGeoPathEvaluator", "Operator for evaluating an inversion move (2-opt) based on geo (world) distances.")]
-  [StorableClass]
-  public class TSPInversionMoveGeoPathEvaluator : TSPInversionMovePathEvaluator {
-    public override Type EvaluatorType {
-      get { return typeof(TSPGeoPathEvaluator); }
-    }
-
-    private const double PI = 3.141592;
-    private const double RADIUS = 6378.388;
-
-    [StorableConstructor]
-    protected TSPInversionMoveGeoPathEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPInversionMoveGeoPathEvaluator(TSPInversionMoveGeoPathEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPInversionMoveGeoPathEvaluator() : base() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPInversionMoveGeoPathEvaluator(this, cloner);
-    }
-    
-    /// <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: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs	(revision 14454)
@@ -33,5 +33,5 @@
   [Item("TSPInversionMovePathEvaluator", "Evaluates an inversion move (2-opt) by summing up the length of all added edges and subtracting the length of all deleted edges.")]
   [StorableClass]
-  public abstract class TSPInversionMovePathEvaluator : TSPPathMoveEvaluator, IPermutationInversionMoveOperator {
+  public class TSPInversionMovePathEvaluator : TSPPathMoveEvaluator, IPermutationInversionMoveOperator {
     public ILookupParameter<InversionMove> InversionMoveParameter {
       get { return (ILookupParameter<InversionMove>)Parameters["InversionMove"]; }
@@ -46,5 +46,9 @@
     }
 
-    public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, TSPInversionMovePathEvaluator evaluator) {
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPInversionMovePathEvaluator(this, cloner);
+    }
+
+    public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) {
       int edge1source = permutation.GetCircular(move.Index1 - 1);
       int edge1target = permutation[move.Index1];
@@ -54,12 +58,12 @@
       double moveQuality = 0;
       // remove two edges
-      moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+      moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1],
             coordinates[edge1target, 0], coordinates[edge1target, 1]);
-      moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+      moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge2source, 0], coordinates[edge2source, 1],
         coordinates[edge2target, 0], coordinates[edge2target, 1]);
       // add two edges
-      moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+      moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1],
         coordinates[edge2source, 0], coordinates[edge2source, 1]);
-      moveQuality += evaluator.CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
+      moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1target, 0], coordinates[edge1target, 1],
         coordinates[edge2target, 0], coordinates[edge2target, 1]);
       return moveQuality;
@@ -82,6 +86,6 @@
     }
 
-    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates) {
-      return EvaluateByCoordinates(permutation, InversionMoveParameter.ActualValue, coordinates, this);
+    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) {
+      return EvaluateByCoordinates(permutation, InversionMoveParameter.ActualValue, coordinates, distanceFunction);
     }
 
Index: anches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveRoundedEuclideanPathEvaluator.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveRoundedEuclideanPathEvaluator.cs	(revision 14453)
+++ 	(revision )
@@ -1,51 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TravelingSalesman {
-  /// <summary>
-  /// An operator to evaluate inversion moves (2-opt).
-  /// </summary>
-  [Item("TSPInversionMoveRoundedEuclideanPathEvaluator", "Operator for evaluating an inversion move (2-opt) based on rounded euclidean distances.")]
-  [StorableClass]
-  public class TSPInversionMoveRoundedEuclideanPathEvaluator : TSPInversionMovePathEvaluator {
-    [StorableConstructor]
-    protected TSPInversionMoveRoundedEuclideanPathEvaluator(bool deserializing) : base(deserializing) { }
-    protected TSPInversionMoveRoundedEuclideanPathEvaluator(TSPInversionMoveRoundedEuclideanPathEvaluator original, Cloner cloner) : base(original, cloner) { }
-    public TSPInversionMoveRoundedEuclideanPathEvaluator() : base() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TSPInversionMoveRoundedEuclideanPathEvaluator(this, cloner);
-    }
-    
-    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: /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs
===================================================================
--- /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 14453)
+++ /branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 14454)
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -37,43 +36,66 @@
 
 namespace HeuristicLab.Problems.TravelingSalesman {
+  public enum TSPDistanceFunction { Euclidean, RoundedEuclidean, UpperEuclidean, Geo, DistanceMatrix };
+
   [Item("Traveling Salesman Problem (TSP)", "Represents a symmetric Traveling Salesman Problem.")]
-  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 100)]
+  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 999)]
   [StorableClass]
-  public sealed class TravelingSalesmanProblem : SingleObjectiveHeuristicOptimizationProblem<ITSPEvaluator, IPermutationCreator>, IStorableContent,
-    IProblemInstanceConsumer<TSPData> {
+  public sealed class TravelingSalesmanProblem : SingleObjectiveBasicProblem<PermutationEncoding>, IStorableContent, IProblemInstanceConsumer<TSPData> {
+    public const double PI = 3.141592;
+    public const double RADIUS = 6378.388;
     private static readonly int DistanceMatrixSizeLimit = 1000;
-    public string Filename { get; set; }
+
+    public override bool Maximization {
+      get { return false; }
+    }
 
     #region Parameter Properties
+    [Storable]
+    private IFixedValueParameter<EnumValue<TSPDistanceFunction>> distanceFunctionParameter;
+    public IFixedValueParameter<EnumValue<TSPDistanceFunction>> DistanceFunctionParameter {
+      get { return distanceFunctionParameter; }
+    }
+    [Storable]
+    private OptionalValueParameter<DoubleMatrix> coordinatesParameter;
     public OptionalValueParameter<DoubleMatrix> CoordinatesParameter {
-      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
-    }
+      get { return coordinatesParameter; }
+    }
+    [Storable]
+    private OptionalValueParameter<DistanceMatrix> distanceMatrixParameter;
     public OptionalValueParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (OptionalValueParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ValueParameter<BoolValue> UseDistanceMatrixParameter {
-      get { return (ValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
-    }
+      get { return distanceMatrixParameter; }
+    }
+    [Storable]
+    private IFixedValueParameter<BoolValue> useDistanceMatrixParameter;
+    public IFixedValueParameter<BoolValue> UseDistanceMatrixParameter {
+      get { return useDistanceMatrixParameter; }
+    }
+    [Storable]
+    private OptionalValueParameter<Permutation> bestKnownSolutionParameter;
     public OptionalValueParameter<Permutation> BestKnownSolutionParameter {
-      get { return (OptionalValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
+      get { return bestKnownSolutionParameter; }
     }
     #endregion
 
     #region Properties
+    public TSPDistanceFunction DistanceFunction {
+      get { return distanceFunctionParameter.Value.Value; }
+      set { distanceFunctionParameter.Value.Value = value; }
+    }
     public DoubleMatrix Coordinates {
-      get { return CoordinatesParameter.Value; }
-      set { CoordinatesParameter.Value = value; }
+      get { return coordinatesParameter.Value; }
+      set { coordinatesParameter.Value = value; }
     }
     public DistanceMatrix DistanceMatrix {
-      get { return DistanceMatrixParameter.Value; }
-      set { DistanceMatrixParameter.Value = value; }
-    }
-    public BoolValue UseDistanceMatrix {
-      get { return UseDistanceMatrixParameter.Value; }
-      set { UseDistanceMatrixParameter.Value = value; }
+      get { return distanceMatrixParameter.Value; }
+      set { distanceMatrixParameter.Value = value; }
+    }
+    public bool UseDistanceMatrix {
+      get { return useDistanceMatrixParameter.Value.Value; }
+      set { useDistanceMatrixParameter.Value.Value = value; }
     }
     public Permutation BestKnownSolution {
-      get { return BestKnownSolutionParameter.Value; }
-      set { BestKnownSolutionParameter.Value = value; }
+      get { return bestKnownSolutionParameter.Value; }
+      set { bestKnownSolutionParameter.Value = value; }
     }
     private BestTSPSolutionAnalyzer BestTSPSolutionAnalyzer {
@@ -82,17 +104,4 @@
     private TSPAlleleFrequencyAnalyzer TSPAlleleFrequencyAnalyzer {
       get { return Operators.OfType<TSPAlleleFrequencyAnalyzer>().FirstOrDefault(); }
-    }
-    #endregion
-
-    // BackwardsCompatibility3.3
-    #region Backwards compatible code, remove with 3.4
-    [Obsolete]
-    [Storable(Name = "operators")]
-    private IEnumerable<IOperator> oldOperators {
-      get { return null; }
-      set {
-        if (value != null && value.Any())
-          Operators.AddRange(value);
-      }
     }
     #endregion
@@ -102,4 +111,9 @@
     private TravelingSalesmanProblem(TravelingSalesmanProblem original, Cloner cloner)
       : base(original, cloner) {
+      distanceFunctionParameter = cloner.Clone(original.distanceFunctionParameter);
+      coordinatesParameter = cloner.Clone(original.coordinatesParameter);
+      distanceMatrixParameter = cloner.Clone(original.distanceMatrixParameter);
+      useDistanceMatrixParameter = cloner.Clone(original.useDistanceMatrixParameter);
+      bestKnownSolutionParameter = cloner.Clone(original.bestKnownSolutionParameter);
       RegisterEventHandlers();
     }
@@ -107,15 +121,15 @@
       return new TravelingSalesmanProblem(this, cloner);
     }
-    public TravelingSalesmanProblem()
-      : base(new TSPRoundedEuclideanPathEvaluator(), new RandomPermutationCreator()) {
-      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
-      Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new ValueParameter<BoolValue>("UseDistanceMatrix", "True if the coordinates based evaluators should calculate the distance matrix from the coordinates and use it for evaluation similar to the distance matrix evaluator, otherwise false.", new BoolValue(true)));
-      Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));
-
-      Maximization.Value = false;
-      MaximizationParameter.Hidden = true;
-      UseDistanceMatrixParameter.Hidden = true;
-      DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
+    public TravelingSalesmanProblem() : base() {
+      Encoding = new PermutationEncoding("TSPTour") { Length = 16 };
+
+      Parameters.Add(distanceFunctionParameter = new FixedValueParameter<EnumValue<TSPDistanceFunction>>("DistanceFunction", "The distance function that is used to calculate distance among the coordinates.", new EnumValue<TSPDistanceFunction>(TSPDistanceFunction.RoundedEuclidean)));
+      Parameters.Add(coordinatesParameter = new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
+      Parameters.Add(distanceMatrixParameter = new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(useDistanceMatrixParameter = new FixedValueParameter<BoolValue>("UseDistanceMatrix", "True if the coordinates based evaluators should calculate the distance matrix from the coordinates and use it for evaluation similar to the distance matrix evaluator, otherwise false.", new BoolValue(true)));
+      Parameters.Add(bestKnownSolutionParameter = new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));
+      
+      useDistanceMatrixParameter.Hidden = true;
+      distanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
 
       Coordinates = new DoubleMatrix(new double[,] {
@@ -125,105 +139,84 @@
         { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }
       });
-
-      SolutionCreator.PermutationParameter.ActualName = "TSPTour";
+      
       Evaluator.QualityParameter.ActualName = "TSPTourLength";
-      ParameterizeSolutionCreator();
-      ParameterizeEvaluator();
 
       InitializeOperators();
       RegisterEventHandlers();
     }
-
-    #region Events
-    protected override void OnSolutionCreatorChanged() {
-      base.OnSolutionCreatorChanged();
-      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
-      ParameterizeSolutionCreator();
-      ParameterizeEvaluator();
+    
+    #region Helpers
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    public override double Evaluate(Individual individual, IRandom random) {
+      var tour = individual.Permutation(Encoding.Name);
+      return Evaluate(tour);
+    }
+
+    public double Evaluate(Permutation tour) {
+      if (UseDistanceMatrix) return EvaluateWithDistanceMatrix(tour);
+
+      switch (DistanceFunction) {
+        case TSPDistanceFunction.DistanceMatrix:
+          return EvaluateWithDistanceMatrix(tour);
+        case TSPDistanceFunction.Euclidean:
+        case TSPDistanceFunction.RoundedEuclidean:
+        case TSPDistanceFunction.UpperEuclidean:
+        case TSPDistanceFunction.Geo:
+          return EvaluateWithDistanceCalculation(tour);
+        default: throw new InvalidOperationException(string.Format("Unknown distance function: {0}", DistanceFunction));
+      }
+    }
+
+    private double EvaluateWithDistanceMatrix(Permutation tour) {
+      var distances = DistanceMatrix;
+      double length = 0;
+      for (var i = 0; i < tour.Length - 1; i++)
+        length += distances[tour[i], tour[i + 1]];
+      length += distances[tour[tour.Length - 1], tour[0]];
+      return length;
+    }
+
+    private double EvaluateWithDistanceCalculation(Permutation tour) {
+      var coordinates = Coordinates;
+      var distanceFunction = DistanceFunction;
+      double length = 0;
+      for (var i = 0; i < tour.Length - 1; i++)
+        length += CalculateDistance(distanceFunction, coordinates[tour[i], 0], coordinates[tour[i], 1], coordinates[tour[i + 1], 0], coordinates[tour[i + 1], 1]);
+      length += CalculateDistance(distanceFunction, coordinates[tour[tour.Length - 1], 0], coordinates[tour[tour.Length - 1], 1], coordinates[tour[0], 0], coordinates[tour[0], 1]);
+      return length;
+    }
+
+    private void RegisterEventHandlers() {
+      coordinatesParameter.ValueChanged += coordinatesParameter_ValueChanged;
+      if (Coordinates != null) {
+        Coordinates.ItemChanged += Coordinates_ItemChanged;
+        Coordinates.Reset += Coordinates_Reset;
+      }
+      Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
+    }
+
+    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
       ParameterizeAnalyzers();
       ParameterizeOperators();
     }
-    protected override void OnEvaluatorChanged() {
-      base.OnEvaluatorChanged();
-      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
-      ParameterizeEvaluator();
-      ParameterizeSolutionCreator();
-      UpdateMoveEvaluators();
-      ParameterizeAnalyzers();
-      if (Evaluator is ITSPCoordinatesPathEvaluator && Coordinates != null)
-        ClearDistanceMatrix();
-    }
-    private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) {
+
+    private void Coordinates_Reset(object sender, EventArgs e) {
+      DistanceMatrix = null;
+    }
+
+    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
+      DistanceMatrix = null;
+    }
+
+    private void coordinatesParameter_ValueChanged(object sender, EventArgs e) {
       if (Coordinates != null) {
         Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
         Coordinates.Reset += new EventHandler(Coordinates_Reset);
-      }
-      if (Evaluator is ITSPCoordinatesPathEvaluator) {
-        ParameterizeSolutionCreator();
-        ClearDistanceMatrix();
-      }
-    }
-    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
-      if (Evaluator is ITSPCoordinatesPathEvaluator) {
-        ClearDistanceMatrix();
-      }
-    }
-    private void Coordinates_Reset(object sender, EventArgs e) {
-      if (Evaluator is ITSPCoordinatesPathEvaluator) {
-        ParameterizeSolutionCreator();
-        ClearDistanceMatrix();
-      }
-    }
-    private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeEvaluator();
-      ParameterizeAnalyzers();
-      ParameterizeOperators();
-    }
-    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeAnalyzers();
-    }
-    #endregion
-
-    #region Helpers
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      // BackwardsCompatibility3.3
-      #region Backwards compatible code (remove with 3.4)
-      OptionalValueParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as OptionalValueParameter<DoubleMatrix>;
-      if (oldDistanceMatrixParameter != null) {
-        Parameters.Remove(oldDistanceMatrixParameter);
-        Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-        DistanceMatrixParameter.GetsCollected = oldDistanceMatrixParameter.GetsCollected;
-        DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
-        if (oldDistanceMatrixParameter.Value != null) {
-          DoubleMatrix oldDM = oldDistanceMatrixParameter.Value;
-          DistanceMatrix newDM = new DistanceMatrix(oldDM.Rows, oldDM.Columns, oldDM.ColumnNames, oldDM.RowNames);
-          newDM.SortableView = oldDM.SortableView;
-          for (int i = 0; i < newDM.Rows; i++)
-            for (int j = 0; j < newDM.Columns; j++)
-              newDM[i, j] = oldDM[i, j];
-          DistanceMatrixParameter.Value = (DistanceMatrix)newDM.AsReadOnly();
-        }
-      }
-
-      ValueParameter<DoubleMatrix> oldCoordinates = (Parameters["Coordinates"] as ValueParameter<DoubleMatrix>);
-      if (oldCoordinates != null) {
-        Parameters.Remove(oldCoordinates);
-        Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.", oldCoordinates.Value, oldCoordinates.GetsCollected));
-      }
-
-      if (Operators.Count == 0) InitializeOperators();
-      #endregion
-      RegisterEventHandlers();
-    }
-
-    private void RegisterEventHandlers() {
-      CoordinatesParameter.ValueChanged += new EventHandler(CoordinatesParameter_ValueChanged);
-      if (Coordinates != null) {
-        Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
-        Coordinates.Reset += new EventHandler(Coordinates_Reset);
-      }
-      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
-      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+        DistanceMatrix = null;
+      }
     }
 
@@ -239,131 +232,78 @@
       Operators.Add(new TSPAlleleFrequencyAnalyzer());
       Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>()));
+      Operators.AddRange(ApplicationManager.Manager.GetInstances<ITSPMoveEvaluator>());
+
       ParameterizeAnalyzers();
-      var operators = new HashSet<IPermutationOperator>(new IPermutationOperator[] {
-        new OrderCrossover2(),
-        new InversionManipulator(),
-        new StochasticInversionMultiMoveGenerator()
-      }, new TypeEqualityComparer<IPermutationOperator>());
-      foreach (var op in ApplicationManager.Manager.GetInstances<IPermutationOperator>())
-        operators.Add(op);
-      Operators.AddRange(operators);
       ParameterizeOperators();
       UpdateMoveEvaluators();
     }
     private void UpdateMoveEvaluators() {
-      Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
-      foreach (var op in ApplicationManager.Manager.GetInstances<ITSPMoveEvaluator>())
-        if (op.EvaluatorType == Evaluator.GetType()) {
-          Operators.Add(op);
-        }
       ParameterizeOperators();
       OnOperatorsChanged();
-    }
-    private void ParameterizeSolutionCreator() {
-      if (Evaluator is ITSPDistanceMatrixEvaluator && DistanceMatrix != null)
-        SolutionCreator.LengthParameter.Value = new IntValue(DistanceMatrix.Rows);
-      else if (Evaluator is ITSPCoordinatesPathEvaluator && Coordinates != null)
-        SolutionCreator.LengthParameter.Value = new IntValue(Coordinates.Rows);
-      else {
-        SolutionCreator.LengthParameter.Value = null;
-        string error = "The given problem does not support the selected evaluator.";
-        if (Evaluator is ITSPDistanceMatrixEvaluator)
-          error += Environment.NewLine + "Please review that the " + DistanceMatrixParameter.Name + " parameter is defined or choose another evaluator.";
-        else error += Environment.NewLine + "Please review that the " + CoordinatesParameter.Name + " parameter is defined or choose another evaluator.";
-        PluginInfrastructure.ErrorHandling.ShowErrorDialog(error, null);
-      }
-      SolutionCreator.LengthParameter.Hidden = SolutionCreator.LengthParameter.Value != null;
-      SolutionCreator.PermutationTypeParameter.Value = new PermutationType(PermutationTypes.RelativeUndirected);
-      SolutionCreator.PermutationTypeParameter.Hidden = true;
-    }
-    private void ParameterizeEvaluator() {
-      if (Evaluator is ITSPPathEvaluator) {
-        ITSPPathEvaluator evaluator = (ITSPPathEvaluator)Evaluator;
-        evaluator.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
-        evaluator.PermutationParameter.Hidden = true;
-      }
-      if (Evaluator is ITSPCoordinatesPathEvaluator) {
-        ITSPCoordinatesPathEvaluator evaluator = (ITSPCoordinatesPathEvaluator)Evaluator;
-        evaluator.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
-        evaluator.CoordinatesParameter.Hidden = true;
-        evaluator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-        evaluator.DistanceMatrixParameter.Hidden = true;
-        evaluator.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
-        evaluator.UseDistanceMatrixParameter.Hidden = true;
-      }
-      if (Evaluator is ITSPDistanceMatrixEvaluator) {
-        var evaluator = (ITSPDistanceMatrixEvaluator)Evaluator;
-        evaluator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-        evaluator.DistanceMatrixParameter.Hidden = true;
-      }
     }
     private void ParameterizeAnalyzers() {
       if (BestTSPSolutionAnalyzer != null) {
         BestTSPSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
-        BestTSPSolutionAnalyzer.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
-        BestTSPSolutionAnalyzer.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        BestTSPSolutionAnalyzer.CoordinatesParameter.ActualName = coordinatesParameter.Name;
+        BestTSPSolutionAnalyzer.PermutationParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName;
         BestTSPSolutionAnalyzer.ResultsParameter.ActualName = "Results";
         BestTSPSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
-        BestTSPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
-        BestTSPSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
+        BestTSPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = bestKnownSolutionParameter.Name;
+        BestTSPSolutionAnalyzer.MaximizationParameter.ActualName = ((ISingleObjectiveHeuristicOptimizationProblem)this).MaximizationParameter.Name;
       }
 
       if (TSPAlleleFrequencyAnalyzer != null) {
-        TSPAlleleFrequencyAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
-        TSPAlleleFrequencyAnalyzer.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
-        TSPAlleleFrequencyAnalyzer.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-        TSPAlleleFrequencyAnalyzer.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        TSPAlleleFrequencyAnalyzer.MaximizationParameter.ActualName = ((ISingleObjectiveHeuristicOptimizationProblem)this).MaximizationParameter.Name;
+        TSPAlleleFrequencyAnalyzer.CoordinatesParameter.ActualName = coordinatesParameter.Name;
+        TSPAlleleFrequencyAnalyzer.DistanceMatrixParameter.ActualName = distanceMatrixParameter.Name;
+        TSPAlleleFrequencyAnalyzer.SolutionParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName;
         TSPAlleleFrequencyAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
-        TSPAlleleFrequencyAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
+        TSPAlleleFrequencyAnalyzer.BestKnownSolutionParameter.ActualName = bestKnownSolutionParameter.Name;
         TSPAlleleFrequencyAnalyzer.ResultsParameter.ActualName = "Results";
       }
     }
     private void ParameterizeOperators() {
-      foreach (IPermutationCrossover op in Operators.OfType<IPermutationCrossover>()) {
-        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
-        op.ParentsParameter.Hidden = true;
-        op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
-        op.ChildParameter.Hidden = true;
-      }
-      foreach (IPermutationManipulator op in Operators.OfType<IPermutationManipulator>()) {
-        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
-        op.PermutationParameter.Hidden = true;
-      }
-      foreach (IPermutationMoveOperator op in Operators.OfType<IPermutationMoveOperator>()) {
-        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
-        op.PermutationParameter.Hidden = true;
-      }
       foreach (ITSPPathMoveEvaluator op in Operators.OfType<ITSPPathMoveEvaluator>()) {
-        op.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
+        op.DistanceFunctionParameter.ActualName = distanceFunctionParameter.Name;
+        op.DistanceFunctionParameter.Hidden = true;
+        op.CoordinatesParameter.ActualName = coordinatesParameter.Name;
         op.CoordinatesParameter.Hidden = true;
-        op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
+        op.DistanceMatrixParameter.ActualName = distanceMatrixParameter.Name;
         op.DistanceMatrixParameter.Hidden = true;
-        op.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
+        op.UseDistanceMatrixParameter.ActualName = useDistanceMatrixParameter.Name;
         op.UseDistanceMatrixParameter.Hidden = true;
         op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
         op.QualityParameter.Hidden = true;
-        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.PermutationParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName;
         op.PermutationParameter.Hidden = true;
       }
-      foreach (IPermutationMultiNeighborhoodShakingOperator op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()) {
-        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
-        op.PermutationParameter.Hidden = true;
-      }
       foreach (ISingleObjectiveImprovementOperator op in Operators.OfType<ISingleObjectiveImprovementOperator>()) {
-        op.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.SolutionParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName;
         op.SolutionParameter.Hidden = true;
       }
       foreach (ISingleObjectivePathRelinker op in Operators.OfType<ISingleObjectivePathRelinker>()) {
-        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.ParentsParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName;
         op.ParentsParameter.Hidden = true;
       }
       foreach (ISolutionSimilarityCalculator op in Operators.OfType<ISolutionSimilarityCalculator>()) {
-        op.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName;
+        op.SolutionVariableName = Encoding.SolutionCreator.PermutationParameter.ActualName;
         op.QualityVariableName = Evaluator.QualityParameter.ActualName;
       }
     }
 
-    private void ClearDistanceMatrix() {
-      DistanceMatrixParameter.Value = null;
+    public void UpdateDistanceMatrix() {
+      var df = DistanceFunction;
+      var c = Coordinates;
+      if (c == null) throw new InvalidOperationException("No coordinates are given to calculate distance matrix.");
+      DistanceMatrix = CalculateDistanceMatrix(df, c);
+    }
+
+    public static DistanceMatrix CalculateDistanceMatrix(TSPDistanceFunction distance, DoubleMatrix coordinates) {
+      var dm = new double[coordinates.Rows, coordinates.Rows];
+      for (var i = 0; i < dm.GetLength(0); i++) {
+        for (var j = 0; j < dm.GetLength(1); j++)
+          dm[i, j] = CalculateDistance(distance, coordinates[i, 0], coordinates[i, 1], coordinates[j, 0], coordinates[j, 1]);
+      }
+      return new DistanceMatrix(dm, readOnly: true);
     }
     #endregion
@@ -381,50 +321,44 @@
       Name = data.Name;
       Description = data.Description;
-
-      bool clearCoordinates = false, clearDistanceMatrix = false;
+      
       if (data.Coordinates != null && data.Coordinates.GetLength(0) > 0)
         Coordinates = new DoubleMatrix(data.Coordinates);
-      else clearCoordinates = true;
-
-      TSPEvaluator evaluator;
+      else Coordinates = null;
+      
       if (data.DistanceMeasure == DistanceMeasure.Att
         || data.DistanceMeasure == DistanceMeasure.Manhattan
         || data.DistanceMeasure == DistanceMeasure.Maximum) {
-        evaluator = new TSPDistanceMatrixEvaluator();
-        UseDistanceMatrix = new BoolValue(true);
+        UseDistanceMatrix = true;
         DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix());
+        DistanceFunction = TSPDistanceFunction.DistanceMatrix;
       } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) {
-        evaluator = new TSPDistanceMatrixEvaluator();
-        UseDistanceMatrix = new BoolValue(true);
+        UseDistanceMatrix = true;
         DistanceMatrix = new DistanceMatrix(data.Distances);
+        DistanceFunction = TSPDistanceFunction.DistanceMatrix;
       } else {
-        clearDistanceMatrix = true;
-        UseDistanceMatrix = new BoolValue(data.Dimension <= DistanceMatrixSizeLimit);
+        UseDistanceMatrix = data.Dimension <= DistanceMatrixSizeLimit;
         switch (data.DistanceMeasure) {
           case DistanceMeasure.Euclidean:
-            evaluator = new TSPEuclideanPathEvaluator();
+            DistanceFunction = TSPDistanceFunction.Euclidean;
             break;
           case DistanceMeasure.RoundedEuclidean:
-            evaluator = new TSPRoundedEuclideanPathEvaluator();
+            DistanceFunction = TSPDistanceFunction.RoundedEuclidean;
             break;
           case DistanceMeasure.UpperEuclidean:
-            evaluator = new TSPUpperEuclideanPathEvaluator();
+            DistanceFunction = TSPDistanceFunction.UpperEuclidean;
             break;
           case DistanceMeasure.Geo:
-            evaluator = new TSPGeoPathEvaluator();
+            DistanceFunction = TSPDistanceFunction.Geo;
             break;
           default:
             throw new InvalidDataException("An unknown distance measure is given in the instance!");
         }
-      }
-      evaluator.QualityParameter.ActualName = "TSPTourLength";
-      Evaluator = evaluator;
-
-      // reset them after assigning the evaluator
-      if (clearCoordinates) Coordinates = null;
-      if (clearDistanceMatrix) DistanceMatrix = null;
-
+        if (UseDistanceMatrix) UpdateDistanceMatrix();
+        else DistanceMatrix = null;
+      }
+      Evaluator.QualityParameter.ActualName = "TSPTourLength";
+      
       BestKnownSolution = null;
-      BestKnownQuality = null;
+      BestKnownQualityParameter.Value = null;
 
       if (data.BestKnownTour != null) {
@@ -433,8 +367,8 @@
         } catch (InvalidOperationException) {
           if (data.BestKnownQuality.HasValue)
-            BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
+            BestKnownQuality = data.BestKnownQuality.Value;
         }
       } else if (data.BestKnownQuality.HasValue) {
-        BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
+        BestKnownQuality = data.BestKnownQuality.Value;
       }
       OnReset();
@@ -444,14 +378,53 @@
       var route = new Permutation(PermutationTypes.RelativeUndirected, tour);
       BestKnownSolution = route;
-
-      double quality;
-      if (Evaluator is ITSPDistanceMatrixEvaluator) {
-        quality = TSPDistanceMatrixEvaluator.Apply(DistanceMatrix, route);
-      } else if (Evaluator is ITSPCoordinatesPathEvaluator) {
-        quality = TSPCoordinatesPathEvaluator.Apply((TSPCoordinatesPathEvaluator)Evaluator, Coordinates, route);
-      } else {
-        throw new InvalidOperationException("Cannot calculate solution quality, evaluator type is unknown.");
-      }
-      BestKnownQuality = new DoubleValue(quality);
+      BestKnownQuality = Evaluate(route);
+    }
+
+    public static double CalculateDistance(TSPDistanceFunction distanceFunction, double x1, double y1, double x2, double y2) {
+      switch (distanceFunction) {
+        case TSPDistanceFunction.Euclidean:
+          return CalculateEuclideanDistance(x1, y1, x2, y2);
+        case TSPDistanceFunction.RoundedEuclidean:
+          return CalculateRoundedEuclideanDistance(x1, y1, x2, y2);
+        case TSPDistanceFunction.UpperEuclidean:
+          return CalculateUpperEuclideanDistance(x1, y1, x2, y2);
+        case TSPDistanceFunction.Geo:
+          return CalculateGeoDistance(x1, y1, x2, y2);
+        default: throw new ArgumentException(string.Format("Distance calculation not available for {0}", distanceFunction));
+      }
+    }
+
+    public static double CalculateEuclideanDistance(double x1, double y1, double x2, double y2) {
+      return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+    }
+
+    public static double CalculateRoundedEuclideanDistance(double x1, double y1, double x2, double y2) {
+      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
+    }
+
+    public static double CalculateUpperEuclideanDistance(double x1, double y1, double x2, double y2) {
+      return Math.Ceiling(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
+    }
+
+    public static double CalculateGeoDistance(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 static double ConvertToRadian(double x) {
+      return PI * (Math.Truncate(x) + 5.0 * (x - Math.Truncate(x)) / 3.0) / 180.0;
     }
   }
