Index: /trunk/sources/HeuristicLab.Algorithms.TS/3.3/TS.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.TS/3.3/TS.cs	(revision 3073)
+++ /trunk/sources/HeuristicLab.Algorithms.TS/3.3/TS.cs	(revision 3074)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -33,6 +34,17 @@
 namespace HeuristicLab.Algorithms.TS {
   [Item("TS", "A tabu search algorithm.")]
+  [Creatable("Algorithms")]
   public sealed class TS : EngineAlgorithm {
-    /*#region Parameter Properties
+    #region Problem Properties
+    public override Type ProblemType {
+      get { return typeof(ISingleObjectiveProblem); }
+    }
+    public new ISingleObjectiveProblem Problem {
+      get { return (ISingleObjectiveProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+    #endregion
+
+    #region Parameter Properties
     private ValueParameter<IntValue> SeedParameter {
       get { return (ValueParameter<IntValue>)Parameters["Seed"]; }
@@ -43,4 +55,19 @@
     private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
       get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
+    }
+    private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
+      get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
+    }
+    private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
+      get { return (ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
+    }
+    private ConstrainedValueParameter<ITabuMoveEvaluator> TabuMoveEvaluatorParameter {
+      get { return (ConstrainedValueParameter<ITabuMoveEvaluator>)Parameters["TabuMoveEvaluator"]; }
+    }
+    private ConstrainedValueParameter<ITabuMoveMaker> TabuMoveMakerParameter {
+      get { return (ConstrainedValueParameter<ITabuMoveMaker>)Parameters["TabuMoveMaker"]; }
+    }
+    private ValueParameter<IntValue> TabuTenureParameter {
+      get { return (ValueParameter<IntValue>)Parameters["TabuTenure"]; }
     }
     private ValueParameter<IntValue> MaximumIterationsParameter {
@@ -61,4 +88,24 @@
       get { return MoveGeneratorParameter.Value; }
       set { MoveGeneratorParameter.Value = value; }
+    }
+    public IMoveMaker MoveMaker {
+      get { return MoveMakerParameter.Value; }
+      set { MoveMakerParameter.Value = value; }
+    }
+    public ISingleObjectiveMoveEvaluator MoveEvaluator {
+      get { return MoveEvaluatorParameter.Value; }
+      set { MoveEvaluatorParameter.Value = value; }
+    }
+    public ITabuMoveEvaluator TabuMoveEvaluator {
+      get { return TabuMoveEvaluatorParameter.Value; }
+      set { TabuMoveEvaluatorParameter.Value = value; }
+    }
+    public ITabuMoveMaker TabuMoveMaker {
+      get { return TabuMoveMakerParameter.Value; }
+      set { TabuMoveMakerParameter.Value = value; }
+    }
+    public IntValue TabuTenure {
+      get { return TabuTenureParameter.Value; }
+      set { TabuTenureParameter.Value = value; }
     }
     public IntValue MaximumIterations {
@@ -82,4 +129,9 @@
       Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
       Parameters.Add(new ConstrainedValueParameter<IMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
+      Parameters.Add(new ConstrainedValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
+      Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
+      Parameters.Add(new ConstrainedValueParameter<ITabuMoveEvaluator>("TabuMoveEvaluator", "The operator to evaluate whether a move is tabu or not."));
+      Parameters.Add(new ConstrainedValueParameter<ITabuMoveMaker>("TabuMoveMaker", "The operator used to insert attributes of a move into the tabu list."));
+      Parameters.Add(new ValueParameter<IntValue>("TabuTenure", "The length of the tabu list.", new IntValue(10)));
       Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(1000)));
 
@@ -100,14 +152,15 @@
 
       tsMainLoop.MoveGeneratorParameter.ActualName = MoveGeneratorParameter.Name;
-      tsMainLoop.MoveMakerParameter.ActualName = MoveGenerator..Name;
-      tsMainLoop.ElitesParameter.ActualName = ElitesParameter.Name;
-      tsMainLoop.MaximumGenerationsParameter.ActualName = MaximumGenerationsParameter.Name;
-      tsMainLoop.MutatorParameter.ActualName = MutatorParameter.Name;
-      tsMainLoop.MutationProbabilityParameter.ActualName = MutationProbabilityParameter.Name;
+      tsMainLoop.MoveMakerParameter.ActualName = MoveMakerParameter.Name;
+      tsMainLoop.MoveEvaluatorParameter.ActualName = MoveEvaluatorParameter.Name;
+      tsMainLoop.TabuMoveEvaluatorParameter.ActualName = TabuMoveEvaluatorParameter.Name;
+      tsMainLoop.TabuMoveMakerParameter.ActualName = TabuMoveMakerParameter.Name;
+      tsMainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
       tsMainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
       tsMainLoop.ResultsParameter.ActualName = "Results";
 
-      Initialze();
-    }
+      Initialize();
+    }
+
     [StorableConstructor]
     private TS(bool deserializing) : base() { }
@@ -115,5 +168,5 @@
     public override IDeepCloneable Clone(Cloner cloner) {
       TS clone = (TS)base.Clone(cloner);
-      clone.Initialze();
+      clone.Initialize();
       return clone;
     }
@@ -124,9 +177,12 @@
       ParameterizeStochasticOperator(Problem.Evaluator);
       foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
+      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
+        op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
+      }
       ParameterizeSolutionsCreator();
-      ParameterizeSGAMainLoop();
-      ParameterizeSelectors();
-      UpdateCrossovers();
-      UpdateMutators();
+      ParameterizeTSMainLoop();
+      ParameterizeMoveEvaluator();
+      ParameterizeMoveMaker();
+      UpdateMoveGenerator();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       base.OnProblemChanged();
@@ -140,6 +196,7 @@
       ParameterizeStochasticOperator(Problem.Evaluator);
       ParameterizeSolutionsCreator();
-      ParameterizeSGAMainLoop();
-      ParameterizeSelectors();
+      ParameterizeTSMainLoop();
+      ParameterizeMoveEvaluator();
+      ParameterizeMoveMaker();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       base.Problem_EvaluatorChanged(sender, e);
@@ -147,25 +204,36 @@
     protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
       foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
-      UpdateCrossovers();
-      UpdateMutators();
+      // This may seem pointless, but some operators already have the eventhandler registered, others don't
+      // FIXME: Is there another way to solve this problem?
+      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
+        op.MoveQualityParameter.ActualNameChanged -= new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
+        op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
+      }
+      IMoveGenerator oldMoveGenerator = MoveGenerator;
+      UpdateMoveGenerator();
+      if (oldMoveGenerator == MoveGenerator) // in this case MoveGeneratorParameter_ValueChanged did not fire
+        UpdateMoveParameters();
+      ParameterizeTSMainLoop();
+      ParameterizeMoveEvaluator();
+      ParameterizeMoveMaker();
       base.Problem_OperatorsChanged(sender, e);
     }
-    private void ElitesParameter_ValueChanged(object sender, EventArgs e) {
-      Elites.ValueChanged += new EventHandler(Elites_ValueChanged);
-      ParameterizeSelectors();
-    }
-    private void Elites_ValueChanged(object sender, EventArgs e) {
-      ParameterizeSelectors();
-    }
-    private void PopulationSizeParameter_ValueChanged(object sender, EventArgs e) {
-      PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
-      ParameterizeSelectors();
-    }
-    private void PopulationSize_ValueChanged(object sender, EventArgs e) {
-      ParameterizeSelectors();
-    }
     private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeSGAMainLoop();
-      ParameterizeSelectors();
+      ParameterizeTSMainLoop();
+      ParameterizeMoveEvaluator();
+      ParameterizeMoveMaker();
+    }
+    private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
+      UpdateMoveParameters();
+    }
+    private void MoveEvaluatorParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeTSMainLoop();
+      ParameterizeMoveEvaluator();
+      ParameterizeMoveMaker();
+    }
+    private void MoveEvaluator_MoveQualityParameter_ActualNameChanged(object sender, EventArgs e) {
+      ParameterizeTSMainLoop();
+      ParameterizeMoveEvaluator();
+      ParameterizeMoveMaker();
     }
     #endregion
@@ -173,23 +241,73 @@
     #region Helpers
     [StorableHook(HookType.AfterDeserialization)]
-    private void Initialze() {
-      InitializeSelectors();
-      UpdateSelectors();
-      PopulationSizeParameter.ValueChanged += new EventHandler(PopulationSizeParameter_ValueChanged);
-      PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
-      ElitesParameter.ValueChanged += new EventHandler(ElitesParameter_ValueChanged);
-      Elites.ValueChanged += new EventHandler(Elites_ValueChanged);
-      if (Problem != null)
+    private void Initialize() {
+      if (Problem != null) {
         Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
-    }
-
+        foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
+          op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
+        }
+      }
+      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
+      MoveEvaluatorParameter.ValueChanged += new EventHandler(MoveEvaluatorParameter_ValueChanged);
+    }
+    private void UpdateMoveGenerator() {
+      IMoveGenerator oldMoveGenerator = MoveGenerator;
+      MoveGeneratorParameter.ValidValues.Clear();
+      if (Problem != null) {
+        foreach (IMoveGenerator generator in Problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
+          MoveGeneratorParameter.ValidValues.Add(generator);
+      }
+      if (oldMoveGenerator != null && MoveGeneratorParameter.ValidValues.Any(x => x.GetType() == oldMoveGenerator.GetType()))
+        MoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
+      if (MoveGenerator == null) {
+        ClearMoveParameters();
+      }
+    }
+    private void UpdateMoveParameters() {
+      IMoveMaker oldMoveMaker = MoveMaker;
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+      ITabuMoveEvaluator oldTabuMoveEvaluator = TabuMoveEvaluator;
+      ITabuMoveMaker oldTabuMoveMaker = TabuMoveMaker;
+      ClearMoveParameters();
+      List<Type> moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
+      foreach (Type type in moveTypes.ToList()) {
+        if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
+          moveTypes.Remove(type);
+      }
+      foreach (Type type in moveTypes) {
+        var operators = Problem.Operators.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
+        foreach (IMoveMaker moveMaker in operators.OfType<IMoveMaker>())
+          MoveMakerParameter.ValidValues.Add(moveMaker);
+        foreach (ISingleObjectiveMoveEvaluator moveEvaluator in operators.OfType<ISingleObjectiveMoveEvaluator>())
+          MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
+        foreach (ITabuMoveEvaluator tabuMoveEvaluator in operators.OfType<ITabuMoveEvaluator>())
+          TabuMoveEvaluatorParameter.ValidValues.Add(tabuMoveEvaluator);
+        foreach (ITabuMoveMaker tabuMoveMaker in operators.OfType<ITabuMoveMaker>())
+          TabuMoveMakerParameter.ValidValues.Add(tabuMoveMaker);
+      }
+      if (oldMoveMaker != null && MoveMakerParameter.ValidValues.Any(x => x.GetType() == oldMoveMaker.GetType()))
+        MoveMaker = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+      if (oldMoveEvaluator != null && MoveEvaluatorParameter.ValidValues.Any(x => x.GetType() == oldMoveEvaluator.GetType()))
+        MoveEvaluator = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+      if (oldTabuMoveMaker != null && TabuMoveMakerParameter.ValidValues.Any(x => x.GetType() == oldTabuMoveMaker.GetType()))
+        TabuMoveMaker = TabuMoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldTabuMoveMaker.GetType());
+      if (oldTabuMoveEvaluator != null && TabuMoveEvaluatorParameter.ValidValues.Any(x => x.GetType() == oldTabuMoveEvaluator.GetType()))
+        TabuMoveEvaluator = TabuMoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldTabuMoveEvaluator.GetType());
+    }
+    private void ClearMoveParameters() {
+      MoveMakerParameter.ValidValues.Clear();
+      MoveEvaluatorParameter.ValidValues.Clear();
+      TabuMoveEvaluatorParameter.ValidValues.Clear();
+      TabuMoveMakerParameter.ValidValues.Clear();
+    }
     private void ParameterizeSolutionsCreator() {
       SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
       SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
     }
-    private void ParameterizeSGAMainLoop() {
-      TSMainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+    private void ParameterizeTSMainLoop() {
       TSMainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
       TSMainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+      if (MoveEvaluator != null)
+        TSMainLoop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
     }
     private void ParameterizeStochasticOperator(IOperator op) {
@@ -197,52 +315,17 @@
         ((IStochasticOperator)op).RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
     }
-    private void InitializeSelectors() {
-      selectors = new List<ISelector>();
-      if (ApplicationManager.Manager != null) {
-        selectors.AddRange(ApplicationManager.Manager.GetInstances<ISelector>().Where(x => !(x is IMultiObjectiveSelector)).OrderBy(x => x.Name));
-        ParameterizeSelectors();
-      }
-    }
-    private void ParameterizeSelectors() {
-      foreach (ISelector selector in Selectors) {
-        selector.CopySelected = new BoolValue(true);
-        selector.NumberOfSelectedSubScopesParameter.Value = new IntValue(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
-        ParameterizeStochasticOperator(selector);
-      }
-      if (Problem != null) {
-        foreach (ISingleObjectiveSelector selector in Selectors.OfType<ISingleObjectiveSelector>()) {
-          selector.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
-          selector.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-        }
-      }
-    }
-    private void UpdateSelectors() {
-      if (ApplicationManager.Manager != null) {
-        ISelector oldSelector = SelectorParameter.Value;
-        SelectorParameter.ValidValues.Clear();
-        foreach (ISelector selector in Selectors.OrderBy(x => x.Name))
-          SelectorParameter.ValidValues.Add(selector);
-        if (oldSelector != null)
-          SelectorParameter.Value = SelectorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldSelector.GetType());
-      }
-    }
-    private void UpdateCrossovers() {
-      ICrossover oldCrossover = CrossoverParameter.Value;
-      CrossoverParameter.ValidValues.Clear();
-      foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
-        CrossoverParameter.ValidValues.Add(crossover);
-      if (oldCrossover != null)
-        CrossoverParameter.Value = CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldCrossover.GetType());
-    }
-    private void UpdateMutators() {
-      IManipulator oldMutator = MutatorParameter.Value;
-      MutatorParameter.ValidValues.Clear();
-      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
-        MutatorParameter.ValidValues.Add(mutator);
-      if (oldMutator != null)
-        MutatorParameter.Value = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
-    }
-    #endregion
-     */
+    private void ParameterizeMoveEvaluator() {
+      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
+        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+      }
+    }
+    private void ParameterizeMoveMaker() {
+      foreach (IMoveMaker op in Problem.Operators.OfType<IMoveMaker>()) {
+        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+        if (MoveEvaluator != null)
+          op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+      }
+    }
+    #endregion
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.TS/3.3/TSMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.TS/3.3/TSMainLoop.cs	(revision 3073)
+++ /trunk/sources/HeuristicLab.Algorithms.TS/3.3/TSMainLoop.cs	(revision 3074)
@@ -42,6 +42,9 @@
       get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
     }
