Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/BestTSPSolutionAnalyzer.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/BestTSPSolutionAnalyzer.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/BestTSPSolutionAnalyzer.cs	(revision 9281)
@@ -0,0 +1,132 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator for analyzing the best solution of Traveling Salesman Problems given in path representation using city coordinates.
+  /// </summary>
+  [Item("BestTSPSolutionAnalyzer", "An operator for analyzing the best solution of Traveling Salesman Problems given in path representation using city coordinates.")]
+  [StorableClass]
+  public sealed class BestTSPSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+
+    public LookupParameter<BoolValue> MaximizationParameter {
+      get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public LookupParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (LookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+    public ScopeTreeLookupParameter<Permutation> PermutationParameter {
+      get { return (ScopeTreeLookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public LookupParameter<PathTSPTour> BestSolutionParameter {
+      get { return (LookupParameter<PathTSPTour>)Parameters["BestSolution"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public LookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public LookupParameter<Permutation> BestKnownSolutionParameter {
+      get { return (LookupParameter<Permutation>)Parameters["BestKnownSolution"]; }
+    }
+
+    [StorableConstructor]
+    private BestTSPSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private BestTSPSolutionAnalyzer(BestTSPSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestTSPSolutionAnalyzer(this, cloner);
+    }
+    public BestTSPSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
+      Parameters.Add(new ScopeTreeLookupParameter<Permutation>("Permutation", "The TSP solutions given in path representation from which the best solution should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the TSP solutions which should be analyzed."));
+      Parameters.Add(new LookupParameter<PathTSPTour>("BestSolution", "The best TSP solution."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best TSP solution should be stored."));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this TSP instance."));
+      Parameters.Add(new LookupParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));
+
+      MaximizationParameter.Hidden = true;
+      CoordinatesParameter.Hidden = true;
+      PermutationParameter.Hidden = true;
+      QualityParameter.Hidden = true;
+      BestSolutionParameter.Hidden = true;
+      ResultsParameter.Hidden = true;
+      BestKnownQualityParameter.Hidden = true;
+      BestKnownSolutionParameter.Hidden = true;
+    }
+
+    public override IOperation Apply() {
+      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
+      ItemArray<Permutation> permutations = PermutationParameter.ActualValue;
+      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+      ResultCollection results = ResultsParameter.ActualValue;
+      bool max = MaximizationParameter.ActualValue.Value;
+      DoubleValue bestKnownQuality = BestKnownQualityParameter.ActualValue;
+
+      int i = -1;
+      if (!max)
+        i = qualities.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      else i = qualities.Select((x, index) => new { index, x.Value }).OrderByDescending(x => x.Value).First().index;
+
+      if (bestKnownQuality == null ||
+          max && qualities[i].Value > bestKnownQuality.Value ||
+          !max && qualities[i].Value < bestKnownQuality.Value) {
+        BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[i].Value);
+        BestKnownSolutionParameter.ActualValue = (Permutation)permutations[i].Clone();
+      }
+
+      PathTSPTour tour = BestSolutionParameter.ActualValue;
+      if (tour == null) {
+        tour = new PathTSPTour(coordinates, (Permutation)permutations[i].Clone(), new DoubleValue(qualities[i].Value));
+        BestSolutionParameter.ActualValue = tour;
+        results.Add(new Result("Best TSP Solution", tour));
+      } else {
+        if (max && tour.Quality.Value < qualities[i].Value ||
+          !max && tour.Quality.Value > qualities[i].Value) {
+          tour.Coordinates = coordinates;
+          tour.Permutation = (Permutation)permutations[i].Clone();
+          tour.Quality.Value = qualities[i].Value;
+        }
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPAlleleFrequencyAnalyzer.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPAlleleFrequencyAnalyzer.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPAlleleFrequencyAnalyzer.cs	(revision 9281)
@@ -0,0 +1,86 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Analysis;
+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 for analyzing the frequency of alleles in solutions of Traveling Salesman Problems given in path representation.
+  /// </summary>
+  [Item("TSPAlleleFrequencyAnalyzer", "An operator for analyzing the frequency of alleles in solutions of Traveling Salesman Problems given in path representation.")]
+  [StorableClass]
+  public sealed class TSPAlleleFrequencyAnalyzer : AlleleFrequencyAnalyzer<Permutation> {
+    public LookupParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (LookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+    public LookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (LookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    [StorableConstructor]
+    private TSPAlleleFrequencyAnalyzer(bool deserializing) : base(deserializing) { }
+    private TSPAlleleFrequencyAnalyzer(TSPAlleleFrequencyAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public TSPAlleleFrequencyAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The x- and y-coordinates of the cities."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPAlleleFrequencyAnalyzer(this, cloner);
+    }
+
+    protected override Allele[] CalculateAlleles(Permutation solution) {
+      Allele[] alleles = new Allele[solution.Length];
+      DoubleMatrix coords = CoordinatesParameter.ActualValue;
+      DistanceMatrix dm = DistanceMatrixParameter.ActualValue;
+      if (dm == null && coords == null) throw new InvalidOperationException("Neither a distance matrix nor coordinates were given.");
+      int source, target, h;
+      double impact;
+
+      for (int i = 0; i < solution.Length - 1; i++) {
+        source = solution[i];
+        target = solution[i + 1];
+        if (source > target) { h = source; source = target; target = h; }
+        impact = dm != null ? dm[source, target] : CalculateLength(coords[source, 0], coords[source, 1], coords[target, 0], coords[target, 1]);
+        alleles[i] = new Allele(source.ToString() + "-" + target.ToString(), impact);
+      }
+      source = solution[solution.Length - 1];
+      target = solution[0];
+      if (source > target) { h = source; source = target; target = h; }
+      impact = dm != null ? dm[source, target] : CalculateLength(coords[source, 0], coords[source, 1], coords[target, 0], coords[target, 1]);
+      alleles[alleles.Length - 1] = new Allele(source.ToString() + "-" + target.ToString(), impact);
+
+      return alleles;
+    }
+
+    private double CalculateLength(double x1, double y1, double x2, double y2) {
+      return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPPopulationDiversityAnalyzer.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPPopulationDiversityAnalyzer.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPPopulationDiversityAnalyzer.cs	(revision 9281)
@@ -0,0 +1,88 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  // BackwardsCompatibility3.3
+  #region Backwards compatible code, remove with 3.4
+  /// <summary>
+  /// An operator for analyzing the diversity of solutions of Traveling Salesman Problems given in path representation.
+  /// </summary>
+  [Obsolete]
+  [NonDiscoverableType]
+  [Item("TSPPopulationDiversityAnalyzer", "An operator for analyzing the diversity of solutions of Traveling Salesman Problems given in path representation.")]
+  [StorableClass]
+  public sealed class TSPPopulationDiversityAnalyzer : PopulationDiversityAnalyzer<Permutation> {
+    [StorableConstructor]
+    private TSPPopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { }
+    private TSPPopulationDiversityAnalyzer(TSPPopulationDiversityAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public TSPPopulationDiversityAnalyzer() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPPopulationDiversityAnalyzer(this, cloner);
+    }
+
+    protected override double[,] CalculateSimilarities(Permutation[] solutions) {
+      int count = solutions.Length;
+      double[,] similarities = new double[count, count];
+      int[][] edges = new int[count][];
+
+      for (int i = 0; i < count; i++)
+        edges[i] = CalculateEdgesVector(solutions[i]);
+
+      for (int i = 0; i < count; i++) {
+        similarities[i, i] = 1;
+        for (int j = i + 1; j < count; j++) {
+          similarities[i, j] = CalculateSimilarity(edges[i], edges[j]);
+          similarities[j, i] = similarities[i, j];
+        }
+      }
+      return similarities;
+    }
+
+    private int[] CalculateEdgesVector(Permutation permutation) {
+      // transform path representation into adjacency representation
+      int[] edgesVector = new int[permutation.Length];
+      for (int i = 0; i < permutation.Length - 1; i++)
+        edgesVector[permutation[i]] = permutation[i + 1];
+      edgesVector[permutation[permutation.Length - 1]] = permutation[0];
+      return edgesVector;
+    }
+
+    private double CalculateSimilarity(int[] edgesA, int[] edgesB) {
+      // calculate relative number of identical edges
+      int identicalEdges = 0;
+      for (int i = 0; i < edgesA.Length; i++) {
+        if ((edgesA[i] == edgesB[i]) || (edgesA[edgesB[i]] == i))
+          identicalEdges++;
+      }
+      return ((double)identicalEdges) / edgesA.Length;
+    }
+  }
+  #endregion
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/DistanceMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/DistanceMatrix.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/DistanceMatrix.cs	(revision 9281)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// Represents a distance matrix of a Traveling Salesman Problem.
+  /// </summary>
+  [Item("DistanceMatrix", "Represents a distance matrix of a Traveling Salesman Problem.")]
+  [StorableClass]
+  public sealed class DistanceMatrix : DoubleMatrix {
+    [StorableConstructor]
+    private DistanceMatrix(bool deserializing) : base(deserializing) { }
+    private DistanceMatrix(DistanceMatrix original, Cloner cloner) {
+      throw new NotSupportedException("Distance matrices cannot be cloned.");
+    }
+    public DistanceMatrix() : base() { }
+    public DistanceMatrix(int rows, int columns) : base(rows, columns) { }
+    public DistanceMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    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, IEnumerable<string> columnNames) : base(elements, columnNames) { }
+    public DistanceMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      // distance matrices are not cloned for performance reasons
+      cloner.RegisterClonedObject(this, this);
+      return this;
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPCoordinatesPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPCoordinatesPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPCoordinatesPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,135 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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>
+  /// A base class for operators which evaluate TSP solutions given in path representation using city coordinates.
+  /// </summary>
+  [Item("TSPCoordinatesPathEvaluator", "A base class for operators which evaluate TSP solutions given in path representation using city coordinates.")]
+  [StorableClass]
+  public abstract class TSPCoordinatesPathEvaluator : TSPEvaluator, ITSPCoordinatesPathEvaluator {
+    private object locker = new object();
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
+    }
+
+    [StorableConstructor]
+    protected TSPCoordinatesPathEvaluator(bool deserializing) : base(deserializing) { }
+    protected TSPCoordinatesPathEvaluator(TSPCoordinatesPathEvaluator original, Cloner cloner) : base(original, cloner) { }
+    protected TSPCoordinatesPathEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The TSP solution given in path representation which should be evaluated."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
+      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 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
+    }
+
+    public static double Apply(TSPCoordinatesPathEvaluator evaluator, DoubleMatrix coordinates, Permutation tour) {
+      DoubleMatrix c = coordinates;
+      Permutation p = tour;
+      double length = 0;
+      for (int i = 0; i < p.Length - 1; i++)
+        length += evaluator.CalculateDistance(c[p[i], 0], c[p[i], 1], c[p[i + 1], 0], c[p[i + 1], 1]);
+      length += evaluator.CalculateDistance(c[p[p.Length - 1], 0], c[p[p.Length - 1], 1], c[p[0], 0], c[p[0], 1]);
+      return length;
+    }
+
+    public sealed override IOperation Apply() {
+      if (UseDistanceMatrixParameter.ActualValue.Value) {
+        Permutation p = PermutationParameter.ActualValue;
+        DistanceMatrix dm = DistanceMatrixParameter.ActualValue;
+
+        if (dm == null) {  // calculate distance matrix
+          lock (locker) {
+            dm = DistanceMatrixParameter.ActualValue;
+            if (dm == null) {  // check again to avoid race condition
+              DoubleMatrix c = CoordinatesParameter.ActualValue;
+              if (c == null) throw new InvalidOperationException("Neither a distance matrix nor coordinates were given.");
+              dm = new DistanceMatrix(c.Rows, c.Rows);
+              for (int i = 0; i < dm.Rows; i++) {
+                for (int j = 0; j < dm.Columns; j++)
+                  dm[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);
+              }
+              DistanceMatrixParameter.ActualValue = (DistanceMatrix)dm.AsReadOnly();
+            }
+          }
+        }
+
+        double length = 0;
+        for (int i = 0; i < p.Length - 1; i++)
+          length += dm[p[i], p[i + 1]];
+        length += dm[p[p.Length - 1], p[0]];
+        QualityParameter.ActualValue = new DoubleValue(length);
+      } else {
+        Permutation p = PermutationParameter.ActualValue;
+        DoubleMatrix c = CoordinatesParameter.ActualValue;
+        if (c == null) throw new InvalidOperationException("No coordinates were given.");
+        double length = 0;
+        for (int i = 0; i < p.Length - 1; i++)
+          length += CalculateDistance(c[p[i], 0], c[p[i], 1], c[p[i + 1], 0], c[p[i + 1], 1]);
+        length += CalculateDistance(c[p[p.Length - 1], 0], c[p[p.Length - 1], 1], c[p[0], 0], c[p[0], 1]);
+        QualityParameter.ActualValue = new DoubleValue(length);
+      }
+      return base.Apply();
+    }
+
+    /// <summary>
+    /// Calculates the distance between two points.
+    /// </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 abstract double CalculateDistance(double x1, double y1, double x2, double y2);
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPDistanceMatrixEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPDistanceMatrixEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPDistanceMatrixEvaluator.cs	(revision 9281)
@@ -0,0 +1,79 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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>
+  /// A base class for operators which evaluate TSP solutions given in path representation using a distance matrix.
+  /// </summary>
+  [Item("TSPDistanceMatrixEvaluator", "Evaluate TSP solutions given in path representation using the distance matrix.")]
+  [StorableClass]
+  public sealed class TSPDistanceMatrixEvaluator : TSPEvaluator, ITSPDistanceMatrixEvaluator {
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    [StorableConstructor]
+    private TSPDistanceMatrixEvaluator(bool deserializing) : base(deserializing) { }
+    private TSPDistanceMatrixEvaluator(TSPDistanceMatrixEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public TSPDistanceMatrixEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The TSP solution given in path representation which should be evaluated."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPDistanceMatrixEvaluator(this, cloner);
+    }
+
+    public static double Apply(DistanceMatrix distances, Permutation tour) {
+      if (distances == null || distances.Rows == 0 || distances.Columns == 0
+        || distances.Rows != distances.Columns)
+        throw new InvalidOperationException("TSPDistanceMatrixEvaluator: The distance matrix is empty or not square");
+      if (tour == null) throw new ArgumentNullException("tour", "TSPDistanceMatrixEvaluator: No tour is given.");
+      Permutation p = tour;
+      double length = 0;
+      for (int i = 0; i < p.Length - 1; i++)
+        length += distances[p[i], p[i + 1]];
+      length += distances[p[p.Length - 1], p[0]];
+      return length;
+    }
+
+    public override IOperation Apply() {
+      Permutation p = PermutationParameter.ActualValue;
+      DistanceMatrix dm = DistanceMatrixParameter.ActualValue;
+
+      QualityParameter.ActualValue = new DoubleValue(Apply(dm, p));
+      return base.Apply();
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPEuclideanPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPEuclideanPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPEuclideanPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 which evaluates TSP solutions given in path representation using the Euclidean distance metric.
+  /// </summary>
+  [Item("TSPEuclideanPathEvaluator", "An operator which evaluates TSP solutions given in path representation using the Euclidean distance metric.")]
+  [StorableClass]
+  public sealed class TSPEuclideanPathEvaluator : TSPCoordinatesPathEvaluator {
+    [StorableConstructor]
+    private TSPEuclideanPathEvaluator(bool deserializing) : base(deserializing) { }
+    private TSPEuclideanPathEvaluator(TSPEuclideanPathEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public TSPEuclideanPathEvaluator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPEuclideanPathEvaluator(this, cloner);
+    }
+    
+    /// <summary>
+    /// Calculates the distance between two points using the Euclidean distance metric.
+    /// </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) {
+      return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPEvaluator.cs	(revision 9281)
@@ -0,0 +1,52 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// A base class for operators which evaluate TSP solutions.
+  /// </summary>
+  [Item("TSPEvaluator", "A base class for operators which evaluate TSP solutions.")]
+  [StorableClass]
+  public abstract class TSPEvaluator : SingleSuccessorOperator, ITSPEvaluator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    [StorableConstructor]
+    protected TSPEvaluator(bool deserializing) : base(deserializing) { }
+    protected TSPEvaluator(TSPEvaluator original, Cloner cloner) : base(original, cloner) { }
+    protected TSPEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The evaluated quality of the TSP solution."));
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPGeoPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPGeoPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPGeoPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,77 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 which evaluates TSP solutions given in path representation using the GEO distance metric (globe coordinates).
+  /// </summary>
+  [Item("TSPGeoPathEvaluator", "An operator which evaluates TSP solutions given in path representation using the GEO distance metric (globe coordinates).")]
+  [StorableClass]
+  public sealed class TSPGeoPathEvaluator : TSPCoordinatesPathEvaluator {
+    private const double PI = 3.141592;
+    private const double RADIUS = 6378.388;
+
+    [StorableConstructor]
+    private TSPGeoPathEvaluator(bool deserializing) : base(deserializing) { }
+    private TSPGeoPathEvaluator(TSPGeoPathEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public TSPGeoPathEvaluator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPGeoPathEvaluator(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/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPRoundedEuclideanPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPRoundedEuclideanPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Evaluators/TSPRoundedEuclideanPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 which evaluates TSP solutions given in path representation using the rounded Euclidean distance metric.
+  /// </summary>
+  [Item("TSPRoundedEuclideanPathEvaluator", "An operator which evaluates TSP solutions given in path representation using the rounded Euclidean distance metric.")]
+  [StorableClass]
+  public sealed class TSPRoundedEuclideanPathEvaluator : TSPCoordinatesPathEvaluator {
+    [StorableConstructor]
+    private TSPRoundedEuclideanPathEvaluator(bool deserializing) : base(deserializing) { }
+    private TSPRoundedEuclideanPathEvaluator(TSPRoundedEuclideanPathEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public TSPRoundedEuclideanPathEvaluator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPRoundedEuclideanPathEvaluator(this, cloner);
+    }
+    
+    /// <summary>
+    /// Calculates the distance between two points using the rounded Euclidean distance metric.
+    /// </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) {
+      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj	(revision 9281)
@@ -0,0 +1,266 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{D767C38D-8014-46B0-9A32-03A3AECCE34A}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.TravelingSalesman</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.TravelingSalesman-3.3</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Analyzers\BestTSPSolutionAnalyzer.cs" />
+    <Compile Include="Analyzers\TSPPopulationDiversityAnalyzer.cs" />
+    <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="Improvers\TSPImprovementOperator.cs" />
+    <Compile Include="Interfaces\ITSPDistanceMatrixEvaluator.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\TSPInversionMovePathEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveRoundedEuclideanPathEvaluator.cs" />
+    <Compile Include="PathRelinkers\TSPMultipleGuidesPathRelinker.cs" />
+    <Compile Include="PathRelinkers\TSPPathRelinker.cs" />
+    <Compile Include="PathRelinkers\TSPSimultaneousPathRelinker.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="SimilarityCalculators\TSPSimilarityCalculator.cs" />
+    <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" />
+    <Compile Include="Interfaces\ITSPMoveEvaluator.cs" />
+    <Compile Include="Interfaces\ITSPPathEvaluator.cs" />
+    <Compile Include="Interfaces\ITSPPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TSPPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TSPMoveEvaluator.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
+      <Project>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</Project>
+      <Name>HeuristicLab.Encodings.PermutationEncoding-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
+      <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
+      <Name>HeuristicLab.Operators-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
+      <Project>{25087811-F74C-4128-BC86-8324271DA13E}</Project>
+      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
+      <Project>{102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}</Project>
+      <Name>HeuristicLab.Persistence-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj">
+      <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project>
+      <Name>HeuristicLab.Problems.Instances-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+   <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Improvers/TSPImprovementOperator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Improvers/TSPImprovementOperator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Improvers/TSPImprovementOperator.cs	(revision 9281)
@@ -0,0 +1,130 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator that improves traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator tries to improve the traveling salesman solution by swapping two randomly chosen edges for a certain number of times.
+  /// </remarks>
+  [Item("TSPImprovementOperator", "An operator that improves traveling salesman solutions. The operator tries to improve the traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
+  [StorableClass]
+  public sealed class TSPImprovementOperator : SingleSuccessorOperator, ISingleObjectiveImprovementOperator {
+    #region Parameter properties
+    public ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    public IValueParameter<IntValue> ImprovementAttemptsParameter {
+      get { return (IValueParameter<IntValue>)Parameters["ImprovementAttempts"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IItem> SolutionParameter {
+      get { return (IValueLookupParameter<IItem>)Parameters["Solution"]; }
+    }
+    #endregion
+
+    #region Properties
+    public IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    public DistanceMatrix DistanceMatrix {
+      get { return DistanceMatrixParameter.ActualValue; }
+      set { DistanceMatrixParameter.ActualValue = value; }
+    }
+    public IntValue ImprovementAttempts {
+      get { return ImprovementAttemptsParameter.Value; }
+      set { ImprovementAttemptsParameter.Value = value; }
+    }
+    public IRandom Random {
+      get { return RandomParameter.ActualValue; }
+      set { RandomParameter.ActualValue = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private TSPImprovementOperator(bool deserializing) : base(deserializing) { }
+    private TSPImprovementOperator(TSPImprovementOperator original, Cloner cloner) : base(original, cloner) { }
+    public TSPImprovementOperator()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope that contains the solution to be improved."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new ValueParameter<IntValue>("ImprovementAttempts", "The number of improvement attempts the operator should perform.", new IntValue(100)));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "A pseudo random number generator."));
+      Parameters.Add(new ValueLookupParameter<IItem>("Solution", "The solution to be improved. This parameter is used for name translation only."));
+      #endregion
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPImprovementOperator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      Permutation currSol = CurrentScope.Variables[SolutionParameter.ActualName].Value as Permutation;
+      if (currSol == null)
+        throw new ArgumentException("Cannot improve solution because it has the wrong type.");
+      if (currSol.PermutationType != PermutationTypes.RelativeUndirected)
+        throw new ArgumentException("Cannot improve solution because the permutation type is not supported.");
+
+      for (int i = 0; i < ImprovementAttempts.Value; i++) {
+        int a = Random.Next(currSol.Length);
+        int b = Random.Next(currSol.Length);
+        double oldFirstEdgeLength = DistanceMatrix[currSol[a], currSol[(a - 1 + currSol.Length) % currSol.Length]];
+        double oldSecondEdgeLength = DistanceMatrix[currSol[b], currSol[(b + 1) % currSol.Length]];
+        double newFirstEdgeLength = DistanceMatrix[currSol[b], currSol[(a - 1 + currSol.Length) % currSol.Length]];
+        double newSecondEdgeLength = DistanceMatrix[currSol[a], currSol[(b + 1 + currSol.Length) % currSol.Length]];
+        if (newFirstEdgeLength + newSecondEdgeLength < oldFirstEdgeLength + oldSecondEdgeLength)
+          Invert(currSol, a, b);
+      }
+
+      CurrentScope.Variables.Add(new Variable("LocalEvaluatedSolutions", ImprovementAttempts));
+
+      return base.Apply();
+    }
+
+    private void Invert(Permutation sol, int i, int j) {
+      if (i != j)
+        for (int a = 0; a < Math.Abs(i - j) / 2; a++)
+          if (sol[(i + a) % sol.Length] != sol[(j - a + sol.Length) % sol.Length]) {
+            // XOR swap
+            sol[(i + a) % sol.Length] ^= sol[(j - a + sol.Length) % sol.Length];
+            sol[(j - a + sol.Length) % sol.Length] ^= sol[(i + a) % sol.Length];
+            sol[(i + a) % sol.Length] ^= sol[(j - a + sol.Length) % sol.Length];
+          }
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPCoordinatesPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPCoordinatesPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPCoordinatesPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,34 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An interface which represents an evaluation operator which evaluates TSP solutions given in path representation using city coordinates.
+  /// </summary>
+  public interface ITSPCoordinatesPathEvaluator : ITSPPathEvaluator {
+    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
+    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
+    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPDistanceMatrixEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPDistanceMatrixEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPDistanceMatrixEvaluator.cs	(revision 9281)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An interface which represents an evaluation operator which evaluates TSP solutions given in path representation using a distance matrix.
+  /// </summary>
+  public interface ITSPDistanceMatrixEvaluator : ITSPPathEvaluator {
+    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPEvaluator.cs	(revision 9281)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An interface which represents an evaluation operator for Traveling Salesman Problems.
+  /// </summary>
+  public interface ITSPEvaluator : ISingleObjectiveEvaluator { }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 9281)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Optimization;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  public interface ITSPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator {
+    Type EvaluatorType { get; }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An interface which represents an evaluation operator which evaluates TSP solutions given in path representation.
+  /// </summary>
+  public interface ITSPPathEvaluator : ITSPEvaluator {
+    ILookupParameter<Permutation> PermutationParameter { get; }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs	(revision 9281)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  public interface ITSPPathMoveEvaluator : ITSPMoveEvaluator, IPermutationMoveOperator {
+    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
+    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
+    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 9281)
@@ -0,0 +1,60 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// A base class for operators which evaluate TSP solutions.
+  /// </summary>
+  [Item("TSPMoveEvaluator", "A base class for operators which evaluate TSP moves.")]
+  [StorableClass]
+  public abstract class TSPMoveEvaluator : SingleSuccessorOperator, ITSPMoveEvaluator, IMoveOperator {
+
+    public abstract Type EvaluatorType { get; }
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+
+    [StorableConstructor]
+    protected TSPMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected TSPMoveEvaluator(TSPMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    protected TSPMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a TSP solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The evaluated quality of a move on a TSP solution."));
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 9281)
@@ -0,0 +1,109 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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>
+  /// A base class for operators which evaluate TSP solutions.
+  /// </summary>
+  [Item("TSPMoveEvaluator", "A base class for operators which evaluate TSP moves.")]
+  [StorableClass]
+  public abstract class TSPPathMoveEvaluator : TSPMoveEvaluator, ITSPPathMoveEvaluator {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
+    }
+
+    [StorableConstructor]
+    protected TSPPathMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected TSPPathMoveEvaluator(TSPPathMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    protected TSPPathMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The city's coordinates."));
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated (if it does not exist already) and used for evaluation, otherwise false."));
+    }
+
+    [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
+    }
+
+    public override IOperation Apply() {
+      Permutation permutation = PermutationParameter.ActualValue;
+      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
+      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;
+        }
+        relativeQualityDifference = EvaluateByDistanceMatrix(permutation, distanceMatrix);
+      } else {
+        if (coordinates == null) throw new InvalidOperationException("No coordinates were given.");
+        relativeQualityDifference = EvaluateByCoordinates(permutation, coordinates);
+      }
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(QualityParameter.ActualValue.Value + relativeQualityDifference);
+      else moveQuality.Value = QualityParameter.ActualValue.Value + relativeQualityDifference;
+      return base.Apply();
+    }
+
+    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
+    protected abstract double EvaluateByDistanceMatrix(Permutation permutation, 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();
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveEuclideanPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveEuclideanPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveEuclideanPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveGeoPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveGeoPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveGeoPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,81 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs	(revision 9281)
@@ -0,0 +1,120 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate a translocation or insertion move.
+  /// </summary>
+  [Item("TSPTranslocationMovePathEvaluator", "Evaluates a translocation or insertion move (3-opt) by summing up the length of all added edges and subtracting the length of all deleted edges.")]
+  [StorableClass]
+  public abstract class TSPTranslocationMovePathEvaluator : TSPPathMoveEvaluator, IPermutationTranslocationMoveOperator {
+    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
+      get { return (ILookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
+    }
+
+    [StorableConstructor]
+    protected TSPTranslocationMovePathEvaluator(bool deserializing) : base(deserializing) { }
+    protected TSPTranslocationMovePathEvaluator(TSPTranslocationMovePathEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public TSPTranslocationMovePathEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move to evaluate."));
+    }
+
+    public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, TSPTranslocationMovePathEvaluator evaluator) {
+      if (move.Index1 == move.Index3
+        || move.Index2 == permutation.Length - 1 && move.Index3 == 0
+        || move.Index1 == 0 && move.Index3 == permutation.Length - 1 - move.Index2) return 0;
+
+      int edge1source = permutation.GetCircular(move.Index1 - 1);
+      int edge1target = permutation[move.Index1];
+      int edge2source = permutation[move.Index2];
+      int edge2target = permutation.GetCircular(move.Index2 + 1);
+      int edge3source, edge3target;
+      if (move.Index3 > move.Index1) {
+        edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+        edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+      } else {
+        edge3source = permutation.GetCircular(move.Index3 - 1);
+        edge3target = permutation[move.Index3];
+      }
+      double moveQuality = 0;
+      // remove three edges
+      moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+        coordinates[edge1target, 0], coordinates[edge1target, 1]);
+      moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      moveQuality -= evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
+        coordinates[edge3target, 0], coordinates[edge3target, 1]);
+      // add three edges
+      moveQuality += evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
+        coordinates[edge1target, 0], coordinates[edge1target, 1]);
+      moveQuality += evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+        coordinates[edge3target, 0], coordinates[edge3target, 1]);
+      moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      return moveQuality;
+    }
+
+    public static double EvaluateByDistanceMatrix(Permutation permutation, TranslocationMove move, DistanceMatrix distanceMatrix) {
+      if (move.Index1 == move.Index3
+        || move.Index2 == permutation.Length - 1 && move.Index3 == 0
+        || move.Index1 == 0 && move.Index3 == permutation.Length - 1 - move.Index2) return 0;
+
+      int edge1source = permutation.GetCircular(move.Index1 - 1);
+      int edge1target = permutation[move.Index1];
+      int edge2source = permutation[move.Index2];
+      int edge2target = permutation.GetCircular(move.Index2 + 1);
+      int edge3source, edge3target;
+      if (move.Index3 > move.Index1) {
+        edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+        edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+      } else {
+        edge3source = permutation.GetCircular(move.Index3 - 1);
+        edge3target = permutation[move.Index3];
+      }
+      double moveQuality = 0;
+      // remove three edges
+      moveQuality -= distanceMatrix[edge1source, edge1target];
+      moveQuality -= distanceMatrix[edge2source, edge2target];
+      moveQuality -= distanceMatrix[edge3source, edge3target];
+      // add three edges
+      moveQuality += distanceMatrix[edge3source, edge1target];
+      moveQuality += distanceMatrix[edge2source, edge3target];
+      moveQuality += distanceMatrix[edge1source, edge2target];
+      return moveQuality;
+    }
+
+    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates) {
+      return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, this);
+    }
+
+    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
+      return EvaluateByDistanceMatrix(permutation, TranslocationMoveParameter.ActualValue, distanceMatrix);
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveRoundedEuclideanPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveRoundedEuclideanPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMoveRoundedEuclideanPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveEuclideanPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveEuclideanPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveEuclideanPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveGeoPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveGeoPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveGeoPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,80 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs	(revision 9281)
@@ -0,0 +1,92 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator to evaluate inversion moves (2-opt).
+  /// </summary>
+  [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 ILookupParameter<InversionMove> InversionMoveParameter {
+      get { return (ILookupParameter<InversionMove>)Parameters["InversionMove"]; }
+    }
+
+    [StorableConstructor]
+    protected TSPInversionMovePathEvaluator(bool deserializing) : base(deserializing) { }
+    protected TSPInversionMovePathEvaluator(TSPInversionMovePathEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public TSPInversionMovePathEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
+    }
+
+    public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, TSPInversionMovePathEvaluator evaluator) {
+      int edge1source = permutation.GetCircular(move.Index1 - 1);
+      int edge1target = permutation[move.Index1];
+      int edge2source = permutation[move.Index2];
+      int edge2target = permutation.GetCircular(move.Index2 + 1);
+      if (move.Index2 - move.Index1 >= permutation.Length - 2) return 0;
+      double moveQuality = 0;
+      // remove two edges
+      moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+            coordinates[edge1target, 0], coordinates[edge1target, 1]);
+      moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      // add two edges
+      moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+        coordinates[edge2source, 0], coordinates[edge2source, 1]);
+      moveQuality += evaluator.CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
+        coordinates[edge2target, 0], coordinates[edge2target, 1]);
+      return moveQuality;
+    }
+
+    public static double EvaluateByDistanceMatrix(Permutation permutation, InversionMove move, DistanceMatrix distanceMatrix) {
+      int edge1source = permutation.GetCircular(move.Index1 - 1);
+      int edge1target = permutation[move.Index1];
+      int edge2source = permutation[move.Index2];
+      int edge2target = permutation.GetCircular(move.Index2 + 1);
+      if (move.Index2 - move.Index1 >= permutation.Length - 2) return 0;
+      double moveQuality = 0;
+      // remove two edges
+      moveQuality -= distanceMatrix[edge1source, edge1target];
+      moveQuality -= distanceMatrix[edge2source, edge2target];
+      // add two edges
+      moveQuality += distanceMatrix[edge1source, edge2source];
+      moveQuality += distanceMatrix[edge1target, edge2target];
+      return moveQuality;
+    }
+
+    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates) {
+      return EvaluateByCoordinates(permutation, InversionMoveParameter.ActualValue, coordinates, this);
+    }
+
+    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
+      return EvaluateByDistanceMatrix(permutation, InversionMoveParameter.ActualValue, distanceMatrix);
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveRoundedEuclideanPathEvaluator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveRoundedEuclideanPathEvaluator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMoveRoundedEuclideanPathEvaluator.cs	(revision 9281)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPMultipleGuidesPathRelinker.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPMultipleGuidesPathRelinker.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPMultipleGuidesPathRelinker.cs	(revision 9281)
@@ -0,0 +1,134 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator that relinks paths between traveling salesman solutions using a multiple guiding strategy.
+  /// </summary>
+  /// <remarks>
+  /// The operator incrementally changes the initiating solution towards the guiding solution by correcting edges as needed. For each city it choses the best edge from all guiding solutions.
+  /// </remarks>
+  [Item("TSPMultipleGuidesPathRelinker", "An operator that relinks paths between traveling salesman solutions using a multiple guiding strategy. The operator incrementally changes the initiating solution towards the guiding solution by correcting edges as needed. For each city it choses the best edge from all guiding solutions.")]
+  [StorableClass]
+  public sealed class TSPMultipleGuidesPathRelinker : SingleObjectivePathRelinker {
+    #region Parameter properties
+    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    #endregion
+
+    #region Properties
+    public DistanceMatrix DistanceMatrix {
+      get { return DistanceMatrixParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private TSPMultipleGuidesPathRelinker(bool deserializing) : base(deserializing) { }
+    private TSPMultipleGuidesPathRelinker(TSPMultipleGuidesPathRelinker original, Cloner cloner) : base(original, cloner) { }
+    public TSPMultipleGuidesPathRelinker()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      #endregion
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPMultipleGuidesPathRelinker(this, cloner);
+    }
+
+    public static ItemArray<IItem> Apply(IItem initiator, IItem[] guides, DistanceMatrix distances, PercentValue n) {
+      if (!(initiator is Permutation) || guides.Any(x => !(x is Permutation)))
+        throw new ArgumentException("Cannot relink path because some of the provided solutions have the wrong type.");
+      if (n.Value <= 0.0)
+        throw new ArgumentException("RelinkingAccuracy must be greater than 0.");
+
+      Permutation v1 = initiator.Clone() as Permutation;
+      Permutation[] targets = new Permutation[guides.Length];
+      Array.Copy(guides, targets, guides.Length);
+
+      if (targets.Any(x => x.Length != v1.Length))
+        throw new ArgumentException("At least one solution is of different length.");
+
+      IList<Permutation> solutions = new List<Permutation>();
+      for (int i = 0; i < v1.Length; i++) {
+        int currCityIndex = i;
+        int bestCityIndex = (i + 1) % v1.Length;
+        double currDistance = distances[v1[currCityIndex], v1[bestCityIndex]];
+        // check each guiding solution
+        targets.ToList().ForEach(solution => {
+          // locate current city
+          var node = solution.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == v1[currCityIndex]);
+          int pred = solution[(node.Index - 1 + solution.Length) % solution.Length];
+          int succ = solution[(node.Index + 1) % solution.Length];
+          // get distances to neighbors
+          var results = new[] { pred, succ }.Select(x => new { Id = x, Distance = distances[x, node.Id] });
+          var bestCity = results.Where(x => x.Distance < currDistance).OrderBy(x => x.Distance).FirstOrDefault();
+          if (bestCity != null) {
+            bestCityIndex = v1.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == bestCity.Id).Index;
+            currDistance = bestCity.Distance;
+          }
+        });
+        Invert(v1, currCityIndex + 1, bestCityIndex);
+        solutions.Add(v1.Clone() as Permutation);
+      }
+
+      IList<IItem> selection = new List<IItem>();
+      if (solutions.Count > 0) {
+        int noSol = (int)(solutions.Count * n.Value);
+        if (noSol <= 0) noSol++;
+        double stepSize = (double)solutions.Count / (double)noSol;
+        for (int i = 0; i < noSol; i++)
+          selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5)));
+      }
+
+      return new ItemArray<IItem>(selection);
+    }
+
+    private static void Invert(Permutation sol, int i, int j) {
+      if (i != j)
+        for (int a = 0; a < Math.Abs(i - j) / 2; a++)
+          if (sol[(i + a) % sol.Length] != sol[(j - a + sol.Length) % sol.Length]) {
+            // XOR swap
+            sol[(i + a) % sol.Length] ^= sol[(j - a + sol.Length) % sol.Length];
+            sol[(j - a + sol.Length) % sol.Length] ^= sol[(i + a) % sol.Length];
+            sol[(i + a) % sol.Length] ^= sol[(j - a + sol.Length) % sol.Length];
+          }
+    }
+
+    protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) {
+      if (parents.Length < 2)
+        throw new ArgumentException("The number of parents is smaller than 2.");
+      return Apply(parents[0], parents.Skip(1).ToArray(), DistanceMatrix, n);
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPPathRelinker.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPPathRelinker.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPPathRelinker.cs	(revision 9281)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator that relinks paths between traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator incrementally assimilates the initiating solution into the guiding solution by correcting edges as needed.
+  /// </remarks>
+  [Item("TSPPathRelinker", "An operator that relinks paths between traveling salesman solutions. The operator incrementally assimilates the initiating solution into the guiding solution by correcting edges as needed.")]
+  [StorableClass]
+  public sealed class TSPPathRelinker : SingleObjectivePathRelinker {
+    [StorableConstructor]
+    private TSPPathRelinker(bool deserializing) : base(deserializing) { }
+    private TSPPathRelinker(TSPPathRelinker original, Cloner cloner) : base(original, cloner) { }
+    public TSPPathRelinker() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPPathRelinker(this, cloner);
+    }
+
+    public static ItemArray<IItem> Apply(IItem initiator, IItem guide, PercentValue n) {
+      if (!(initiator is Permutation) || !(guide is Permutation))
+        throw new ArgumentException("Cannot relink path because one of the provided solutions or both have the wrong type.");
+      if (n.Value <= 0.0)
+        throw new ArgumentException("RelinkingAccuracy must be greater than 0.");
+
+      Permutation v1 = initiator.Clone() as Permutation;
+      Permutation v2 = guide as Permutation;
+
+      if (v1.Length != v2.Length)
+        throw new ArgumentException("The solutions are of different length.");
+
+      IList<Permutation> solutions = new List<Permutation>();
+      for (int i = 0; i < v1.Length; i++)
+        if (v1[i] != v2[i]) {
+          var target = v1.Select((x, index) => new { Value = x, ValueIndex = index }).First(x => x.Value == v2[i]);
+          if (v1[i] != v1[target.ValueIndex]) {
+            // XOR swap
+            v1[i] ^= v1[target.ValueIndex];
+            v1[target.ValueIndex] ^= v1[i];
+            v1[i] ^= v1[target.ValueIndex];
+            solutions.Add(v1.Clone() as Permutation);
+          }
+        }
+
+      IList<IItem> selection = new List<IItem>();
+      if (solutions.Count > 0) {
+        int noSol = (int)(solutions.Count * n.Value);
+        if (noSol <= 0) noSol++;
+        double stepSize = (double)solutions.Count / (double)noSol;
+        for (int i = 0; i < noSol; i++)
+          selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5)));
+      }
+
+      return new ItemArray<IItem>(selection);
+    }
+
+    protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) {
+      if (parents.Length != 2)
+        throw new ArgumentException("The number of parents is not equal to 2.");
+      return Apply(parents[0], parents[1], n);
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPSimultaneousPathRelinker.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPSimultaneousPathRelinker.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPSimultaneousPathRelinker.cs	(revision 9281)
@@ -0,0 +1,104 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator that relinks paths between traveling salesman solutions starting from both ends.
+  /// </summary>
+  /// <remarks>
+  /// The operator incrementally assimilates the initiating solution into the guiding solution and vice versa by correcting edges as needed.
+  /// </remarks>
+  [Item("TSPSimultaneousPathRelinker", "An operator that relinks paths between traveling salesman solutions starting from both ends. The operator incrementally assimilates the initiating solution into the guiding solution and vice versa by correcting edges as needed.")]
+  [StorableClass]
+  public sealed class TSPSimultaneousPathRelinker : SingleObjectivePathRelinker {
+    [StorableConstructor]
+    private TSPSimultaneousPathRelinker(bool deserializing) : base(deserializing) { }
+    private TSPSimultaneousPathRelinker(TSPSimultaneousPathRelinker original, Cloner cloner) : base(original, cloner) { }
+    public TSPSimultaneousPathRelinker() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPSimultaneousPathRelinker(this, cloner);
+    }
+
+    public static ItemArray<IItem> Apply(IItem initiator, IItem guide, PercentValue n) {
+      if (!(initiator is Permutation) || !(guide is Permutation))
+        throw new ArgumentException("Cannot relink path because one of the provided solutions or both have the wrong type.");
+      if (n.Value <= 0.0)
+        throw new ArgumentException("RelinkingAccuracy must be greater than 0.");
+
+      Permutation firstInitiator = initiator.Clone() as Permutation;
+      Permutation firstGuide = guide.Clone() as Permutation;
+      Permutation secondInitiator = firstGuide.Clone() as Permutation;
+      Permutation secondGuide = firstInitiator.Clone() as Permutation;
+
+      if (firstInitiator.Length != firstGuide.Length)
+        throw new ArgumentException("The solutions are of different length.");
+
+      IList<Permutation> solutions = new List<Permutation>();
+      for (int i = 0; i < firstInitiator.Length / 2; i++) {
+        if (firstInitiator[i] != firstGuide[i]) {
+          var target = firstInitiator.Select((x, index) => new { Value = x, ValueIndex = index }).First(x => x.Value == firstGuide[i]);
+          // XOR swap
+          firstInitiator[i] ^= firstInitiator[target.ValueIndex];
+          firstInitiator[target.ValueIndex] ^= firstInitiator[i];
+          firstInitiator[i] ^= firstInitiator[target.ValueIndex];
+          solutions.Add(firstInitiator.Clone() as Permutation);
+        }
+        int j = secondInitiator.Length - 1 - i;
+        if (secondInitiator[j] != secondGuide[j]) {
+          var target = secondInitiator.Select((x, index) => new { Value = x, ValueIndex = index }).First(x => x.Value == secondGuide[j]);
+          // XOR swap
+          secondInitiator[j] ^= secondInitiator[target.ValueIndex];
+          secondInitiator[target.ValueIndex] ^= secondInitiator[j];
+          secondInitiator[j] ^= secondInitiator[target.ValueIndex];
+          solutions.Add(secondInitiator.Clone() as Permutation);
+        }
+      }
+
+      IList<IItem> selection = new List<IItem>();
+      if (solutions.Count > 0) {
+        int noSol = (int)(solutions.Count * n.Value);
+        if (noSol <= 0) noSol++;
+        double stepSize = (double)solutions.Count / (double)noSol;
+        for (int i = 0; i < noSol; i++)
+          selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5)));
+      }
+
+      return new ItemArray<IItem>(selection);
+    }
+
+    protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) {
+      if (parents.Length != 2)
+        throw new ArgumentException("The number of parents is not equal to 2.");
+      return Apply(parents[0], parents[1], n);
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathTSPTour.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathTSPTour.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/PathTSPTour.cs	(revision 9281)
@@ -0,0 +1,185 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// Represents a tour of a Traveling Salesman Problem given in path representation which can be visualized in the GUI.
+  /// </summary>
+  [Item("PathTSPTour", "Represents a tour of a Traveling Salesman Problem given in path representation which can be visualized in the GUI.")]
+  [StorableClass]
+  public sealed class PathTSPTour : Item {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; }
+    }
+
+    [Storable]
+    private DoubleMatrix coordinates;
+    public DoubleMatrix Coordinates {
+      get { return coordinates; }
+      set {
+        if (coordinates != value) {
+          if (coordinates != null) DeregisterCoordinatesEvents();
+          coordinates = value;
+          if (coordinates != null) RegisterCoordinatesEvents();
+          OnCoordinatesChanged();
+        }
+      }
+    }
+    [Storable]
+    private Permutation permutation;
+    public Permutation Permutation {
+      get { return permutation; }
+      set {
+        if (permutation != value) {
+          if (permutation != null) DeregisterPermutationEvents();
+          permutation = value;
+          if (permutation != null) RegisterPermutationEvents();
+          OnPermutationChanged();
+        }
+      }
+    }
+    [Storable]
+    private DoubleValue quality;
+    public DoubleValue Quality {
+      get { return quality; }
+      set {
+        if (quality != value) {
+          if (quality != null) DeregisterQualityEvents();
+          quality = value;
+          if (quality != null) RegisterQualityEvents();
+          OnQualityChanged();
+        }
+      }
+    }
+
+    [StorableConstructor]
+    private PathTSPTour(bool deserializing) : base(deserializing) { }
+    private PathTSPTour(PathTSPTour original, Cloner cloner)
+      : base(original, cloner) {
+      this.coordinates = cloner.Clone(original.coordinates);
+      this.permutation = cloner.Clone(original.permutation);
+      this.quality = cloner.Clone(original.quality);
+      Initialize();
+    }
+    public PathTSPTour() : base() { }
+    public PathTSPTour(DoubleMatrix coordinates)
+      : base() {
+      this.coordinates = coordinates;
+      Initialize();
+    }
+    public PathTSPTour(DoubleMatrix coordinates, Permutation permutation)
+      : base() {
+      this.coordinates = coordinates;
+      this.permutation = permutation;
+      Initialize();
+    }
+    public PathTSPTour(DoubleMatrix coordinates, Permutation permutation, DoubleValue quality)
+      : base() {
+      this.coordinates = coordinates;
+      this.permutation = permutation;
+      this.quality = quality;
+      Initialize();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PathTSPTour(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    private void Initialize() {
+      if (coordinates != null) RegisterCoordinatesEvents();
+      if (permutation != null) RegisterPermutationEvents();
+      if (quality != null) RegisterQualityEvents();
+    }
+
+    #region Events
+    public event EventHandler CoordinatesChanged;
+    private void OnCoordinatesChanged() {
+      var changed = CoordinatesChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+    public event EventHandler PermutationChanged;
+    private void OnPermutationChanged() {
+      var changed = PermutationChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+    public event EventHandler QualityChanged;
+    private void OnQualityChanged() {
+      var changed = QualityChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    private void RegisterCoordinatesEvents() {
+      Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
+      Coordinates.Reset += new EventHandler(Coordinates_Reset);
+    }
+    private void DeregisterCoordinatesEvents() {
+      Coordinates.ItemChanged -= new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
+      Coordinates.Reset -= new EventHandler(Coordinates_Reset);
+    }
+    private void RegisterPermutationEvents() {
+      Permutation.ItemChanged += new EventHandler<EventArgs<int>>(Permutation_ItemChanged);
+      Permutation.Reset += new EventHandler(Permutation_Reset);
+    }
+    private void DeregisterPermutationEvents() {
+      Permutation.ItemChanged -= new EventHandler<EventArgs<int>>(Permutation_ItemChanged);
+      Permutation.Reset -= new EventHandler(Permutation_Reset);
+    }
+    private void RegisterQualityEvents() {
+      Quality.ValueChanged += new EventHandler(Quality_ValueChanged);
+    }
+    private void DeregisterQualityEvents() {
+      Quality.ValueChanged -= new EventHandler(Quality_ValueChanged);
+    }
+
+    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
+      OnCoordinatesChanged();
+    }
+    private void Coordinates_Reset(object sender, EventArgs e) {
+      OnCoordinatesChanged();
+    }
+    private void Permutation_ItemChanged(object sender, EventArgs<int> e) {
+      OnPermutationChanged();
+    }
+    private void Permutation_Reset(object sender, EventArgs e) {
+      OnPermutationChanged();
+    }
+    private void Quality_ValueChanged(object sender, EventArgs e) {
+      OnQualityChanged();
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Plugin.cs.frame
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Plugin.cs.frame	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Plugin.cs.frame	(revision 9281)
@@ -0,0 +1,45 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Problems.TravelingSalesman plugin
+  /// </summary>
+  [Plugin("HeuristicLab.Problems.TravelingSalesman", "3.3.7.$WCREV$")]
+  [PluginFile("HeuristicLab.Problems.TravelingSalesman-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.PermutationEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  public class HeuristicLabProblemsTravelingSalesmanPlugin : PluginBase {
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Properties/AssemblyInfo.cs.frame	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/Properties/AssemblyInfo.cs.frame	(revision 9281)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Problems.TravelingSalesman")]
+[assembly: AssemblyDescription("HeuristicLab Traveling Salesman Problem classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2012 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3c4c7e0d-ad0b-4e9b-8182-cd7498c7e55d")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.7.$WCREV$")]
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/SimilarityCalculators/TSPSimilarityCalculator.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/SimilarityCalculators/TSPSimilarityCalculator.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/SimilarityCalculators/TSPSimilarityCalculator.cs	(revision 9281)
@@ -0,0 +1,110 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization.Operators;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  /// <summary>
+  /// An operator that performs similarity calculation between two traveling salesman solutions.
+  /// </summary>
+  /// <remarks>
+  /// The operator calculates the similarity based on the number of edges the two solutions have in common.
+  /// </remarks>
+  [Item("TSPSimilarityCalculator", "An operator that performs similarity calculation between two traveling salesman solutions. The operator calculates the similarity based on the number of edges the two solutions have in common.")]
+  public sealed class TSPSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {
+    private TSPSimilarityCalculator(bool deserializing) : base(deserializing) { }
+    private TSPSimilarityCalculator(TSPSimilarityCalculator original, Cloner cloner) : base(original, cloner) { }
+    public TSPSimilarityCalculator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TSPSimilarityCalculator(this, cloner);
+    }
+
+    public static double CalculateSimilarity(Permutation left, Permutation right) {
+      if (left == null || right == null)
+        throw new ArgumentException("Cannot calculate similarity because one of the provided solutions or both are null.");
+      if (left.PermutationType != right.PermutationType)
+        throw new ArgumentException("Cannot calculate similarity because the provided solutions have different types.");
+      if (left.Length != right.Length)
+        throw new ArgumentException("Cannot calculate similarity because the provided solutions have different lengths.");
+      if (object.ReferenceEquals(left, right)) return 1.0;
+
+      switch (left.PermutationType) {
+        case PermutationTypes.Absolute:
+          return CalculateAbsolute(left, right);
+        case PermutationTypes.RelativeDirected:
+          return CalculateRelativeDirected(left, right);
+        case PermutationTypes.RelativeUndirected:
+          return CalculateRelativeUndirected(left, right);
+        default:
+          throw new InvalidOperationException("unknown permutation type");
+      }
+    }
+
+    private static double CalculateAbsolute(Permutation left, Permutation right) {
+      double similarity = 0.0;
+      for (int i = 0; i < left.Length; i++)
+        if (left[i] == right[i]) similarity++;
+
+      return similarity / left.Length;
+    }
+
+    private static double CalculateRelativeDirected(Permutation left, Permutation right) {
+      int[] edges = new int[right.Length];
+      for (int i = 0; i < right.Length; i++)
+        edges[right[i]] = right[(i + 1) % right.Length];
+
+      double similarity = 0.0;
+      for (int i = 0; i < left.Length; i++)
+        if (left[(i + 1) % left.Length] == edges[left[i]]) similarity++;
+
+      return similarity / left.Length;
+    }
+
+    private static double CalculateRelativeUndirected(Permutation left, Permutation right) {
+      int[,] edges = new int[right.Length, 2];
+      for (int i = 0; i < right.Length; i++) {
+        edges[right[i], 0] = right[(i + 1) % right.Length];
+        edges[right[i], 1] = right[(i - 1 + right.Length) % right.Length];
+      }
+
+      double similarity = 0.0;
+      for (int i = 0; i < left.Length; i++) {
+        int targetCity = left[(i + 1) % left.Length];
+        if (targetCity == edges[left[i], 0] || targetCity == edges[left[i], 1])
+          similarity++;
+      }
+
+      return similarity / left.Length;
+    }
+
+    public override double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution) {
+      var sol1 = leftSolution.Variables[SolutionVariableName].Value as Permutation;
+      var sol2 = rightSolution.Variables[SolutionVariableName].Value as Permutation;
+
+      return CalculateSimilarity(sol1, sol2);
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 9281)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 9281)
@@ -0,0 +1,466 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Problems.Instances;
+
+namespace HeuristicLab.Problems.TravelingSalesman {
+  [Item("Traveling Salesman Problem", "Represents a symmetric Traveling Salesman Problem.")]
+  [Creatable("Problems")]
+  [StorableClass]
+  public sealed class TravelingSalesmanProblem : SingleObjectiveHeuristicOptimizationProblem<ITSPEvaluator, IPermutationCreator>, IStorableContent,
+    IProblemInstanceConsumer<TSPData> {
+    private static readonly int DistanceMatrixSizeLimit = 1000;
+    public string Filename { get; set; }
+
+    #region Parameter Properties
+    public OptionalValueParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+    public OptionalValueParameter<DistanceMatrix> DistanceMatrixParameter {
+      get { return (OptionalValueParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    public ValueParameter<BoolValue> UseDistanceMatrixParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
+    }
+    public OptionalValueParameter<Permutation> BestKnownSolutionParameter {
+      get { return (OptionalValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
+    }
+    #endregion
+
+    #region Properties
+    public DoubleMatrix Coordinates {
+      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; }
+    }
+    public Permutation BestKnownSolution {
+      get { return BestKnownSolutionParameter.Value; }
+      set { BestKnownSolutionParameter.Value = value; }
+    }
+    private BestTSPSolutionAnalyzer BestTSPSolutionAnalyzer {
+      get { return Operators.OfType<BestTSPSolutionAnalyzer>().FirstOrDefault(); }
+    }
+    private TSPAlleleFrequencyAnalyzer TSPAlleleFrequencyAnalyzer {
+      get { return Operators.OfType<TSPAlleleFrequencyAnalyzer>().FirstOrDefault(); }
+    }
+    private SingleObjectivePopulationDiversityAnalyzer SingleObjectivePopulationDiversityAnalyzer {
+      get { return Operators.OfType<SingleObjectivePopulationDiversityAnalyzer>().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
+
+    [StorableConstructor]
+    private TravelingSalesmanProblem(bool deserializing) : base(deserializing) { }
+    private TravelingSalesmanProblem(TravelingSalesmanProblem original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      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;
+
+      Coordinates = new DoubleMatrix(new double[,] {
+        { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },
+        { 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 },
+        { 300, 100 }, { 300, 200 }, { 300, 300 }, { 300, 400 },
+        { 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();
+      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) {
+      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);
+    }
+
+    private void InitializeOperators() {
+      Operators.Add(new TSPImprovementOperator());
+      Operators.Add(new TSPMultipleGuidesPathRelinker());
+      Operators.Add(new TSPPathRelinker());
+      Operators.Add(new TSPSimultaneousPathRelinker());
+      Operators.Add(new TSPSimilarityCalculator());
+
+      Operators.Add(new BestTSPSolutionAnalyzer());
+      Operators.Add(new TSPAlleleFrequencyAnalyzer());
+      Operators.Add(new SingleObjectivePopulationDiversityAnalyzer());
+      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 (ITSPPathMoveEvaluator op in ApplicationManager.Manager.GetInstances<ITSPPathMoveEvaluator>())
+        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.ResultsParameter.ActualName = "Results";
+        BestTSPSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
+        BestTSPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
+        BestTSPSolutionAnalyzer.MaximizationParameter.ActualName = 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.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        TSPAlleleFrequencyAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
+        TSPAlleleFrequencyAnalyzer.ResultsParameter.ActualName = "Results";
+      }
+
+      if (SingleObjectivePopulationDiversityAnalyzer != null) {
+        SingleObjectivePopulationDiversityAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
+        SingleObjectivePopulationDiversityAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        SingleObjectivePopulationDiversityAnalyzer.ResultsParameter.ActualName = "Results";
+        SingleObjectivePopulationDiversityAnalyzer.SimilarityCalculator = Operators.OfType<TSPSimilarityCalculator>().SingleOrDefault();
+      }
+    }
+    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.CoordinatesParameter.Hidden = true;
+        op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
+        op.DistanceMatrixParameter.Hidden = true;
+        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.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.Hidden = true;
+      }
+      foreach (ISingleObjectivePathRelinker op in Operators.OfType<ISingleObjectivePathRelinker>()) {
+        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.ParentsParameter.Hidden = true;
+      }
+      foreach (TSPSimilarityCalculator op in Operators.OfType<TSPSimilarityCalculator>()) {
+        op.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName;
+        op.QualityVariableName = Evaluator.QualityParameter.ActualName;
+      }
+    }
+
+    private void ClearDistanceMatrix() {
+      DistanceMatrixParameter.Value = null;
+    }
+    #endregion
+
+    public void Load(TSPData data) {
+      if (data.Coordinates == null && data.Distances == null)
+        throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!");
+      if (data.Dimension > DistanceMatrixSizeLimit && (data.DistanceMeasure == DistanceMeasure.Att
+        || data.DistanceMeasure == DistanceMeasure.Manhattan
+        || data.DistanceMeasure == DistanceMeasure.Maximum
+        || data.DistanceMeasure == DistanceMeasure.UpperEuclidean))
+        throw new System.IO.InvalidDataException("The given instance uses an unsupported distance measure and is too large for using a distance matrix.");
+      if (data.Coordinates != null && data.Coordinates.GetLength(1) != 2)
+        throw new System.IO.InvalidDataException("The coordinates of the given instance are not in the right format, there need to be one row for each customer and two columns for the x and y coordinates.");
+
+      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;
+      if (data.DistanceMeasure == DistanceMeasure.Att
+        || data.DistanceMeasure == DistanceMeasure.Manhattan
+        || data.DistanceMeasure == DistanceMeasure.Maximum
+        || data.DistanceMeasure == DistanceMeasure.UpperEuclidean) {
+        evaluator = new TSPDistanceMatrixEvaluator();
+        UseDistanceMatrix = new BoolValue(true);
+        DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix());
+      } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) {
+        evaluator = new TSPDistanceMatrixEvaluator();
+        UseDistanceMatrix = new BoolValue(true);
+        DistanceMatrix = new DistanceMatrix(data.Distances);
+      } else {
+        clearDistanceMatrix = true;
+        UseDistanceMatrix = new BoolValue(data.Dimension <= DistanceMatrixSizeLimit);
+        switch (data.DistanceMeasure) {
+          case DistanceMeasure.Euclidean:
+            evaluator = new TSPEuclideanPathEvaluator();
+            break;
+          case DistanceMeasure.RoundedEuclidean:
+            evaluator = new TSPRoundedEuclideanPathEvaluator();
+            break;
+          case DistanceMeasure.Geo:
+            evaluator = new TSPGeoPathEvaluator();
+            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;
+
+      BestKnownSolution = null;
+      BestKnownQuality = null;
+
+      if (data.BestKnownTour != null) {
+        try {
+          EvaluateAndLoadTour(data.BestKnownTour);
+        }
+        catch (InvalidOperationException) {
+          if (data.BestKnownQuality.HasValue)
+            BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
+        }
+      } else if (data.BestKnownQuality.HasValue) {
+        BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
+      }
+      OnReset();
+    }
+
+    public void EvaluateAndLoadTour(int[] tour) {
+      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);
+    }
+  }
+}
