Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/HeuristicLab.Algorithms.ScatterSearch-3.3.csproj
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/HeuristicLab.Algorithms.ScatterSearch-3.3.csproj	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/HeuristicLab.Algorithms.ScatterSearch-3.3.csproj	(revision 7756)
@@ -87,5 +87,9 @@
   <ItemGroup>
     <Compile Include="DiversityCalculator.cs" />
+    <Compile Include="IPathRelinker.cs" />
     <Compile Include="Knapsack\BinaryVectorDiversityCalculator.cs" />
+    <Compile Include="Knapsack\KnapsackPathRelinker.cs" />
+    <Compile Include="TravelingSalesman\TravelingSalesmanPathRelinker.cs" />
+    <Compile Include="PathRelinker.cs" />
     <Compile Include="Knapsack\INBinaryVectorCrossover.cs" />
     <Compile Include="IScatterSearchTargetProcessor.cs" />
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/IPathRelinker.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/IPathRelinker.cs	(revision 7756)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/IPathRelinker.cs	(revision 7756)
@@ -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.Optimization;
+
+namespace HeuristicLab.Algorithms.ScatterSearch {
+  /// <summary>
+  /// An interface which represents an operator for path relinking.
+  /// </summary>
+  public interface IPathRelinker : ICrossover {
+    ILookupParameter<ItemArray<IItem>> ParentsParameter { get; }
+  }
+}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/BinaryVectorDiversityCalculator.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/BinaryVectorDiversityCalculator.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/BinaryVectorDiversityCalculator.cs	(revision 7756)
@@ -31,5 +31,5 @@
   [Item("BinaryVectorDiversityCalculator", "An operator that performs diversity calculation between bool-valued vectors.")]
   [StorableClass]