-    public SubScopesLookupParameter<DoubleValue> QualityParameter {
-      get { return (SubScopesLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    public LookupParameter<DoubleValue> QualityParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public LookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
     }
     public ValueLookupParameter<IntValue> MaximumIterationsParameter {
@@ -57,18 +60,15 @@
       get { return (ValueLookupParameter<IOperator>)Parameters["MoveGenerator"]; }
     }
-    public ValueLookupParameter<IOperator> MoveQualityEvaluatorParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["MoveQualityEvaluator"]; }
-    }
-    public ValueLookupParameter<IOperator> MoveTabuEvaluatorParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["MoveTabuEvaluator"]; }
-    }
-    public ValueLookupParameter<IOperator> TabuSelectorParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["TabuSelector"]; }
-    }
-    public ValueLookupParameter<IOperator> MoveTabuMakerParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["MoveTabuMaker"]; }
+    public ValueLookupParameter<IOperator> MoveEvaluatorParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["MoveEvaluator"]; }
     }
     public ValueLookupParameter<IOperator> MoveMakerParameter {
       get { return (ValueLookupParameter<IOperator>)Parameters["MoveMaker"]; }
+    }
+    public ValueLookupParameter<IOperator> TabuMoveEvaluatorParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["TabuMoveEvaluator"]; }
+    }
+    public ValueLookupParameter<IOperator> TabuMoveMakerParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["TabuMoveMaker"]; }
     }
 
