Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinCrossover.cs	(revision 4185)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinCrossover.cs	(revision 4186)
@@ -51,4 +51,17 @@
         DistanceMatrixParameter, UseDistanceMatrixParameter.ActualValue,
         city, -1, out route, out place);
+    }
+
+    protected Tour FindRoute(PotvinEncoding solution, int city) {
+      Tour found = null;
+
+      foreach (Tour tour in solution.Tours) {
+        if (tour.Cities.Contains(city)) {
+          found = tour;
+          break;
+        }
+      }
+
+      return found;
     }
 
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/RouteBasedCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/RouteBasedCrossover.cs	(revision 4186)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/RouteBasedCrossover.cs	(revision 4186)
@@ -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.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("RouteBasedCrossover", "The RBX crossover for the Potvin VRP representations.  It is implemented as described in Potvin, J.-Y. and Bengio, S. (1996). The Vehicle Routing Problem with Time Windows - Part II: Genetic Search. INFORMS Journal of Computing, 8:165–172.")]
+  [StorableClass]
+  public sealed class RouteBasedCrossover : PotvinCrossover {
+    [StorableConstructor]
+    private RouteBasedCrossover(bool deserializing) : base(deserializing) { }
+
+    public RouteBasedCrossover()
+      : base() { }
+     
+    protected override PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2) {
+      PotvinEncoding child = parent2.Clone() as PotvinEncoding;
+
+      int tourParent1 = random.Next(parent1.Tours.Count);
+      Tour replacing = parent1.Tours[tourParent1].Clone() as Tour;
+
+      int tourParent2 = random.Next(child.Tours.Count);
+      Tour replaced = child.Tours[tourParent2];
+
+      child.Tours.Remove(replaced);
+      child.Tours.Add(replacing);
+
+      foreach (int city in replaced.Cities)
+        if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
+          child.Unrouted.Add(city);
+
+      if (Repair(random, child, replacing))
+        return child;
+      else {
+        if(random.NextDouble() < 0.5)
+          return parent1.Clone() as PotvinEncoding;
+        else
+          return parent2.Clone() as PotvinEncoding;
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/SequenceBasedCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/SequenceBasedCrossover.cs	(revision 4185)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/SequenceBasedCrossover.cs	(revision 4186)
@@ -35,18 +35,5 @@
     public SequenceBasedCrossover()
       : base() { }
-    
-    private Tour FindRoute(PotvinEncoding solution, int city) {
-      Tour found = null;
-
-      foreach (Tour tour in solution.Tours) {
-        if (tour.Cities.Contains(city)) {
-          found = tour;
-          break;
-        }
-      }
-
-      return found;
-    }
-    
+        
     protected override PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2) {
       PotvinEncoding child = parent1.Clone() as PotvinEncoding;
@@ -78,8 +65,9 @@
           child.Unrouted.Add(city);
 
-      if (Repair(random, child, newTour))
+      if (Feasible(newTour) &&
+          Repair(random, child, newTour)) {
         return child;
-      else {
-        if(random.NextDouble() < 0.5)
+      } else {
+        if (random.NextDouble() < 0.5)
           return parent1.Clone() as PotvinEncoding;
         else
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/SequenceBasedCrossover2.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/SequenceBasedCrossover2.cs	(revision 4186)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/SequenceBasedCrossover2.cs	(revision 4186)
@@ -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 HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("SequenceBasedCrossover2", "The SBX2 crossover for the Potvin VRP representations.  It a variant of the operator described in Potvin, J.-Y. and Bengio, S. (1996). The Vehicle Routing Problem with Time Windows - Part II: Genetic Search. INFORMS Journal of Computing, 8:165–172.")]
+  [StorableClass]
+  public sealed class SequenceBasedCrossover2 : PotvinCrossover {
+    [StorableConstructor]
+    private SequenceBasedCrossover2(bool deserializing) : base(deserializing) { }
+
+    public SequenceBasedCrossover2()
+      : base() { }
+        
+    protected override PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2) {
+      PotvinEncoding child = parent1.Clone() as PotvinEncoding;
+      Tour newTour = new Tour();
+
+      int breakPoint1 = random.Next(1, Cities + 1);
+      int breakPoint2 = breakPoint1;
+      Tour tour1 = FindRoute(child, breakPoint1);
+      breakPoint1 = tour1.Cities.IndexOf(breakPoint1);
+
+      for (int i = 0; i < breakPoint1; i++)
+        newTour.Cities.Add(tour1.Cities[i]);
+
+      Tour tour2 = FindRoute(parent2, breakPoint2);
+      breakPoint2 = tour2.Cities.IndexOf(breakPoint2);
+
+      for (int i = breakPoint2; i < tour2.Cities.Count; i++)
+        newTour.Cities.Add(tour2.Cities[i]);
+
+      child.Tours.Remove(tour1);
+      child.Tours.Add(newTour);
+
+      foreach (int city in tour1.Cities)
+        if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
+          child.Unrouted.Add(city);
+
+      foreach (int city in tour2.Cities)
+        if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
+          child.Unrouted.Add(city);
+
+      if (Repair(random, child, newTour)) {
+        return child;
+      } else {
+        if (random.NextDouble() < 0.5)
+          return parent1.Clone() as PotvinEncoding;
+        else
+          return parent2.Clone() as PotvinEncoding;
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/LocalSearchManipulator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/LocalSearchManipulator.cs	(revision 4186)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/LocalSearchManipulator.cs	(revision 4186)
@@ -0,0 +1,113 @@
+﻿#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.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("LocalSearchManipulator", "The LSM operator which manipulates a Potvin VRP representation.  It is implemented as described in Potvin, J.-Y. and Bengio, S. (1996). The Vehicle Routing Problem with Time Windows - Part II: Genetic Search. INFORMS Journal of Computing, 8:165–172.")]
+  [StorableClass]
+  public sealed class LocalSearchManipulator : PotvinManipulator {
+    [StorableConstructor]
+    private LocalSearchManipulator(bool deserializing) : base(deserializing) { }
+
+    public LocalSearchManipulator() : base() { }
+
+    private bool FindBetterInsertionPlace(
+      PotvinEncoding individual, int tour, int city, int length,
+      out int insertionTour, out int insertionPlace) {
+      bool insertionFound = false;
+      insertionTour = -1;
+      insertionPlace = 1;
+
+      List<int> toBeDeleted = individual.Tours[tour].Cities.GetRange(city, length);
+      double distance = GetLength(individual.Tours[tour]);
+      individual.Tours[tour].Cities.RemoveRange(city, length);
+      double removalBenefit = distance - GetLength(individual.Tours[tour]);
+
+      int currentTour = 0;
+      while (currentTour < individual.Tours.Count && !insertionFound) {
+        int currentCity = 0;
+        while (currentCity <= individual.Tours[currentTour].Cities.Count && !insertionFound) {
+          distance = GetLength(individual.Tours[currentTour]);
+          individual.Tours[currentTour].Cities.InsertRange(currentCity, toBeDeleted);
+          if (Feasible(individual.Tours[currentTour])) {
+            double lengthIncrease =
+              GetLength(individual.Tours[currentTour]) - distance;
+            if (removalBenefit > lengthIncrease) {
+              insertionTour = currentTour;
+              insertionPlace = currentCity;
+
+              insertionFound = true;
+            }
+          }
+          individual.Tours[currentTour].Cities.RemoveRange(currentCity, length);
+          
+          currentCity++;
+        }
+        currentTour++;
+      }
+
+      individual.Tours[tour].Cities.InsertRange(city, toBeDeleted);
+
+      return insertionFound;
+    }
+
+    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
+      //only apply to feasible individuals
+      if (Feasible(individual)) {
+        bool insertionFound;
+
+        do {
+          insertionFound = false;
+          int length = 3;
+          while (length > 0 && !insertionFound) {
+            int tour = 0;
+            while (tour < individual.Tours.Count && !insertionFound) {
+              int city = 0;
+              while (city <= individual.Tours[tour].Cities.Count - length && !insertionFound) {
+                int insertionTour, insertionPlace;
+                if (FindBetterInsertionPlace(individual, tour, city, length,
+                 out insertionTour, out insertionPlace)) {
+                  insertionFound = true;
+
+                  List<int> toBeInserted = individual.Tours[tour].Cities.GetRange(city, length);
+
+                  individual.Tours[tour].Cities.RemoveRange(city, length);
+                  individual.Tours[insertionTour].Cities.InsertRange(
+                    insertionPlace,
+                    toBeInserted);
+                }
+                city++;
+              }
+              tour++;
+            }
+            length--;
+          }
+        } while (insertionFound);
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/TwoLevelExchangeManipulator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/TwoLevelExchangeManipulator.cs	(revision 4185)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/TwoLevelExchangeManipulator.cs	(revision 4186)
@@ -28,11 +28,11 @@
 
 namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
-  [Item("TwoLevelExchangeOperator", "The 2M operator which manipulates a Potvin VRP representation.  It is implemented as described in Potvin, J.-Y. and Bengio, S. (1996). The Vehicle Routing Problem with Time Windows - Part II: Genetic Search. INFORMS Journal of Computing, 8:165–172.")]
+  [Item("TwoLevelExchangeManipulator", "The 2M operator which manipulates a Potvin VRP representation.  It is implemented as described in Potvin, J.-Y. and Bengio, S. (1996). The Vehicle Routing Problem with Time Windows - Part II: Genetic Search. INFORMS Journal of Computing, 8:165–172.")]
   [StorableClass]
-  public sealed class TwoLevelExchangeOperator : PotvinManipulator {
+  public sealed class TwoLevelExchangeManipulator : PotvinManipulator {
     [StorableConstructor]
-    private TwoLevelExchangeOperator(bool deserializing) : base(deserializing) { }
+    private TwoLevelExchangeManipulator(bool deserializing) : base(deserializing) { }
 
-    public TwoLevelExchangeOperator(): base() { }
+    public TwoLevelExchangeManipulator() : base() { }
     
     protected override void Manipulate(IRandom random, PotvinEncoding individual) {
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 4185)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 4186)
@@ -110,6 +110,9 @@
     <Compile Include="Encodings\General\Crossovers\MultiVRPCrossover.cs" />
     <Compile Include="Encodings\General\Creators\RandomCreator.cs" />
+    <Compile Include="Encodings\Potvin\Crossovers\SequenceBasedCrossover2.cs" />
+    <Compile Include="Encodings\Potvin\Crossovers\RouteBasedCrossover.cs" />
     <Compile Include="Encodings\Potvin\Crossovers\SequenceBasedCrossover.cs" />
     <Compile Include="Encodings\Potvin\Crossovers\PotvinCrossover.cs" />
+    <Compile Include="Encodings\Potvin\Manipulators\LocalSearchManipulator.cs" />
     <Compile Include="Encodings\Potvin\Manipulators\TwoLevelExchangeManipulator.cs" />
     <Compile Include="Encodings\Potvin\Manipulators\OneLevelExchangeManipulator.cs" />
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VRPOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VRPOperator.cs	(revision 4185)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VRPOperator.cs	(revision 4186)
@@ -137,4 +137,17 @@
     }
 
+    protected bool Feasible(IVRPEncoding solution) {
+      bool feasible = true;
+
+      foreach (Tour tour in solution.Tours) {
+        if (!Feasible(tour)) {
+          feasible = false;
+          break;
+        }
+      }
+
+      return feasible;
+    }
+
     protected double GetLength(Tour tour) {
       return tour.GetLength(