-  public sealed class BinaryVectorDiversityCalculator : HeuristicLab.Algorithms.ScatterSearch.DiversityCalculator {
+  public sealed class BinaryVectorDiversityCalculator : DiversityCalculator {
     [StorableConstructor]
     private BinaryVectorDiversityCalculator(bool deserializing) : base(deserializing) { }
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/INBinaryVectorCrossover.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/INBinaryVectorCrossover.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/INBinaryVectorCrossover.cs	(revision 7756)
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/KnapsackImprovementOperator.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/KnapsackImprovementOperator.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/KnapsackImprovementOperator.cs	(revision 7756)
@@ -39,5 +39,4 @@
   [StorableClass]
   public sealed class KnapsackImprovementOperator : SingleSuccessorOperator, ILocalImprovementOperator, IScatterSearchTargetProcessor {
-
     #region Problem properties
     public Type ProblemType {
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/KnapsackPathRelinker.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/KnapsackPathRelinker.cs	(revision 7756)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/KnapsackPathRelinker.cs	(revision 7756)
@@ -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 System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ScatterSearch.Knapsack {
+  /// <summary>
+  /// An operator that relinks paths between knapsack solutions.
+  /// </summary>
+  [Item("KnapsackPathRelinker", "An operator that relinks paths between knapsack solutions.")]
+  [StorableClass]
+  public sealed class KnapsackPathRelinker : PathRelinker {
+    [StorableConstructor]
+    private KnapsackPathRelinker(bool deserializing) : base(deserializing) { }
+    private KnapsackPathRelinker(KnapsackPathRelinker original, Cloner cloner) : base(original, cloner) { }
+    public KnapsackPathRelinker()
+      : base() {
+      ParentsParameter.ActualName = "KnapsackSolution";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new KnapsackPathRelinker(this, cloner);
+    }
+
+    public static ItemArray<IItem> Apply(IItem initiator, IItem guide, PercentValue n) {
+      var v1 = initiator.Clone() as BinaryVector;
+      var v2 = guide as BinaryVector;
+
+      if (v1.Length != v2.Length)
+        throw new ArgumentException("KnapsackPathRelinker: The solutions are of different length.");
+      if (n.Value == 0.0)
+        throw new ArgumentException("KnapsackPathRelinker: RelinkingAccuracy is 0.");
+
+      var solutions = new List<BinaryVector>();
+      for (int i = 0; i < v1.Length; i++) {
+        if (v1[i] != v2[i]) {
+          v1[i] = v2[i];
+          solutions.Add((BinaryVector)v1.Clone());
+        }
+      }
+
+      var stepSize = 1 / n.Value;
+      var selection = new List<IItem>();
+      for (int i = 0; i < solutions.Count; i = (int)Math.Round(i + stepSize)) {
+        selection.Add(solutions.ElementAt(i));
+      }
+
+      return new ItemArray<IItem>(selection);
+    }
+
+    protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) {
+      if (parents.Length != 2) throw new ArgumentException("KnapsackPathRelinker: The number of parents is not equal to 2.");
+      return Apply(parents[0], parents[1], n);
+    }
+  }
+}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NBinaryVectorCrossover.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NBinaryVectorCrossover.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NBinaryVectorCrossover.cs	(revision 7756)
@@ -64,6 +64,6 @@
       #region Create parameters
       Parameters.Add(new ScopeParameter("CurrentScope"));
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
-      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("Parents", "The parent vectors which should be crossed."));
+      Parameters.Add(new LookupParameter<IRandom>("Random"));
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("Parents"));
       #endregion
       ParentsParameter.ActualName = "BinaryVector";
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NChildCrossover.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NChildCrossover.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/Knapsack/NChildCrossover.cs	(revision 7756)
@@ -78,5 +78,5 @@
 
     protected override ItemArray<BinaryVector> Cross(IRandom random, ItemArray<BinaryVector> parents) {
-      if (parents.Length != 2) throw new ArgumentException("ERROR in NChildCrossover: The number of parents is not equal to 2");
+      if (parents.Length != 2) throw new ArgumentException("NChildCrossover: The number of parents is not equal to 2.");
 
       if (NParameter.ActualValue == null) throw new InvalidOperationException("NChildCrossover: Parameter " + NParameter.ActualName + " could not be found.");
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/PathRelinker.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/PathRelinker.cs	(revision 7756)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/PathRelinker.cs	(revision 7756)
@@ -0,0 +1,76 @@
+﻿#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.Algorithms.ScatterSearch {
+  /// <summary>
+  /// A base class for operators that perform path relinking.
+  /// </summary>
+  [Item("PathRelinker", "A base class for operators that perform a crossover of bool-valued vectors.")]
+  [StorableClass]
+  public abstract class PathRelinker : SingleSuccessorOperator, IPathRelinker {
+    #region Parameter properties
+    public ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public IValueLookupParameter<PercentValue> RelinkingAccuracyParameter {
+      get { return (IValueLookupParameter<PercentValue>)Parameters["RelinkingAccuracy"]; }
+    }
+    public ILookupParameter<ItemArray<IItem>> ParentsParameter {
+      get { return (IScopeTreeLookupParameter<IItem>)Parameters["Parents"]; }
+    }
+    #endregion
+
+    #region Properties
+    private IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected PathRelinker(bool deserializing) : base(deserializing) { }
+    protected PathRelinker(PathRelinker original, Cloner cloner) : base(original, cloner) { }
+    protected PathRelinker()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ScopeParameter("CurrentScope"));
+      Parameters.Add(new ValueLookupParameter<PercentValue>("RelinkingAccuracy", new PercentValue(0.25)));
+      Parameters.Add(new ScopeTreeLookupParameter<IItem>("Parents"));
+      #endregion
+    }
+
+    public sealed override IOperation Apply() {
+      var relinkedSolutions = Relink(ParentsParameter.ActualValue, RelinkingAccuracyParameter.ActualValue);
+      for (int i = 0; i < relinkedSolutions.Length; i++) {
+        CurrentScope.Variables.Add(new Variable(string.Format("Child {0}", i), relinkedSolutions[i]));
+      }
+      return base.Apply();
+    }
+
+    protected abstract ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n);
+  }
+}
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearch.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearch.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/ScatterSearch.cs	(revision 7756)
@@ -306,4 +306,7 @@
       ICrossover defaultCrossover = Problem.Operators.OfType<ICrossover>().FirstOrDefault();
 
+      CrossoverParameter.ValidValues.Add(new TravelingSalesman.TravelingSalesmanPathRelinker());
+      CrossoverParameter.ValidValues.Add(new Knapsack.KnapsackPathRelinker());
+
       foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
         CrossoverParameter.ValidValues.Add(crossover);
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/PermutationDiversityCalculator.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/PermutationDiversityCalculator.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/PermutationDiversityCalculator.cs	(revision 7756)
@@ -32,5 +32,5 @@
   [Item("PermutationDiversityCalculator", "An operator that performs diversity calculation between permutations.")]
   [StorableClass]