@@ -86,5 +86,6 @@
       Parameters.Add(new ValueLookupParameter<IRandom>("Random", "A pseudo random number generator."));
       Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
-      Parameters.Add(new SubScopesLookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The value which represents the quality of a move."));
       Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed."));
       Parameters.Add(new ValueLookupParameter<IntValue>("TabuTenure", "The length of the tabu list, and also means the number of iterations a move is kept tabu"));
@@ -92,8 +93,8 @@
 
       Parameters.Add(new ValueLookupParameter<IOperator>("MoveGenerator", "The operator that generates the moves."));
-      Parameters.Add(new ValueLookupParameter<IOperator>("MoveQualityEvaluator", "The operator that evaluates the quality of a move."));
-      Parameters.Add(new ValueLookupParameter<IOperator>("MoveTabuEvaluator", "The operator that evaluates whether a move is tabu."));
-      Parameters.Add(new ValueLookupParameter<IOperator>("MoveTabuMaker", "The operator that declares a move tabu."));
       Parameters.Add(new ValueLookupParameter<IOperator>("MoveMaker", "The operator that performs a move and updates the quality."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("MoveEvaluator", "The operator that evaluates a move."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("TabuMoveEvaluator", "The operator that evaluates whether a move is tabu."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("TabuMoveMaker", "The operator that declares a move tabu."));
 
       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope which represents a population of solutions on which the TS should be applied."));
@@ -108,6 +109,6 @@
       Placeholder moveGenerator = new Placeholder();
       UniformSequentialSubScopesProcessor moveEvaluationProcessor = new UniformSequentialSubScopesProcessor();
-      Placeholder moveQualityEvaluator = new Placeholder();
-      Placeholder moveTabuEvaluator = new Placeholder();
+      Placeholder moveEvaluator = new Placeholder();
+      Placeholder tabuMoveEvaluator = new Placeholder();
       SubScopesSorter moveQualitySorter = new SubScopesSorter();
       BestAverageWorstQualityCalculator bestAverageWorstMoveQualityCalculator = new BestAverageWorstQualityCalculator();
@@ -115,5 +116,5 @@
       RightReducer rightReducer = new RightReducer();
       UniformSequentialSubScopesProcessor moveMakingProcessor = new UniformSequentialSubScopesProcessor();
-      Placeholder moveTabuMaker = new Placeholder();
+      Placeholder tabuMoveMaker = new Placeholder();
       Placeholder moveMaker = new Placeholder();
       DataTableValuesCollector valuesCollector = new DataTableValuesCollector();
@@ -143,9 +144,9 @@
       moveGenerator.OperatorParameter.ActualName = "MoveGenerator";
 
-      moveQualityEvaluator.Name = "MoveQualityEvaluator (placeholder)";
-      moveQualityEvaluator.OperatorParameter.ActualName = "MoveQualityEvaluator";
-
-      moveTabuEvaluator.Name = "MoveTabuEvaluator (placeholder)";
-      moveTabuEvaluator.OperatorParameter.ActualName = "MoveTabuEvaluator";
+      moveEvaluator.Name = "MoveEvaluator (placeholder)";
+      moveEvaluator.OperatorParameter.ActualName = "MoveEvaluator";
+
+      tabuMoveEvaluator.Name = "TabuMoveEvaluator (placeholder)";
+      tabuMoveEvaluator.OperatorParameter.ActualName = "TabuMoveEvaluator";
 
       moveQualitySorter.DescendingParameter.ActualName = "Maximization";
@@ -162,6 +163,6 @@
       moveMakingProcessor.Name = "MoveMaking processor (UniformSequentialSubScopesProcessor)";
 
-      moveTabuMaker.Name = "MoveTabuMaker (placeholder)";
-      moveTabuMaker.OperatorParameter.ActualName = "MoveTabuMaker";
+      tabuMoveMaker.Name = "TabuMoveMaker (placeholder)";
+      tabuMoveMaker.OperatorParameter.ActualName = "TabuMoveMaker";
 
       moveMaker.Name = "MoveMaker (placeholder)";
@@ -198,14 +199,14 @@
       mainProcessor.Successor = valuesCollector;
       moveGenerator.Successor = moveEvaluationProcessor;
-      moveEvaluationProcessor.Operator = moveQualityEvaluator;
+      moveEvaluationProcessor.Operator = moveEvaluator;
       moveEvaluationProcessor.Successor = moveQualitySorter;
-      moveQualityEvaluator.Successor = moveTabuEvaluator;
+      moveEvaluator.Successor = tabuMoveEvaluator;
       moveQualitySorter.Successor = bestAverageWorstMoveQualityCalculator;
       bestAverageWorstMoveQualityCalculator.Successor = tabuSelector;
       tabuSelector.Successor = rightReducer;
       rightReducer.Successor = moveMakingProcessor;
-      moveMakingProcessor.Operator = moveTabuMaker;
+      moveMakingProcessor.Operator = tabuMoveMaker;
       moveMakingProcessor.Successor = subScopesRemover;
-      moveTabuMaker.Successor = moveMaker;
+      tabuMoveMaker.Successor = moveMaker;
       valuesCollector.Successor = iterationsCounter;
       iterationsCounter.Successor = iterationsComparator;
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 3073)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 3074)
@@ -98,4 +98,5 @@
     <Compile Include="Interfaces\IPermutationMoveOperator.cs" />
     <Compile Include="Interfaces\IPermutationOperator.cs" />
+    <Compile Include="Interfaces\IThreeOptPermutationMoveOperator.cs" />
     <Compile Include="Interfaces\ITwoOptPermutationMoveOperator.cs" />
     <Compile Include="Manipulators\InsertionManipulator.cs" />
@@ -106,4 +107,8 @@
     <Compile Include="Manipulators\TranslocationInversionManipulator.cs" />
     <Compile Include="Manipulators\TranslocationManipulator.cs" />
+    <Compile Include="Moves\ThreeIndexMove.cs" />
+    <Compile Include="Moves\ThreeOpt\StochasticThreeOptMoveGenerator.cs" />
+    <Compile Include="Moves\ThreeOpt\ThreeOptMove.cs" />
+    <Compile Include="Moves\ThreeOpt\ThreeOptMoveGenerator.cs" />
     <Compile Include="Moves\TwoOpt\ExhaustiveTwoOptMoveGenerator.cs">
       <SubType>Code</SubType>
@@ -120,13 +125,7 @@
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="Moves\TwoOpt\TwoOptMoveTabuAttribute.cs">
-      <SubType>Code</SubType>
-    </Compile>
-    <Compile Include="Moves\TwoOpt\TwoOptMoveTabuEvaluator.cs">
-      <SubType>Code</SubType>
-    </Compile>
-    <Compile Include="Moves\TwoOpt\TwoOptMoveTabuMaker.cs">
-      <SubType>Code</SubType>
-    </Compile>
+    <Compile Include="Moves\TwoOpt\TwoOptTabuMoveAttribute.cs" />
+    <Compile Include="Moves\TwoOpt\TwoOptTabuMoveEvaluator.cs" />
+    <Compile Include="Moves\TwoOpt\TwoOptTabuMoveMaker.cs" />
     <Compile Include="PermutationManipulator.cs" />
     <Compile Include="PermutationCrossover.cs" />
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IThreeOptPermutationMoveOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IThreeOptPermutationMoveOperator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IThreeOptPermutationMoveOperator.cs	(revision 3074)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IThreeOptPermutationMoveOperator : IPermutationMoveOperator {
+    ILookupParameter<ThreeOptMove> ThreeOptMoveParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs	(revision 3074)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("ThreeIndexMove", "A move on a permutation that is specified by 3 indices")]
+  [StorableClass]
+  public class ThreeIndexMove : Item {
+    [Storable]
+    public int Index1 { get; protected set; }
+    [Storable]
+    public int Index2 { get; protected set; }
+    [Storable]
+    public int Index3 { get; protected set; }
+    [Storable]
+    public Permutation Permutation { get; protected set; }
+
+    public ThreeIndexMove()
+      : base() {
+      Index1 = -1;
+      Index2 = -1;
+      Index3 = -1;
+      Permutation = null;
+    }
+
+    public ThreeIndexMove(int index1, int index2, int index3, Permutation permutation)
+      : base() {
+      Index1 = index1;
+      Index2 = index2;
+      Index3 = index3;
+      Permutation = permutation;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      ThreeIndexMove clone = (ThreeIndexMove)base.Clone(cloner);
+      clone.Index1 = Index1;
+      clone.Index2 = Index2;
+      clone.Index3 = Index3;
+      if (Permutation != null)
+        clone.Permutation = (Permutation)Permutation.Clone(cloner);
+      return clone;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMoveGenerator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMoveGenerator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/StochasticThreeOptMoveGenerator.cs	(revision 3074)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticThreeOptMoveGenerator", "Randomly samples n from all possible 3-opt moves from a given permutation.")]
+  [StorableClass]
+  public class StochasticThreeOptMoveGenerator : ThreeOptMoveGenerator, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    private ValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public IntValue SampleSize {
+      get { return SampleSizeParameter.Value; }
+      set { SampleSizeParameter.Value = value; }
+    }
+
+    public StochasticThreeOptMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
+    }
+
+    public static ThreeOptMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      /*int totalMoves = (length) * (length - 1) / 2 - 3;
+      // FIXME: Remove this comment if ExhaustiveThreeOptMoveGenerator exists, otherwise alter the exception message below.
+      if (sampleSize >= totalMoves) throw new InvalidOperationException("StochasticThreeOptMoveGenerator: Sample size (" + sampleSize + ") is larger than the set of all possible moves (" + totalMoves + "), use the ExhaustiveThreeOptMoveGenerator instead.");
+      */
+      ThreeOptMove[] moves = new ThreeOptMove[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        int index1, index2, index3;
+        do {
+          index1 = random.Next(length - 1);
+          index2 = random.Next(index1 + 1, length);
+        } while (index2 - index1 == length - 1);
+        do {
+          index3 = random.Next(length);
+        } while (index1 <= index3 && index3 <= index2 + 1);
+        moves[i] = new ThreeOptMove(index1, index2, index3);
+      }
+      return moves;
+    }
+
+    protected override ThreeOptMove[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ThreeOptMove.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ThreeOptMove.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ThreeOptMove.cs	(revision 3074)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("ThreeOptMove", "A move that changes three edges by performing a translocation.")]
+  [StorableClass]
+  public class ThreeOptMove : ThreeIndexMove {
+    public ThreeOptMove()
+      : base() {
+    }
+
+    public ThreeOptMove(int index1, int index2, int index3)
+      : base(index1, index2, index3, null) {
+    }
+
+    public ThreeOptMove(int index1, int index2, int index3, Permutation permutation)
+      : base(index1, index2, index3, permutation) {
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ThreeOptMoveGenerator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ThreeOptMoveGenerator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/ThreeOptMoveGenerator.cs	(revision 3074)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("ThreeOptMoveGenerator", "Base class for move generators that produce 3-opt moves.")]
+  [StorableClass]
+  public abstract class ThreeOptMoveGenerator : SingleSuccessorOperator, IThreeOptPermutationMoveOperator, IMoveGenerator {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<ThreeOptMove> ThreeOptMoveParameter {
+      get { return (LookupParameter<ThreeOptMove>)Parameters["Move"]; }
+    }
+    protected ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+
+    public ThreeOptMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation for which moves should be generated."));
+      Parameters.Add(new LookupParameter<ThreeOptMove>("Move", "The moves that should be generated in subscopes."));
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
+    }
+
+    public override IOperation Apply() {
+      Permutation p = PermutationParameter.ActualValue;
+      ThreeOptMove[] moves = GenerateMoves(p);
+      Scope[] moveScopes = new Scope[moves.Length];
+      for (int i = 0; i < moveScopes.Length; i++) {
+        moveScopes[i] = new Scope(i.ToString());
+        moveScopes[i].Variables.Add(new Variable(ThreeOptMoveParameter.ActualName, moves[i]));
+      }
+      CurrentScopeParameter.ActualValue.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract ThreeOptMove[] GenerateMoves(Permutation permutation);
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticTwoOptMoveGenerator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticTwoOptMoveGenerator.cs	(revision 3073)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/StochasticTwoOptMoveGenerator.cs	(revision 3074)
@@ -38,4 +38,9 @@
     }
 
+    public IntValue SampleSize {
+      get { return SampleSizeParameter.Value; }
+      set { SampleSizeParameter.Value = value; }
+    }
+
     public StochasticTwoOptMoveGenerator()
       : base() {
@@ -50,6 +55,8 @@
       TwoOptMove[] moves = new TwoOptMove[sampleSize];
       for (int i = 0; i < sampleSize; i++) {
-        int index1 = random.Next(length - 1);
-        int index2 = random.Next(index1 + 1, length);
+        int index1 = random.Next(length - 1), index2;
+        if (index1 >= 2)
+          index2 = random.Next(index1 + 1, length);
+        else index2 = random.Next(index1 + 1, length - (2 - index1));
         moves[i] = new TwoOptMove(index1, index2);
       }
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveGenerator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveGenerator.cs	(revision 3073)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveGenerator.cs	(revision 3074)
@@ -35,5 +35,5 @@
     }
     public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
-      get { return (LookupParameter<TwoOptMove>)Parameters["Move"]; }
+      get { return (LookupParameter<TwoOptMove>)Parameters["TwoOptMove"]; }
     }
     protected ScopeParameter CurrentScopeParameter {
@@ -44,5 +44,5 @@
       : base() {
       Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation for which moves should be generated."));
-      Parameters.Add(new LookupParameter<TwoOptMove>("Move", "The moves that should be generated in subscopes."));
+      Parameters.Add(new LookupParameter<TwoOptMove>("TwoOptMove", "The moves that should be generated in subscopes."));
       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
     }
@@ -61,4 +61,8 @@
 
     protected abstract TwoOptMove[] GenerateMoves(Permutation permutation);
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveMaker.cs	(revision 3073)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveMaker.cs	(revision 3074)
@@ -33,11 +33,11 @@
   public class TwoOptMoveMaker : SingleSuccessorOperator, ITwoOptPermutationMoveOperator, IMoveMaker {
     public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
     public ILookupParameter<DoubleValue> MoveQualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
     }
     public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
-      get { return (LookupParameter<TwoOptMove>)Parameters["Move"]; }
+      get { return (ILookupParameter<TwoOptMove>)Parameters["TwoOptMove"]; }
     }
     public ILookupParameter<Permutation> PermutationParameter {
@@ -48,5 +48,5 @@
       : base() {
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
-      Parameters.Add(new LookupParameter<TwoOptMove>("Move", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<TwoOptMove>("TwoOptMove", "The move to evaluate."));
       Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
       Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
@@ -64,4 +64,8 @@
       return base.Apply();
     }
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
   }
 }
Index: unk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveTabuAttribute.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveTabuAttribute.cs	(revision 3073)
+++ 	(revision )
@@ -1,51 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Encodings.PermutationEncoding {
-  [Item("TwoOptMoveTabuAttribute", "Specifies the tabu attributes for a 2-opt move.")]
-  [StorableClass]
-  public class TwoOptMoveTabuAttribute : Item {
-    [Storable]
-    public int Edge1Source { get; private set; }
-    [Storable]
-    public int Edge1Target { get; private set; }
-    [Storable]
-    public int Edge2Source { get; private set; }
-    [Storable]
-    public int Edge2Target { get; private set; }
-
-    [StorableConstructor]
-    private TwoOptMoveTabuAttribute()
-      : base() {
-    }
-
-    public TwoOptMoveTabuAttribute(int edge1Source, int edge1Target, int edge2Source, int edge2Target)
-      : base() {
-      Edge1Source = edge1Source;
-      Edge1Target = edge1Target;
-      Edge2Source = edge2Source;
-      Edge2Target = edge2Target;
-    }
-  }
-}
Index: unk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveTabuEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveTabuEvaluator.cs	(revision 3073)
+++ 	(revision )
@@ -1,89 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Encodings.PermutationEncoding {
-  [Item("TwoOptMoveTabuEvaluator", "Evaluates whether a given 2-opt move is tabu.")]
-  [StorableClass]
-  public class TwoOptMoveTabuEvaluator : SingleSuccessorOperator, ITwoOptPermutationMoveOperator, ITabuMoveEvaluator {
-    public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
-      get { return (LookupParameter<TwoOptMove>)Parameters["Move"]; }
-    }
-    public ILookupParameter<Permutation> PermutationParameter {
-      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
-    }
-    public LookupParameter<ItemList<IItem>> TabuListParameter {
-      get { return (LookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
-    }
-    public LookupParameter<BoolValue> MoveTabuParameter {
-      get { return (LookupParameter<BoolValue>)Parameters["MoveTabu"]; }
-    }
-    private ScopeParameter CurrentScopeParameter {
-      get { return (ScopeParameter)Parameters["CurrentScope"]; }
-    }
-
-    public TwoOptMoveTabuEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<TwoOptMove>("Move", "The move to evaluate."));
-      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
-      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope."));
-    }
-
-    public override IOperation Apply() {
-      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
-      TwoOptMove move = TwoOptMoveParameter.ActualValue;
-      Permutation permutation = PermutationParameter.ActualValue;
-      int length = permutation.Length;
-      int E1S = permutation.GetCircular(move.Index1 - 1);
-      int E1T = permutation[move.Index1];
-      int E2S = permutation[move.Index2];
-      int E2T = permutation.GetCircular(move.Index2 + 1);
-      bool isTabu = false;
-      foreach (IItem tabuMove in tabuList) {
-        TwoOptMoveTabuAttribute attribute = (tabuMove as TwoOptMoveTabuAttribute);
-        if (attribute != null) {
-          // if previously deleted Edge1Source-Target is readded
-          if (attribute.Edge1Source == E1S && attribute.Edge1Target == E2S || attribute.Edge1Source == E2S && attribute.Edge1Target == E1S
-            // if previously deleted Edge2Source-Target is readded
-            || attribute.Edge2Source == E1T && attribute.Edge2Target == E2T || attribute.Edge2Source == E2T && attribute.Edge2Target == E1T
-            // if previously added Edge1Source-Edge2Source is deleted
-            || attribute.Edge1Source == E1S && attribute.Edge2Source == E1T || attribute.Edge1Source == E1T && attribute.Edge2Source == E1S
-            // if previously added Edge1Target-Edge2Target is deleted
-            || attribute.Edge1Target == E2S && attribute.Edge2Target == E2T || attribute.Edge1Target == E2T && attribute.Edge2Target == E2S) {
-            isTabu = true;
-            break;
-          }
-        }
-      }
-      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
-      return base.Apply();
-    }
-  }
-}
Index: unk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveTabuMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptMoveTabuMaker.cs	(revision 3073)
+++ 	(revision )
@@ -1,74 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Encodings.PermutationEncoding.Moves {
-  [Item("TwoOptMoveTabuMaker", "Declares a given 2-opt move as tabu, by adding its attributes to the tabu list. It also removes the oldest entry in the tabu list when its size is greater than tenure.")]
-  [StorableClass]
-  public class TwoOptMoveTabuMaker : SingleSuccessorOperator, ITwoOptPermutationMoveOperator, ITabuMoveMaker {
-    public ILookupParameter<Permutation> PermutationParameter {
-      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
-    }
-    public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
-      get { return (LookupParameter<TwoOptMove>)Parameters["Move"]; }
-    }
-    public LookupParameter<ItemList<IItem>> TabuListParameter {
-      get { return (LookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
-    }
-    public ValueLookupParameter<IntValue> TabuTenureParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["TabuTenure"]; }
-    }
-
-    public TwoOptMoveTabuMaker()
-      : base() {
-      Parameters.Add(new LookupParameter<TwoOptMove>("Move", "The move that was made."));
-      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list where move attributes are stored."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("TabuTenure", "The tenure of the tabu list."));
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-    }
-
-    public override IOperation Apply() {
-      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
-      TwoOptMove move = TwoOptMoveParameter.ActualValue;
-      IntValue tabuTenure = TabuTenureParameter.ActualValue;
-      Permutation permutation = PermutationParameter.ActualValue;
-      
-      if (tabuList.Count >= tabuTenure.Value) {
-        for (int i = 0; i < tabuTenure.Value - 1; i++)
-          tabuList[i] = tabuList[i + 1];
-        tabuList.RemoveAt(tabuList.Count - 1);
-      }
-
-      TwoOptMoveTabuAttribute attribute = new TwoOptMoveTabuAttribute(
-        permutation.GetCircular(move.Index1 - 1), permutation[move.Index1],
-        permutation[move.Index2], permutation.GetCircular(move.Index2 + 1));
-      tabuList.Add(attribute);
-      return base.Apply();
-    }
-  }
-}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveAttribute.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveAttribute.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveAttribute.cs	(revision 3074)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("TwoOptTabuMoveAttribute", "Specifies the tabu attributes for a 2-opt move.")]
+  [StorableClass]
+  public class TwoOptTabuMoveAttribute : Item {
+    [Storable]
+    public int Edge1Source { get; private set; }
+    [Storable]
+    public int Edge1Target { get; private set; }
+    [Storable]
+    public int Edge2Source { get; private set; }
+    [Storable]
+    public int Edge2Target { get; private set; }
+
+    [StorableConstructor]
+    private TwoOptTabuMoveAttribute()
+      : base() {
+    }
+
+    public TwoOptTabuMoveAttribute(int edge1Source, int edge1Target, int edge2Source, int edge2Target)
+      : base() {
+      Edge1Source = edge1Source;
+      Edge1Target = edge1Target;
+      Edge2Source = edge2Source;
+      Edge2Target = edge2Target;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveEvaluator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveEvaluator.cs	(revision 3074)
@@ -0,0 +1,93 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("TwoOptTabuMoveEvaluator", "Evaluates whether a given 2-opt move is tabu.")]
+  [StorableClass]
+  public class TwoOptTabuMoveEvaluator : SingleSuccessorOperator, ITwoOptPermutationMoveOperator, ITabuMoveEvaluator {
+    public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
+      get { return (LookupParameter<TwoOptMove>)Parameters["TwoOptMove"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public LookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (LookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public LookupParameter<BoolValue> MoveTabuParameter {
+      get { return (LookupParameter<BoolValue>)Parameters["MoveTabu"]; }
+    }
+    private ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+
+    public TwoOptTabuMoveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<TwoOptMove>("TwoOptMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope."));
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      TwoOptMove move = TwoOptMoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      int E1S = permutation.GetCircular(move.Index1 - 1);
+      int E1T = permutation[move.Index1];
+      int E2S = permutation[move.Index2];
+      int E2T = permutation.GetCircular(move.Index2 + 1);
+      bool isTabu = false;
+      foreach (IItem tabuMove in tabuList) {
+        TwoOptTabuMoveAttribute attribute = (tabuMove as TwoOptTabuMoveAttribute);
+        if (attribute != null) {
+          // if previously deleted Edge1Source-Target is readded
+          if (attribute.Edge1Source == E1S && attribute.Edge1Target == E2S || attribute.Edge1Source == E2S && attribute.Edge1Target == E1S
+            // if previously deleted Edge2Source-Target is readded
+            || attribute.Edge2Source == E1T && attribute.Edge2Target == E2T || attribute.Edge2Source == E2T && attribute.Edge2Target == E1T
+            // if previously added Edge1Source-Edge2Source is deleted
+            || attribute.Edge1Source == E1S && attribute.Edge2Source == E1T || attribute.Edge1Source == E1T && attribute.Edge2Source == E1S
+            // if previously added Edge1Target-Edge2Target is deleted
+            || attribute.Edge1Target == E2S && attribute.Edge2Target == E2T || attribute.Edge1Target == E2T && attribute.Edge2Target == E2S) {
+            isTabu = true;
+            break;
+          }
+        }
+      }
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveMaker.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/TwoOptTabuMoveMaker.cs	(revision 3074)
@@ -0,0 +1,78 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("TwoOptTabuMoveMaker", "Declares a given 2-opt move as tabu, by adding its attributes to the tabu list. It also removes the oldest entry in the tabu list when its size is greater than tenure.")]
+  [StorableClass]
+  public class TwoOptTabuMoveMaker : SingleSuccessorOperator, ITwoOptPermutationMoveOperator, ITabuMoveMaker {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
+      get { return (LookupParameter<TwoOptMove>)Parameters["TwoOptMove"]; }
+    }
+    public LookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (LookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ValueLookupParameter<IntValue> TabuTenureParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["TabuTenure"]; }
+    }
+
+    public TwoOptTabuMoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<TwoOptMove>("TwoOptMove", "The move that was made."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list where move attributes are stored."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("TabuTenure", "The tenure of the tabu list."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      TwoOptMove move = TwoOptMoveParameter.ActualValue;
+      IntValue tabuTenure = TabuTenureParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      
+      if (tabuList.Count >= tabuTenure.Value) {
+        for (int i = 0; i < tabuTenure.Value - 1; i++)
+          tabuList[i] = tabuList[i + 1];
+        tabuList.RemoveAt(tabuList.Count - 1);
+      }
+
+      TwoOptTabuMoveAttribute attribute = new TwoOptTabuMoveAttribute(
+        permutation.GetCircular(move.Index1 - 1), permutation[move.Index1],
+        permutation[move.Index2], permutation.GetCircular(move.Index2 + 1));
+      tabuList.Add(attribute);
+      return base.Apply();
+    }
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLab.Problems.TSP-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLab.Problems.TSP-3.3.csproj	(revision 3073)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLab.Problems.TSP-3.3.csproj	(revision 3074)
@@ -89,7 +89,12 @@
     <Compile Include="Interfaces\ITSPCoordinatesPathEvaluator.cs" />
     <Compile Include="Interfaces\ITSPEvaluator.cs" />
+    <Compile Include="Interfaces\ITSPMoveEvaluator.cs" />
     <Compile Include="Interfaces\ITSPPathEvaluator.cs" />
     <Compile Include="HeuristicLabProblemsTSPPlugin.cs" />
-    <Compile Include="MoveEvaluators\TwoOptMoveTSPEvaluator.cs">
+    <Compile Include="Interfaces\ITSPPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TwoOptMoveTSPRoundedEuclideanPathEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TSPPathMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TSPMoveEvaluator.cs" />
+    <Compile Include="MoveEvaluators\TwoOptMoveTSPCoordinatesPathEvaluator.cs">
       <SubType>Code</SubType>
     </Compile>
Index: /trunk/sources/HeuristicLab.Problems.TSP/3.3/Interfaces/ITSPMoveEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/Interfaces/ITSPMoveEvaluator.cs	(revision 3074)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.TSP {
+  public interface ITSPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator {
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.TSP/3.3/Interfaces/ITSPPathMoveEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/Interfaces/ITSPPathMoveEvaluator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/Interfaces/ITSPPathMoveEvaluator.cs	(revision 3074)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+
+namespace HeuristicLab.Problems.TSP {
+  public interface ITSPPathMoveEvaluator : ITSPMoveEvaluator, IPermutationMoveOperator {
+    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
+    ILookupParameter<DoubleMatrix> DistanceMatrixParameter { get; }
+    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TSPMoveEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TSPMoveEvaluator.cs	(revision 3074)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <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 ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+
+    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: /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs	(revision 3074)
@@ -0,0 +1,57 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <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<DoubleMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    }
+    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
+    }
+
+    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<DoubleMatrix>("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."));
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPCoordinatesPathEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPCoordinatesPathEvaluator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPCoordinatesPathEvaluator.cs	(revision 3074)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <summary>
+  /// An operator to evaluate 2-opt moves.
+  /// </summary>
+  [Item("TwoOptMoveTSPCoordinatesPathEvaluator", "Base class for evaluating 2-opt moves given the cities' coordinates.")]
+  [StorableClass]
+  public abstract class TwoOptMoveTSPCoordinatesPathEvaluator : TSPPathMoveEvaluator, ITwoOptPermutationMoveOperator {
+    public ILookupParameter<TwoOptMove> TwoOptMoveParameter {
+      get { return (ILookupParameter<TwoOptMove>)Parameters["TwoOptMove"]; }
+    }
+
+    public TwoOptMoveTSPCoordinatesPathEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<TwoOptMove>("TwoOptMove", "The move to evaluate."));
+    }
+
+    public override IOperation Apply() {
+      Permutation permutation = PermutationParameter.ActualValue;
+      TwoOptMove move = TwoOptMoveParameter.ActualValue;
+      double moveQuality = QualityParameter.ActualValue.Value;
+      int edge1source = permutation.GetCircular(move.Index1 - 1);
+      int edge1target = permutation[move.Index1];
+      int edge2source = permutation[move.Index2];
+      int edge2target = permutation.GetCircular(move.Index2 + 1);
+
+      if (!(move.Index1 == 0 && move.Index2 == permutation.Length - 1)) { // a change like this would break the calculation (it doesn't actually change the quality anyway)
+        if (UseDistanceMatrixParameter.ActualValue.Value) {
+          DoubleMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
+          if (distanceMatrix == null) {
+            distanceMatrix = CalculateDistanceMatrix(CoordinatesParameter.ActualValue);
+            DistanceMatrixParameter.ActualValue = distanceMatrix;
+          }
+          // remove two edges
+          moveQuality -= distanceMatrix[edge1source, edge1target];
+          moveQuality -= distanceMatrix[edge2source, edge2target];
+          // add two edges
+          moveQuality += distanceMatrix[edge1source, edge2source];
+          moveQuality += distanceMatrix[edge1target, edge2target];
+        } else {
+          DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
+          // remove two edges
+          moveQuality -= CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+            coordinates[edge1target, 0], coordinates[edge1target, 1]);
+          moveQuality -= CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
+            coordinates[edge2target, 0], coordinates[edge2target, 1]);
+          // add two edges
+          moveQuality += CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
+            coordinates[edge2source, 0], coordinates[edge2source, 1]);
+          moveQuality += CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
+            coordinates[edge2target, 0], coordinates[edge2target, 1]);
+        }
+      }
+      if (MoveQualityParameter.ActualValue == null) MoveQualityParameter.ActualValue = new DoubleValue(moveQuality);
+      else MoveQualityParameter.ActualValue.Value = moveQuality;
+      return base.Apply();
+    }
+
+    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
+
+    protected DoubleMatrix CalculateDistanceMatrix(DoubleMatrix c) {
+      DoubleMatrix distanceMatrix = new DoubleMatrix(c.Rows, c.Rows);
+      for (int i = 0; i < distanceMatrix.Rows; i++) {
+        for (int j = 0; j < distanceMatrix.Columns; j++)
+          distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);
+      }
+      return distanceMatrix;
+    }
+  }
+}
Index: unk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPEvaluator.cs	(revision 3073)
+++ 	(revision )
@@ -1,90 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System;
-
-namespace HeuristicLab.Problems.TSP {
-  /// <summary>
-  /// An operator to evaluate 2-opt moves.
-  /// </summary>
-  [Item("TwoOptMoveTSPEvaluator", "Evaluates a 2-opt move (rounded euclidean distances) by summing up the length of all added edges and subtracting the length of all deleted edges.")]
-  [StorableClass]
-  public class TwoOptMoveTSPEvaluator : SingleSuccessorOperator {
-    public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-    public LookupParameter<TwoOptMove> MoveParameter {
-      get { return (LookupParameter<TwoOptMove>)Parameters["Move"]; }
-    }
-    public LookupParameter<DoubleValue> MoveQualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
-    }
-    public ILookupParameter<Permutation> PermutationParameter {
-      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
-    }
-    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
-    }
-
-    public TwoOptMoveTSPEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The evaluated quality of the TSP solution."));
-      Parameters.Add(new LookupParameter<TwoOptMove>("Move", "The move to evaluate."));
-      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "Where to store the move quality."));
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The city's coordinates."));
-    }
-
-    public override IOperation Apply() {
-      TwoOptMove move = MoveParameter.ActualValue;
-      Permutation permutation = PermutationParameter.ActualValue;
-      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
-      double moveQuality = QualityParameter.ActualValue.Value;
-      int edge1source = permutation.GetCircular(move.Index1 - 1);
-      int edge1target = permutation[move.Index1];
-      int edge2source = permutation[move.Index2];
-      int edge2target = permutation.GetCircular(move.Index2 + 1);
-      // remove two edges
-      moveQuality -= CalculateDistance(coordinates[edge1source ,0], coordinates[edge1source, 1],
-        coordinates[edge1target, 0], coordinates[edge1target, 1]);
-      moveQuality -= CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
-        coordinates[edge2target, 0], coordinates[edge2target, 1]);
-      // add two edges
-      moveQuality += CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
-        coordinates[edge2source, 0], coordinates[edge2source, 1]);
-      moveQuality += CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
-        coordinates[edge2target, 0], coordinates[edge2target, 1]);
-      if (MoveQualityParameter.ActualValue == null) MoveQualityParameter.ActualValue = new DoubleValue(moveQuality);
-      else MoveQualityParameter.ActualValue.Value = moveQuality;
-      return base.Apply();
-    }
-
-    private double CalculateDistance(double x1, double y1, double x2, double y2) {
-      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
-    }
-  }
-}
Index: /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPRoundedEuclideanPathEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPRoundedEuclideanPathEvaluator.cs	(revision 3074)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/MoveEvaluators/TwoOptMoveTSPRoundedEuclideanPathEvaluator.cs	(revision 3074)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <summary>
+  /// An operator to evaluate 2-opt moves.
+  /// </summary>
+  [Item("TwoOptMoveTSPRoundedEuclideanPathEvaluator", "Evaluates a 2-opt move (rounded euclidean distances) by summing up the length of all added edges and subtracting the length of all deleted edges.")]
+  [StorableClass]
+  public class TwoOptMoveTSPRoundedEuclideanPathEvaluator : TwoOptMoveTSPCoordinatesPathEvaluator {
+    protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
+      return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.TSP/3.3/TSP.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TSP/3.3/TSP.cs	(revision 3073)
+++ /trunk/sources/HeuristicLab.Problems.TSP/3.3/TSP.cs	(revision 3074)
@@ -196,4 +196,16 @@
       OnEvaluatorChanged();
     }
