Index: /branches/HeuristicLab.VRPEnhancements/Build.cmd
===================================================================
--- /branches/HeuristicLab.VRPEnhancements/Build.cmd	(revision 14417)
+++ /branches/HeuristicLab.VRPEnhancements/Build.cmd	(revision 14417)
@@ -0,0 +1,104 @@
+@ECHO OFF
+
+SET CLEANBEFOREBUILD=
+
+SET SELECTED=
+SET CONFIGURATION=
+SET PLATFORM=
+
+IF "%~1"=="" GOTO :prompt_solution
+
+SET SELECTED=%1
+IF NOT EXIST %SELECTED% (
+  ECHO Solution file %SELECTED% could not be found.
+  GOTO :end
+)
+ECHO Building solution %SELECTED% ...
+GOTO :config_selection
+
+:prompt_solution
+SET /A COUNT=0
+FOR /F "tokens=*" %%A IN ('dir /B *.sln') DO (
+  CALL :forloopbody "%%A"
+)
+
+IF "%COUNT%"=="1" (
+  SET SELECTED=%SOLUTIONS.1%
+  ECHO Building %SOLUTIONS.1% as it is the only solution that was found ...
+  GOTO :config_selection
+)
+
+ECHO Found the following solutions:
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO ECHO %%A = %%B
+ECHO.
+SET /P SOLUTIONINDEX=Which solution to build? Type the number: 
+
+SET SELECTED=""
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO (
+  IF "%%A"=="%SOLUTIONINDEX%" SET SELECTED=%%B
+)
+
+IF %SELECTED%=="" GOTO :eof
+
+:config_selection
+IF "%~2"==""  GOTO :prompt_config
+
+SET CONFIGURATION=%~2
+ECHO Building configuration %CONFIGURATION% ...
+GOTO :platform_selection
+
+:prompt_config
+SET /P CONFIGURATION=Which configuration to build [Release]: 
+IF "%CONFIGURATION%"=="" SET CONFIGURATION=Release
+
+:platform_selection
+IF "%~3"=="" GOTO :prompt_platform
+  
+SET PLATFORM=%~3
+ECHO Building platform %PLATFORM% ...
+GOTO :clean
+
+:prompt_platform
+SET /P PLATFORM=Which platform to build [Any CPU]: 
+IF "%PLATFORM%"=="" SET PLATFORM=Any CPU
+
+:clean
+IF "%~4"=="" GOTO :prompt_clean
+
+SET CLEANBEFOREBUILD=%~4
+GOTO :main
+
+:prompt_clean
+SET /P CLEANBEFOREBUILD=Would you like to clean before building [n]: 
+IF "%CLEANBEFOREBUILD%"=="" SET CLEANBEFOREBUILD=n
+
+:main
+REM First find the path to the msbuild.exe by performing a registry query
+FOR /F "tokens=1,3 delims=	 " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0"') DO (
+  IF "%%A"=="MSBuildToolsPath" SET MSBUILDPATH=%%B)
+
+REM Then execute msbuild to clean and build the solution
+REM Disable that msbuild creates a cache file of the solution
+SET MSBuildUseNoSolutionCache=1
+REM Run msbuild to clean and then build
+IF "%CLEANBEFOREBUILD%" NEQ "n" (
+  ECHO Cleaning ...
+  %MSBUILDPATH%msbuild.exe %SELECTED% /target:Clean /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+)
+ECHO Building ...
+%MSBUILDPATH%msbuild.exe %SELECTED% /target:Build /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+
+ECHO.
+ECHO DONE.
+
+:end
+
+PAUSE
+
+GOTO :eof
+
+REM This workaround is necessary so that COUNT gets reevaluated
+:forloopbody
+SET /A COUNT+=1
+SET SOLUTIONS.%COUNT%=%1
+GOTO :eof
Index: /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/ClusterCreator.cs
===================================================================
--- /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/ClusterCreator.cs	(revision 14417)
+++ /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/ClusterCreator.cs	(revision 14417)
@@ -0,0 +1,372 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("ClusterCreator", "Creates a VRP solution by clustering customers first with a KMeans-algorithm and building tours afterwards alternatevly in a random or a greedy fashion.")]
+  [StorableClass]
+  public sealed class ClusterCreator : PotvinCreator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public IValueParameter<IntValue> MinK {
+      get { return (IValueParameter<IntValue>)Parameters["MinK"]; }
+    }
+    public IValueParameter<IntValue> MaxK {
+      get { return (IValueParameter<IntValue>)Parameters["MaxK"]; }
+    }
+
+    public IValueParameter<DoubleValue> ClusterChangeThreshold {
+      get { return (IValueParameter<DoubleValue>)Parameters["ClusterChangeThreshold"]; }
+    }
+
+    public IValueParameter<DoubleArray> TourCreationProbabilities {
+      get { return (IValueParameter<DoubleArray>)Parameters["TourCreationProbabilities"]; }
+    }
+
+    [StorableConstructor]
+    public ClusterCreator(bool deserializing) : base(deserializing) { }
+
+    public ClusterCreator() : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator."));
+      Parameters.Add(new ValueParameter<IntValue>("MinK", "Minimum number of clusters which should be created", new IntValue(1)));
+      Parameters.Add(new OptionalValueParameter<IntValue>("MaxK", "Maximum number of clusters which should be created"));
+      Parameters.Add(new ValueParameter<DoubleValue>("ClusterChangeThreshold", "A certain ratio below which a cluster should be considered as computed satisfactory", new DoubleValue(0.0)));     
+      Parameters.Add(new ValueParameter<DoubleArray>("TourCreationProbabilities", "This weightage array denotes the probability which tour creation method is employed: [shuffled; greedy]", new DoubleArray(new double[] {1, 1})));
+    }
+
+    private ClusterCreator(ClusterCreator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClusterCreator(this, cloner);
+    }
+
+    public static PotvinEncoding CreateSolution(IVRPProblemInstance instance, IRandom random, int minK, int maxK, double clusterChangeThreshold, int creationOption) {
+      PotvinEncoding result = new PotvinEncoding(instance);
+
+      IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
+
+      // add all customers
+      List<int> customers = new List<int>();
+      for (int i = 1; i <= instance.Cities.Value; i++) {
+        if(pdp == null || pdp.GetDemand(i) >= 0)
+          customers.Add(i);
+      }
+
+      // cluster by spatial distribution
+
+      // (1) wrap stops in ClusterObject
+      List<ClusterObject> clusterObjects = new List<ClusterObject>();
+      foreach (int customer in customers) {
+        clusterObjects.Add(new ClusterObject(customer, instance.GetCoordinates(customer)));
+      }
+
+      // (2) cluster
+      int k = random.Next(minK, maxK);
+      List<Cluster> clusters = KMeans(instance, random, clusterObjects, k, clusterChangeThreshold);
+
+      // (3) build tours
+      // (a) shuffle
+      // (b) greedy
+      foreach (Cluster c in clusters) {
+        Tour newTour = new Tour();
+        result.Tours.Add(newTour);
+
+        if (creationOption == 0) {
+          // (a) shuffle
+          c.Objects.Shuffle(random);
+          foreach (ClusterObject o in c.Objects) {
+            newTour.Stops.Add(o.Id);
+          }
+        } else {
+          // (b) greedy
+          foreach (ClusterObject o in c.Objects) {
+            newTour.Stops.Add(o.Id);
+          }
+          GreedyTourCreation(instance, result, newTour, false);
+        }
+      }
+      return result;
+    }
+
+    public override IOperation InstrumentedApply() {
+      IRandom random = RandomParameter.ActualValue;
+
+      int minK = (MinK.Value.Value > 0) ? MinK.Value.Value : 1;
+      int maxK = (MaxK.Value != null) ? MaxK.Value.Value : ProblemInstance.Vehicles.Value;
+      double clusterChangeThreshold = (ClusterChangeThreshold.Value.Value >= 0.0 &&
+                                       ClusterChangeThreshold.Value.Value <= 1.0)
+        ? ClusterChangeThreshold.Value.Value
+        : 0.0;
+
+      // normalize probabilities
+      double max = TourCreationProbabilities.Value.Max();
+      double[] probabilites = new double[2];
+      for (int i = 0; i < TourCreationProbabilities.Value.Length; i++) {
+        probabilites[i] = TourCreationProbabilities.Value[i] / max;
+      }
+
+      List<int> creationOptions = new List<int>() {0, 1};
+      int creationOption = creationOptions.SampleProportional(random, 1, probabilites, false, false).First();
+
+      VRPToursParameter.ActualValue = CreateSolution(ProblemInstance, random, minK, maxK, clusterChangeThreshold, creationOption);
+      return base.InstrumentedApply();
+    }
+
+    private static List<Cluster> KMeans(IVRPProblemInstance instance, IRandom random, List<ClusterObject> objects, int k, double changeTreshold) {
+
+      List<Cluster> clusters = new List<Cluster>();
+      HashSet<int> initMeans = new HashSet<int>();
+      int nextMean = -1;
+
+      // (1) initialize each cluster with a random first object (i.e. mean)
+      for (int i = 0; i < k && i < objects.Count; i++) {
+        Cluster cluster = new Cluster(instance, i);
+
+        do {
+          nextMean = random.Next(0, objects.Count);
+        } while (initMeans.Contains(nextMean));
+        initMeans.Add(nextMean);
+        cluster.SetMean(objects[nextMean]);
+        clusters.Add(cluster);
+      }
+
+      // (2) repeat clustering until change rate is below threshold
+      int changes = 0;
+      double changeRate = 1.0;
+
+      do {
+        changes = KMeansRun(clusters, objects);
+        changeRate = changes / objects.Count;
+
+      } while (changeRate > changeTreshold);
+
+      // remove empty clusters
+      clusters.RemoveAll(c => c.Objects.Count.Equals(0));
+
+      return clusters;
+    }
+
+    private static int KMeansRun(List<Cluster> clusters, List<ClusterObject> objects) {
+      int changes = 0;
+
+      foreach (Cluster c in clusters) {
+        c.Objects.Clear();
+      }
+
+      foreach (ClusterObject o in objects) {
+        int bestClusterIdx = -1;
+        double minImpact = double.MaxValue;
+        for(int i = 0; i < clusters.Count; i++) {
+          double impact = clusters[i].CalculateVarianceIncrease(o);
+          if (impact < minImpact) {
+            minImpact = impact;
+            bestClusterIdx = i;
+          }
+        }
+        clusters[bestClusterIdx].AddObject(o);
+      }
+
+      foreach (Cluster c in clusters) {
+        c.CalculateMean();
+      }
+
+      return changes;
+    }
+
+    class Cluster {
+      public int Id;
+      public List<ClusterObject> Objects { get; private set; }
+      public double Variance { get; private set; }
+      public ClusterObject Mean { get; set; }
+
+      private readonly IVRPProblemInstance instance;
+
+      public Cluster(IVRPProblemInstance instance, int id) {
+        this.instance = instance;
+        Id = id;
+        Objects = new List<ClusterObject>();
+      }
+
+      public bool IsEqual(Cluster cluster) {
+        bool equal = (cluster != null) && (cluster.Objects.Count == Objects.Count);
+        int index = 0;
+
+        while (equal && index < Objects.Count) {
+          equal = cluster.Objects.Contains(Objects[index]);
+          index++;
+        }
+        return equal;
+      }
+
+      public bool AddObject(ClusterObject o) {
+        Objects.Add(o);
+
+        bool clusterChanged = o.ClusterId != Id;
+        o.ClusterId = Id;
+        return clusterChanged;
+      }
+
+      public void SetMean(ClusterObject o) {
+        Mean = o;
+        Mean.ClusterId = Id;
+      }
+
+      public ClusterObject CalculateMean() {
+        int dimensions = instance.Coordinates.Columns;
+        ClusterObject mean = new ClusterObject(-1, Id, dimensions);
+        foreach (ClusterObject o in Objects) {
+          double[] coordinates = instance.GetCoordinates(o.Id);
+          for (int i = 0; i < coordinates.Length; i++) {
+            mean.Coordinates[i] += (coordinates[i] / Objects.Count);
+          }
+        }
+        Mean = mean;
+        return Mean;
+      }
+
+      public double CalculateVariance() {
+        Variance = 0.0;
+
+        if (Mean == null)
+          CalculateMean();
+
+        foreach (ClusterObject o in Objects) {
+          double[] coordinates = instance.GetCoordinates(o.Id);
+          Variance += Math.Pow(Mean.GetDistance(o.Coordinates), 2);
+        }
+        return Variance /= Objects.Count;
+      }
+
+      public double CalculateVarianceIncrease(ClusterObject o) {
+        if(Mean == null)
+          CalculateMean();
+
+        return Math.Pow(Mean.GetDistance(o.Coordinates), 2) / ((Objects.Count > 0) ? Objects.Count : 1);
+      }
+    }
+
+    class ClusterObject {
+      
+      public int Id { get; private set; }
+
+      public int ClusterId { get; set; }
+
+      public double[] Coordinates { get; set; }
+
+      public ClusterObject() { }
+
+      public ClusterObject(int id, int clusterId = -1) {
+        Id = id;
+        ClusterId = clusterId;
+      }
+
+      public ClusterObject(int id, double[] coordinates) {
+        Id = id;
+        Coordinates = coordinates;
+      }
+
+      public ClusterObject(int id, int clusterId, int dimensions) {
+        Id = id;
+        ClusterId = clusterId;
+        Coordinates = new double[dimensions];
+      }
+
+      public double GetDistance(double[] otherCoordinates) {
+        double distance = 0.0;
+
+        for (int i = 0; i < otherCoordinates.Length; i++) {
+          distance += Math.Pow(Coordinates[i] - otherCoordinates[i], 2);
+        }
+        return Math.Sqrt(distance);
+      }
+    }
+
+    private static double CalculateAngleToDepot(IVRPProblemInstance instance, int city) {
+      double dx = instance.GetCoordinates(0)[0];
+      double dy = instance.GetCoordinates(0)[1];
+
+      double cx = instance.GetCoordinates(city)[0];
+      double cy = instance.GetCoordinates(city)[1];
+
+      double alpha = Math.Atan((cx - dx) / (dy - cy)) * (180.0 / Math.PI);
+      if (cx > dx && cy > dy)
+        alpha = (90.0 + alpha) + 90.0;
+      else if (cx < dx && cy > dy)
+        alpha = alpha + 180.0;
+      else if (cx < dx && cy < dy)
+        alpha = (90.0 + alpha) + 270.0;
+
+      return alpha;
+    }
+
+    private static void GreedyTourCreation(IVRPProblemInstance instance, PotvinEncoding individual, Tour tour, bool includeCosts) {
+      Tour unrouted = tour.Clone() as Tour;
+      tour.Stops.Clear();
+      VRPEvaluation evaluation = instance.EvaluateTour(tour, individual);
+      double currentQuality = (includeCosts) ? evaluation.Quality : evaluation.Distance;
+
+      while (unrouted.Stops.Count > 0) {
+        int insertionPosition = tour.Stops.Count;
+        int nextCityIdxToAdd = 0;
+
+        tour.Stops.Add(unrouted.Stops[nextCityIdxToAdd]);
+        evaluation = instance.EvaluateTour(tour, individual);
+        double minQualityIncrease = ((includeCosts) ? evaluation.Quality : evaluation.Distance) - currentQuality;
+        tour.Stops.RemoveAt(insertionPosition);
+
+        for (int j = 1; j < unrouted.Stops.Count; j++) {
+          tour.Stops.Insert(insertionPosition, unrouted.Stops[j]);
+          evaluation = instance.EvaluateTour(tour, individual);
+          double qualityIncrease = ((includeCosts) ? evaluation.Quality : evaluation.Distance) - currentQuality;
+          tour.Stops.RemoveAt(insertionPosition);
+
+          if (qualityIncrease < minQualityIncrease) {
+            nextCityIdxToAdd = j;
+            minQualityIncrease = qualityIncrease;
+          }
+        }
+
+        currentQuality += minQualityIncrease;
+        tour.Stops.Insert(insertionPosition, unrouted.Stops[nextCityIdxToAdd]);
+        unrouted.Stops.RemoveAt(nextCityIdxToAdd);
+      }
+    }
+
+  }
+}
Index: /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Crossovers/PotvinEdgePreservingSequenceBasedCrossover.cs
===================================================================
--- /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Crossovers/PotvinEdgePreservingSequenceBasedCrossover.cs	(revision 14417)
+++ /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Crossovers/PotvinEdgePreservingSequenceBasedCrossover.cs	(revision 14417)
@@ -0,0 +1,111 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("PotvinEdgePreservingSequenceBasedCrossover", "An enhanced variant of the SBX crossover 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. In this SBX variant the second tour segment continues after the last stop of the first segment")]
+  public sealed class PotvinEdgePreservingSequenceBasedCrossover : PotvinCrossover {
+    private PotvinEdgePreservingSequenceBasedCrossover(bool deserializing) : base(deserializing) { }
+
+    public PotvinEdgePreservingSequenceBasedCrossover() : base() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PotvinEdgePreservingSequenceBasedCrossover(this, cloner);
+    }
+
+    private PotvinEdgePreservingSequenceBasedCrossover(PotvinEdgePreservingSequenceBasedCrossover original,
+      Cloner cloner) : base(original, cloner) {
+    }
+
+    public static PotvinEncoding Apply(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2,
+      IVRPProblemInstance problemInstance, bool allowInfeasible) {
+      PotvinEncoding child = parent1.Clone() as PotvinEncoding;
+      Tour newTour = new Tour();
+
+      int cities = problemInstance.Cities.Value;
+
+      if (cities > 0) {
+        // find random break point first tour
+        int breakPoint1 = random.Next(1, cities + 1);
+        Tour tour1 = FindRoute(child, breakPoint1);
+        breakPoint1 = tour1.Stops.IndexOf(breakPoint1);
+
+        // add all stops of the tour from parent1 before breakPoint1 
+        // to the resulting child as first tour segment
+        for (int i = 0; i < breakPoint1; i++)
+          newTour.Stops.Add(tour1.Stops[i]);
+
+        if (newTour.Stops.Count < 1) {
+          Console.Write("x");
+        } else {
+          Console.Write(newTour.Stops.Count);
+        }
+
+        int lastStop = (newTour.Stops.Count > 0) ? newTour.Stops[newTour.Stops.Count - 1] : random.Next(1, cities + 1);
+
+        // find the stop in advance to the breakPoint1
+        // within the tour set of parent2
+        // difference to standard SBX: breakPoint2 is not randomly set
+        Tour tour2 = FindRoute(parent2, lastStop);
+        int breakPoint2 = tour2.Stops.IndexOf(lastStop);
+        breakPoint2++; // add everything after the last added stop
+
+        for (int i = breakPoint2; i < tour2.Stops.Count; i++) {
+          newTour.Stops.Add(tour2.Stops[i]);
+        }
+
+        int tour1Index = child.Tours.IndexOf(tour1);
+        child.Tours.Remove(tour1);
+        child.Tours.Insert(tour1Index, newTour);
+
+        foreach (int city in tour1.Stops) {
+          if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
+            child.Unrouted.Add(city);
+        }
+
+        foreach (int city in tour2.Stops) {
+          if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
+            child.Unrouted.Add(city);
+        }
+
+        if (Repair(random, child, newTour, problemInstance, allowInfeasible) || allowInfeasible) {
+          return child;
+        } else {
+          if (random.NextDouble() < 0.5)
+            return parent1.Clone() as PotvinEncoding;
+          else
+            return parent2.Clone() as PotvinEncoding;
+        }
+      } else {
+        return child;
+      }
+    }
+
+    protected override PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2) {
+      return Apply(random, parent1, parent2, ProblemInstance, AllowInfeasibleSolutions.Value.Value);
+    }
+  }
+}
Index: /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinGreedyTourCreationManipulator.cs
===================================================================
--- /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinGreedyTourCreationManipulator.cs	(revision 14417)
+++ /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinGreedyTourCreationManipulator.cs	(revision 14417)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq.Expressions;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("PotvinGreedyTourCreationManipulator", "This Manipulator reorders the stops within all tours of a solution candidate by following the greedy heuristic: gradually adding those stops to a tour with the least effect on the overall costs.")]
+  [StorableClass]
+  public sealed class PotvinGreedyTourCreationManipulator : PotvinManipulator {
+    public IValueParameter<BoolValue> IncludeCosts {
+      get { return (IValueParameter<BoolValue>) Parameters["IncludeCosts"]; }
+    }
+
+    [StorableConstructor]
+    private PotvinGreedyTourCreationManipulator(bool deserializing) : base(deserializing) { }
+
+    public PotvinGreedyTourCreationManipulator() : base() {
+      Parameters.Add(new ValueParameter<BoolValue>("IncludeCosts", "Indicates if the actual costs should be taken into account when evaluating a tour. Otherwise only the distances between stops are counted.", new BoolValue(true)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PotvinGreedyTourCreationManipulator(this, cloner);
+    }
+
+    private PotvinGreedyTourCreationManipulator(PotvinGreedyTourCreationManipulator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public static void ApplyManipulation(IRandom random, PotvinEncoding individual, IVRPProblemInstance instance,
+      bool allowInfeasible, bool includeCosts) {
+
+      for (int i = 0; i < individual.Tours.Count; i++) {
+        Tour tour = individual.Tours[i];
+        Tour unrouted = individual.Tours[i].Clone() as Tour;
+        tour.Stops.Clear();
+        VRPEvaluation evaluation = instance.EvaluateTour(tour, individual);
+        double currentQuality = (includeCosts) ? evaluation.Quality : evaluation.Distance;
+
+        while (unrouted.Stops.Count > 0) {
+          int insertionPosition = tour.Stops.Count;
+          int nextCityIdxToAdd = 0;
+
+          tour.Stops.Add(unrouted.Stops[nextCityIdxToAdd]);
+          evaluation = instance.EvaluateTour(tour, individual);
+          double minQualityIncrease = ((includeCosts) ? evaluation.Quality : evaluation.Distance) - currentQuality;
+          tour.Stops.RemoveAt(insertionPosition);
+
+          for (int j = 1; j < unrouted.Stops.Count; j++) {
+            tour.Stops.Insert(insertionPosition, unrouted.Stops[j]);
+            evaluation = instance.EvaluateTour(tour, individual);
+            double qualityIncrease = ((includeCosts) ? evaluation.Quality : evaluation.Distance) - currentQuality;
+            tour.Stops.RemoveAt(insertionPosition);
+
+            if (qualityIncrease < minQualityIncrease) {
+              nextCityIdxToAdd = j;
+              minQualityIncrease = qualityIncrease;
+            }
+          }
+
+          currentQuality += minQualityIncrease;
+          tour.Stops.Insert(insertionPosition, unrouted.Stops[nextCityIdxToAdd]);
+          unrouted.Stops.RemoveAt(nextCityIdxToAdd);
+        }
+      }
+    }
+
+    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
+      bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
+      bool includeCosts = IncludeCosts.Value.Value;
+      ApplyManipulation(random, individual, ProblemInstance, allowInfeasible, includeCosts);
+    }
+  }
+}
Index: /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj
===================================================================
--- /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj	(revision 14416)
+++ /branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj	(revision 14417)
@@ -40,5 +40,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -52,5 +52,5 @@
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -106,4 +106,64 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.PermutationEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.PermutationEncoding-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core">
@@ -135,4 +195,7 @@
     <Compile Include="Analyzer\ConstraintRelaxation\TimeWindowed\TimeWindowRelaxationVRPAnalyzer.cs" />
     <Compile Include="Analyzer\VRPSolution.cs" />
+    <Compile Include="Encodings\Potvin\Creators\ClusterCreator.cs" />
+    <Compile Include="Encodings\Potvin\Crossovers\PotvinEdgePreservingSequenceBasedCrossover.cs" />
+    <Compile Include="Encodings\Potvin\Manipulators\PotvinGreedyTourCreationManipulator.cs" />
     <Compile Include="Encodings\Potvin\Moves\TwoOptStar\IPotvinTwoOptStarMoveOperator.cs" />
     <Compile Include="Encodings\Potvin\Moves\TwoOptStar\PotvinTwoOptStarExhaustiveMoveGenerator.cs" />
@@ -400,80 +463,4 @@
     </BootstrapperPackage>
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
-      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
-      <Name>HeuristicLab.Analysis-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
-      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
-      <Name>HeuristicLab.Collections-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
-      <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
-      <Name>HeuristicLab.Common.Resources-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
-      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
-      <Name>HeuristicLab.Common-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
-      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
-      <Name>HeuristicLab.Core-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
-      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
-      <Name>HeuristicLab.Data-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
-      <Project>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</Project>
-      <Name>HeuristicLab.Encodings.PermutationEncoding-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
-      <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
-      <Name>HeuristicLab.Operators-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
-      <Project>{25087811-F74C-4128-BC86-8324271DA13E}</Project>
-      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
-      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
-      <Name>HeuristicLab.Optimization-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
-      <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
-      <Name>HeuristicLab.Parameters-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
-      <Project>{102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}</Project>
-      <Name>HeuristicLab.Persistence-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
-      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
-      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj">
-      <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project>
-      <Name>HeuristicLab.Problems.Instances-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
-      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
-      <Name>HeuristicLab.Random-3.3</Name>
-    </ProjectReference>
-  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/HeuristicLab.VRPEnhancements/HeuristicLab.VRPEnhancements.sln
===================================================================
--- /branches/HeuristicLab.VRPEnhancements/HeuristicLab.VRPEnhancements.sln	(revision 14417)
+++ /branches/HeuristicLab.VRPEnhancements/HeuristicLab.VRPEnhancements.sln	(revision 14417)
@@ -0,0 +1,34 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.VehicleRouting-3.4", "HeuristicLab.Problems.VehicleRouting\3.4\HeuristicLab.Problems.VehicleRouting-3.4.csproj", "{B94FFB82-43D4-40AB-9980-B03470ADF221}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Debug|x64.ActiveCfg = Debug|x64
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Debug|x64.Build.0 = Debug|x64
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Debug|x86.ActiveCfg = Debug|x86
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Debug|x86.Build.0 = Debug|x86
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Release|x64.ActiveCfg = Release|x64
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Release|x64.Build.0 = Release|x64
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Release|x86.ActiveCfg = Release|x86
+		{B94FFB82-43D4-40AB-9980-B03470ADF221}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /branches/HeuristicLab.VRPEnhancements/PreBuildEvent.cmd
===================================================================
--- /branches/HeuristicLab.VRPEnhancements/PreBuildEvent.cmd	(revision 14417)
+++ /branches/HeuristicLab.VRPEnhancements/PreBuildEvent.cmd	(revision 14417)
@@ -0,0 +1,2 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