-  public sealed class PermutationDiversityCalculator : HeuristicLab.Algorithms.ScatterSearch.DiversityCalculator {
+  public sealed class PermutationDiversityCalculator : DiversityCalculator {
     [StorableConstructor]
     private PermutationDiversityCalculator(bool deserializing) : base(deserializing) { }
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/TravelingSalesmanImprovementOperator.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/TravelingSalesmanImprovementOperator.cs	(revision 7755)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/TravelingSalesmanImprovementOperator.cs	(revision 7756)
@@ -39,5 +39,4 @@
   [StorableClass]
   public sealed class TravelingSalesmanImprovementOperator : SingleSuccessorOperator, ILocalImprovementOperator, IScatterSearchTargetProcessor {
-
     #region Problem properties
     public Type ProblemType {
@@ -62,6 +61,6 @@
       get { return (IValueLookupParameter<IEvaluator>)Parameters["Evaluator"]; }
     }
-    public IValueLookupParameter<IntValue> ImprovementIterationsParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["ImprovementIterations"]; }
+    public IValueLookupParameter<IntValue> ImprovementAttemptsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ImprovementAttempts"]; }
     }
     public IValueLookupParameter<IRandom> RandomParameter {
@@ -96,7 +95,7 @@
       set { EvaluatorParameter.ActualValue = value; }
     }
-    public IntValue ImprovementIterations {
-      get { return ImprovementIterationsParameter.ActualValue; }
-      set { ImprovementIterationsParameter.ActualValue = value; }
+    public IntValue ImprovementAttempts {
+      get { return ImprovementAttemptsParameter.ActualValue; }
+      set { ImprovementAttemptsParameter.ActualValue = value; }
     }
     public IRandom Random {
@@ -118,9 +117,9 @@
       : base() {
       #region Create parameters
-      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope."));
-      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("Coordinates", "The coordinates of the cities."));
-      Parameters.Add(new ValueLookupParameter<IEvaluator>("Evaluator", "The operator which is used to evaluate new solutions."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("ImprovementIterations", "The number of improvement attempts."));
-      Parameters.Add(new ValueLookupParameter<IRandom>("Random", "..."));
+      Parameters.Add(new ScopeParameter("CurrentScope"));
+      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("Coordinates"));
+      Parameters.Add(new ValueLookupParameter<IEvaluator>("Evaluator"));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ImprovementAttempts", new IntValue(100)));
+      Parameters.Add(new ValueLookupParameter<IRandom>("Random"));
       Parameters.Add(new ValueLookupParameter<IItem>("Target"));
       #endregion
@@ -138,5 +137,5 @@
       double bestLength = currLength;
 
-      for (int i = 0; i < ImprovementIterations.Value; i++) {
+      for (int i = 0; i < ImprovementAttempts.Value; i++) {
         int a = Random.Next(currSol.Length - 1);
         int b = Random.Next(currSol.Length - 1);
Index: /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/TravelingSalesmanPathRelinker.cs
===================================================================
--- /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/TravelingSalesmanPathRelinker.cs	(revision 7756)
+++ /branches/ScatterSearch/HeuristicLab.Algorithms.ScatterSearch/3.3/TravelingSalesman/TravelingSalesmanPathRelinker.cs	(revision 7756)
@@ -0,0 +1,85 @@
+﻿#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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ScatterSearch.TravelingSalesman {
+  /// <summary>
+  /// An operator that relinks paths between traveling salesman solutions.
+  /// </summary>
+  [Item("TravelingSalesmanPathRelinker", "An operator that relinks paths between traveling salesman solutions.")]
+  [StorableClass]
+  public sealed class TravelingSalesmanPathRelinker : PathRelinker {
+    [StorableConstructor]
+    private TravelingSalesmanPathRelinker(bool deserializing) : base(deserializing) { }
+    private TravelingSalesmanPathRelinker(TravelingSalesmanPathRelinker original, Cloner cloner) : base(original, cloner) { }
+    public TravelingSalesmanPathRelinker()
+      : base() {
+      ParentsParameter.ActualName = "TSPTour";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TravelingSalesmanPathRelinker(this, cloner);
+    }
+
+    public static ItemArray<IItem> Apply(IItem initiator, IItem guide, PercentValue n) {
+      var v1 = initiator.Clone() as Permutation;
+      var v2 = guide as Permutation;
+
+      if (v1.Length != v2.Length)
+        throw new ArgumentException("TravelingSalesmanPathRelinker: The solutions are of different length.");
+      if (n.Value == 0.0)
+        throw new ArgumentException("TravelingSalesmanPathRelinker: RelinkingAccuracy is 0.");
+
+      var 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]);
+          // XOR swap
+          v1[i] ^= v1[target.ValueIndex];
+          v1[target.ValueIndex] ^= v1[i];
+          v1[i] ^= v1[target.ValueIndex];
+          solutions.Add((Permutation)v1.Clone());
+        }
+      }
+
+      var stepSize = 1 / n.Value;
+      var selection = new List<IItem>();
+      for (int i = 0; i < solutions.Count; i = (int)Math.Round(i + stepSize)) {
+        selection.Add(solutions.ElementAt(i));
+      }
+
+      return new ItemArray<IItem>(selection);
+    }
+
+    protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) {
+      if (parents.Length != 2) throw new ArgumentException("TravelingSalesmanPathRelinker: The number of parents is not equal to 2.");
+      return Apply(parents[0], parents[1], n);
+    }
+  }
+}