+    private void MoveGenerator_TwoOptMoveParameter_ActualNameChanged(object sender, EventArgs e) {
+      string name = ((ILookupParameter<TwoOptMove>)sender).ActualName;
+      foreach (ITwoOptPermutationMoveOperator op in Operators.OfType<ITwoOptPermutationMoveOperator>()) {
+        if (!(op is IMoveGenerator)) op.TwoOptMoveParameter.ActualName = name;
+      }
+    }
+    private void MoveGenerator_ThreeOptMoveParameter_ActualNameChanged(object sender, EventArgs e) {
+      string name = ((ILookupParameter<ThreeOptMove>)sender).ActualName;
+      foreach (IThreeOptPermutationMoveOperator op in Operators.OfType<IThreeOptPermutationMoveOperator>()) {
+        if (!(op is IMoveGenerator)) op.ThreeOptMoveParameter.ActualName = name;
+      }
+    }
     #endregion
 
@@ -228,4 +240,5 @@
         ParameterizeOperators();
       }
+      InitializeMoveGenerators();
     }
     private void ParameterizeOperators() {
@@ -237,5 +250,26 @@
         op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
       }
-    }
+      foreach (IPermutationMoveOperator op in Operators.OfType<IPermutationMoveOperator>()) {
+        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+      }
+      foreach (ITSPPathMoveEvaluator op in Operators.OfType<ITSPPathMoveEvaluator>()) {
+        op.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
+        op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
+        op.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
+      }
+    }
+    private void InitializeMoveGenerators() {
+      foreach (ITwoOptPermutationMoveOperator op in Operators.OfType<ITwoOptPermutationMoveOperator>()) {
+        if (op is IMoveGenerator) {
+          op.TwoOptMoveParameter.ActualNameChanged += new EventHandler(MoveGenerator_TwoOptMoveParameter_ActualNameChanged);
+        }
+      }
+      foreach (IThreeOptPermutationMoveOperator op in Operators.OfType<IThreeOptPermutationMoveOperator>()) {
+        if (op is IMoveGenerator) {
+          op.ThreeOptMoveParameter.ActualNameChanged += new EventHandler(MoveGenerator_ThreeOptMoveParameter_ActualNameChanged);
+        }
+      }
+    }
+
     private void ClearDistanceMatrix() {
       DistanceMatrixParameter.Value = null;
