Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/General/PermutationEncoding.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/General/PermutationEncoding.cs	(revision 4288)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/General/PermutationEncoding.cs	(revision 4293)
@@ -27,4 +27,5 @@
 using System.Collections.Generic;
 using HeuristicLab.Problems.VehicleRouting.Encodings.General;
+using System;
 
 namespace HeuristicLab.Problems.VehicleRouting.Encodings.General {
@@ -47,4 +48,8 @@
       : base() {
     }
+
+    public int IndexOf(int city) {
+      return Array.IndexOf(this.array, city);
+    }
   }
 }
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuCrossover.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuCrossover.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuCrossover.cs	(revision 4293)
@@ -0,0 +1,75 @@
+﻿#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 HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Zhu {
+  [Item("ZhuCrossover", "An operator which crosses two VRP representations.")]
+  [StorableClass]
+  public abstract class ZhuCrossover : VRPCrossover, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    
+    [StorableConstructor]
+    protected ZhuCrossover(bool deserializing) : base(deserializing) { }
+
+    public ZhuCrossover()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+    }
+
+    protected abstract ZhuEncoding Crossover(IRandom random, ZhuEncoding parent1, ZhuEncoding parent2);
+
+    public override IOperation Apply() {
+      ItemArray<IVRPEncoding> parents = new ItemArray<IVRPEncoding>(ParentsParameter.ActualValue.Length);
+      for (int i = 0; i < ParentsParameter.ActualValue.Length; i++) {
+        IVRPEncoding solution = ParentsParameter.ActualValue[i];
+
+        if (!(solution is ZhuEncoding)) {
+          parents[i] = ZhuEncoding.ConvertFrom(solution,
+            Cities, 
+            DueTimeParameter.ActualValue,
+            ServiceTimeParameter.ActualValue,
+            ReadyTimeParameter.ActualValue,
+            DemandParameter.ActualValue,
+            CapacityParameter.ActualValue,
+            CoordinatesParameter.ActualValue,
+            DistanceMatrixParameter,
+            UseDistanceMatrixParameter.ActualValue);
+        } else {
+          parents[i] = solution;
+        }
+      }
+      ParentsParameter.ActualValue = parents;
+
+      ChildParameter.ActualValue =
+        Crossover(RandomParameter.ActualValue, parents[0] as ZhuEncoding, parents[1] as ZhuEncoding);
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuHeuristicCrossover1.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuHeuristicCrossover1.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuHeuristicCrossover1.cs	(revision 4293)
@@ -0,0 +1,88 @@
+﻿#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.Zhu {
+  [Item("ZhuHeuristicCrossover1", "The Zhu Heuristic Crossover (Version 1). It is implemented as described in Zhu, K.Q. (2000). A New Genetic Algorithm For VRPTW. Proceedings of the International Conference on Artificial Intelligence.")]
+  [StorableClass]
+  public sealed class ZhuHeuristicCrossover1 : ZhuCrossover {    
+    [StorableConstructor]
+    private ZhuHeuristicCrossover1(bool deserializing) : base(deserializing) { }
+
+    public ZhuHeuristicCrossover1()
+      : base() {
+    }
+
+    private void Swap(ZhuEncoding individual, int city1, int city2) {
+      int index1 = individual.IndexOf(city1);
+      int index2 = individual.IndexOf(city2);
+
+      int temp = individual[index1];
+      individual[index1] = individual[index2];
+      individual[index2] = temp;
+    }
+
+    protected override ZhuEncoding Crossover(IRandom random, ZhuEncoding parent1, ZhuEncoding parent2) {
+      parent1 = parent1.Clone() as ZhuEncoding;
+      parent2 = parent2.Clone() as ZhuEncoding;
+
+      ZhuEncoding child = parent2.Clone() as ZhuEncoding;
+
+      int breakPoint = random.Next(child.Length);
+      int i = breakPoint;
+      int predecessor = breakPoint - 1;
+      if (predecessor < 0)
+        predecessor = predecessor + child.Length;
+
+      while (i != predecessor) {
+        if (i == breakPoint) {
+          child[i] = parent1[i];
+          Swap(parent2, parent2[i], parent1[i]);
+        }
+
+        if (VRPUtilities.GetDistance(
+          child[i] + 1, parent1[(i + 1) % child.Length] + 1,
+          CoordinatesParameter.ActualValue, DistanceMatrixParameter,
+          UseDistanceMatrixParameter.ActualValue)
+          <
+          VRPUtilities.GetDistance(
+          child[i] + 1, parent2[(i + 1) % child.Length] + 1,
+          CoordinatesParameter.ActualValue, DistanceMatrixParameter,
+          UseDistanceMatrixParameter.ActualValue)) {
+          child[(i + 1) % child.Length] = parent1[(i + 1) % child.Length];
+          Swap(parent2, parent2[(i + 1) % child.Length], parent1[(i + 1) % child.Length]);
+        } else {
+          child[(i + 1) % child.Length] = parent2[(i + 1) % child.Length];
+          Swap(parent1, parent1[(i + 1) % child.Length], parent2[(i + 1) % child.Length]);
+        }
+
+        i = (i + 1) % child.Length;
+      }
+
+      return child;
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuHeuristicCrossover2.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuHeuristicCrossover2.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuHeuristicCrossover2.cs	(revision 4293)
@@ -0,0 +1,96 @@
+﻿#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.Zhu {
+  [Item("ZhuHeuristicCrossover2", "The Zhu Heuristic Crossover (Version 2). It is implemented as described in Zhu, K.Q. (2000). A New Genetic Algorithm For VRPTW. Proceedings of the International Conference on Artificial Intelligence.")]
+  [StorableClass]
+  public sealed class ZhuHeuristicCrossover2 : ZhuCrossover {    
+    [StorableConstructor]
+    private ZhuHeuristicCrossover2(bool deserializing) : base(deserializing) { }
+
+    public ZhuHeuristicCrossover2()
+      : base() {
+    }
+
+    protected override ZhuEncoding Crossover(IRandom random, ZhuEncoding parent1, ZhuEncoding parent2) {
+      List<int> p1 = new List<int>(parent1);
+      List<int> p2 = new List<int>(parent2);
+
+      ZhuEncoding child = parent2.Clone() as ZhuEncoding;
+
+      int breakPoint = random.Next(child.Length);
+      int i = breakPoint;
+      int predecessor = breakPoint - 1;
+      if (predecessor < 0)
+        predecessor = predecessor + child.Length;
+      
+      int parent1Index = i;
+      int parent2Index = i;
+
+      while (i != predecessor) {
+        if (i == breakPoint) {
+          child[i] = p1[parent1Index];
+          
+          p1.Remove(child[i]);
+          if (parent1Index >= p1.Count)
+            parent1Index = 0;
+
+          p2.Remove(child[i]);
+          if (parent2Index >= p2.Count)
+            parent2Index = 0;
+        }
+
+        if (VRPUtilities.GetDistance(
+         child[i] + 1, p1[parent1Index] + 1,
+         CoordinatesParameter.ActualValue, DistanceMatrixParameter,
+         UseDistanceMatrixParameter.ActualValue)
+         <
+         VRPUtilities.GetDistance(
+         child[i] + 1, p2[parent2Index] + 1,
+         CoordinatesParameter.ActualValue, DistanceMatrixParameter,
+         UseDistanceMatrixParameter.ActualValue)) {
+          child[(i + 1) % child.Length] = p1[parent1Index];
+        } else {
+          child[(i + 1) % child.Length] = p2[parent2Index];
+        }
+
+        p1.Remove(child[(i + 1) % child.Length]);
+        if (parent1Index >= p1.Count)
+          parent1Index = 0;
+
+        p2.Remove(child[(i + 1) % child.Length]);
+        if (parent2Index >= p2.Count)
+          parent2Index = 0;
+
+        i = (i + 1) % child.Length;
+      }
+
+      return child;
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuMergeCrossover1.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuMergeCrossover1.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuMergeCrossover1.cs	(revision 4293)
@@ -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 HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Zhu {
+  [Item("ZhuMergeCrossover1", "The Zhu Merge Crossover (Version 1). It is implemented as described in Zhu, K.Q. (2000). A New Genetic Algorithm For VRPTW. Proceedings of the International Conference on Artificial Intelligence.")]
+  [StorableClass]
+  public sealed class ZhuMergeCrossover1 : ZhuCrossover {    
+    [StorableConstructor]
+    private ZhuMergeCrossover1(bool deserializing) : base(deserializing) { }
+
+    public ZhuMergeCrossover1()
+      : base() {
+    }
+
+    private void Swap(ZhuEncoding individual, int city1, int city2) {
+      int index1 = individual.IndexOf(city1);
+      int index2 = individual.IndexOf(city2);
+
+      int temp = individual[index1];
+      individual[index1] = individual[index2];
+      individual[index2] = temp;
+    }
+
+    protected override ZhuEncoding Crossover(IRandom random, ZhuEncoding parent1, ZhuEncoding parent2) {
+      parent1 = parent1.Clone() as ZhuEncoding;
+      parent2 = parent2.Clone() as ZhuEncoding;
+
+      ZhuEncoding child = parent2.Clone() as ZhuEncoding;
+
+      int breakPoint = random.Next(child.Length);
+      int i = breakPoint;
+
+      do {
+        if (i == breakPoint) {
+          child[i] = parent1[i];
+          Swap(parent2, parent2[i], parent1[i]);
+        } else {
+          if (DueTimeParameter.ActualValue[parent1[i] + 1] <
+            DueTimeParameter.ActualValue[parent2[i] + 1]) {
+            child[i] = parent1[i];
+            Swap(parent2, parent2[i], parent1[i]);
+          } else {
+            child[i] = parent2[i];
+            Swap(parent1, parent1[i], parent2[i]);
+          }
+        }
+
+        i = (i + 1) % child.Length;
+      } while (i != breakPoint);
+
+      return child;
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuMergeCrossover2.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuMergeCrossover2.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuMergeCrossover2.cs	(revision 4293)
@@ -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 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.Zhu {
+  [Item("ZhuMergeCrossover2", "The Zhu Merge Crossover (Version 2).  It is implemented as described in Zhu, K.Q. (2000). A New Genetic Algorithm For VRPTW. Proceedings of the International Conference on Artificial Intelligence.")]
+  [StorableClass]
+  public sealed class ZhuMergeCrossover2 : ZhuCrossover {    
+    [StorableConstructor]
+    private ZhuMergeCrossover2(bool deserializing) : base(deserializing) { }
+
+    public ZhuMergeCrossover2()
+      : base() {
+    }
+
+    protected override ZhuEncoding Crossover(IRandom random, ZhuEncoding parent1, ZhuEncoding parent2) {
+      List<int> p1 = new List<int>(parent1);
+      List<int> p2 = new List<int>(parent2);
+
+      ZhuEncoding child = parent2.Clone() as ZhuEncoding;
+
+      int breakPoint = random.Next(child.Length);
+      int i = breakPoint;
+
+      int parent1Index = i;
+      int parent2Index = i;
+
+      do {
+        if (i == breakPoint) {
+          child[i] = p1[parent1Index];
+        } else {
+          if (DueTimeParameter.ActualValue[p1[parent1Index] + 1] <
+            DueTimeParameter.ActualValue[p2[parent2Index] + 1]) {
+            child[i] = p1[parent1Index];
+          } else {
+            child[i] = p2[parent2Index];
+          }
+        }
+
+        p1.Remove(child[i]);
+        if (parent1Index >= p1.Count)
+          parent1Index = 0;
+
+        p2.Remove(child[i]);
+        if (parent2Index >= p2.Count)
+          parent2Index = 0;
+
+        i = (i + 1) % child.Length;
+      } while (i != breakPoint);
+
+      return child;
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuPermutationCrossover.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuPermutationCrossover.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Crossovers/ZhuPermutationCrossover.cs	(revision 4293)
@@ -0,0 +1,70 @@
+﻿#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.Zhu {
+  [Item("ZhuPermutationCrossover", "An operator which crosses two VRP representations using a standard permutation operator.")]
+  [StorableClass]
+  public sealed class PrinsPermutationCrossover : ZhuCrossover {    
+    public IValueLookupParameter<IPermutationCrossover> InnerCrossoverParameter {
+      get { return (IValueLookupParameter<IPermutationCrossover>)Parameters["InnerCrossover"]; }
+    }
+
+    [StorableConstructor]
+    private PrinsPermutationCrossover(bool deserializing) : base(deserializing) { }
+
+    public PrinsPermutationCrossover()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IPermutationCrossover>("InnerCrossover", "The permutation crossover.", new PartiallyMatchedCrossover()));
+    }
+
+    protected override ZhuEncoding Crossover(IRandom random, ZhuEncoding parent1, ZhuEncoding parent2) {
+      //note - the inner crossover is called here and the result is converted to a prins representation
+      //some refactoring should be done here in the future - the crossover operation should be called directly
+
+      InnerCrossoverParameter.ActualValue.ParentsParameter.ActualName = ParentsParameter.ActualName;
+      IAtomicOperation op = this.ExecutionContext.CreateOperation(
+        InnerCrossoverParameter.ActualValue, this.ExecutionContext.Scope);
+      op.Operator.Execute((IExecutionContext)op);
+
+      string childName = InnerCrossoverParameter.ActualValue.ChildParameter.ActualName;
+      if (ExecutionContext.Scope.Variables.ContainsKey(childName)) {
+        Permutation permutation = ExecutionContext.Scope.Variables[childName].Value as Permutation;
+        ExecutionContext.Scope.Variables.Remove(childName);
+
+        return new ZhuEncoding(permutation, Cities,
+          DueTimeParameter.ActualValue,
+            ServiceTimeParameter.ActualValue,
+            ReadyTimeParameter.ActualValue,
+            DemandParameter.ActualValue,
+            CapacityParameter.ActualValue,
+            CoordinatesParameter.ActualValue,
+            UseDistanceMatrixParameter.ActualValue);
+      } else
+        return null;
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Manipulators/ZhuManipulator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Manipulators/ZhuManipulator.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Manipulators/ZhuManipulator.cs	(revision 4293)
@@ -0,0 +1,67 @@
+﻿#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 HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Zhu {
+  [Item("ZhuManipulator", "An operator which manipulates a VRP representation.")]
+  [StorableClass]
+  public abstract class ZhuManipulator : VRPManipulator, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected ZhuManipulator(bool deserializing) : base(deserializing) { }
+
+    public ZhuManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+    }
+
+    protected abstract void Manipulate(IRandom random, ZhuEncoding individual);
+
+    public override IOperation Apply() {
+      IVRPEncoding solution = VRPToursParameter.ActualValue;
+      if (!(solution is ZhuEncoding)) {
+        VRPToursParameter.ActualValue = ZhuEncoding.ConvertFrom(solution,
+            Cities, 
+            DueTimeParameter.ActualValue,
+            ServiceTimeParameter.ActualValue,
+            ReadyTimeParameter.ActualValue,
+            DemandParameter.ActualValue,
+            CapacityParameter.ActualValue,
+            CoordinatesParameter.ActualValue,
+            DistanceMatrixParameter,
+            UseDistanceMatrixParameter.ActualValue);
+      }
+
+      Manipulate(RandomParameter.ActualValue, VRPToursParameter.ActualValue as ZhuEncoding);
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Manipulators/ZhuPermutationManipulator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Manipulators/ZhuPermutationManipulator.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/Manipulators/ZhuPermutationManipulator.cs	(revision 4293)
@@ -0,0 +1,52 @@
+﻿#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.Zhu {
+  [Item("ZhuPermutationManipulator", "An operator which manipulates a VRP representation by using a standard permutation manipulator.")]
+  [StorableClass]
+  public sealed class ZhuPermutationManipulator : ZhuManipulator {
+    public IValueLookupParameter<IPermutationManipulator> InnerManipulatorParameter {
+      get { return (IValueLookupParameter<IPermutationManipulator>)Parameters["InnerManipulator"]; }
+    }
+
+    [StorableConstructor]
+    private ZhuPermutationManipulator(bool deserializing) : base(deserializing) { }
+
+    public ZhuPermutationManipulator()
+      : base() {
+        Parameters.Add(new ValueLookupParameter<IPermutationManipulator>("InnerManipulator", "The permutation manipulator.", new TranslocationManipulator()));
+    }
+
+    protected override void Manipulate(IRandom random, ZhuEncoding individual) {
+      InnerManipulatorParameter.ActualValue.PermutationParameter.ActualName = VRPToursParameter.ActualName;
+
+      IAtomicOperation op = this.ExecutionContext.CreateOperation(
+        InnerManipulatorParameter.ActualValue, this.ExecutionContext.Scope);
+      op.Operator.Execute((IExecutionContext)op);
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/ZhuEncoding.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/ZhuEncoding.cs	(revision 4293)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Zhu/ZhuEncoding.cs	(revision 4293)
@@ -0,0 +1,190 @@
+﻿#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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System.Collections.Generic;
+using HeuristicLab.Problems.VehicleRouting.Encodings.General;
+using System;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Zhu {
+  [Item("ZhuEncoding", "Represents a Zhu encoding of VRP solutions. It is implemented as described in Zhu, K.Q. (2000). A New Genetic Algorithm For VRPTW. Proceedings of the International Conference on Artificial Intelligence.")]
+  [StorableClass]
+  public class ZhuEncoding : PermutationEncoding {
+    [Storable]
+    private int cities;
+
+    [Storable]
+    private DoubleMatrix coordinates;
+
+    [Storable]
+    private BoolValue useDistanceMatrix;
+
+    [Storable]
+    DoubleArray dueTimeArray;
+    
+    [Storable]
+    DoubleArray serviceTimeArray;
+
+    [Storable]
+    DoubleArray readyTimeArray;
+    
+    [Storable]
+    DoubleArray demandArray;
+
+    [Storable]
+    DoubleValue capacity;
+
+    #region IVRPEncoding Members
+    public override List<Tour> GetTours(ILookupParameter<DoubleMatrix> distanceMatrix, int maxVehicles = int.MaxValue) {
+      List<Tour> result = new List<Tour>();
+
+      Tour newTour = new Tour();
+
+      for (int i = 0; i < this.Length; i++) {
+        int city = this[i] + 1;
+        newTour.Cities.Add(city);
+        if (!newTour.Feasible(
+          dueTimeArray,
+          serviceTimeArray,
+          readyTimeArray,
+          demandArray,
+          capacity,
+          coordinates,
+          distanceMatrix,
+          useDistanceMatrix)) {
+            newTour.Cities.Remove(city);
+            if (newTour.Cities.Count > 0)
+              result.Add(newTour);
+
+            newTour = new Tour();
+            newTour.Cities.Add(city);
+        }
+      }
+
+      if (newTour.Cities.Count > 0)
+        result.Add(newTour);
+
+      //if there are too many vehicles - repair
+      while (result.Count > maxVehicles) {
+        Tour tour = result[result.Count - 1];
+
+        //find predecessor / successor in permutation
+        int predecessorIndex = Array.IndexOf(this.array, tour.Cities[0] - 1) - 1;
+        if (predecessorIndex >= 0) {
+          int predecessor = this[predecessorIndex] + 1;
+
+          foreach (Tour t in result) {
+            int insertPosition = t.Cities.IndexOf(predecessor) + 1;
+            if (insertPosition != -1) {
+              t.Cities.InsertRange(insertPosition, tour.Cities);
+              break;
+            }
+          }
+        } else {
+          int successorIndex = Array.IndexOf(this.array,
+            tour.Cities[tour.Cities.Count - 1] - 1) + 1;
+          int successor = this[successorIndex] + 1;
+
+          foreach (Tour t in result) {
+            int insertPosition = t.Cities.IndexOf(successor);
+            if (insertPosition != -1) {
+              t.Cities.InsertRange(insertPosition, tour.Cities);
+              break;
+            }
+          }
+        }
+
+        result.Remove(tour);
+      }
+
+      return result;
+    }
+    #endregion
+
+    public override IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
+      ZhuEncoding clone = new ZhuEncoding(
+        new Permutation(this.PermutationType, this.array), cities, 
+        dueTimeArray, serviceTimeArray, readyTimeArray, demandArray, capacity,
+        coordinates, useDistanceMatrix);
+
+      cloner.RegisterClonedObject(this, clone);
+      clone.readOnly = readOnly;
+      return clone;
+    }
+
+    public ZhuEncoding(Permutation permutation, int cities,
+      DoubleArray dueTimeArray, DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
+      DoubleMatrix coordinates, BoolValue useDistanceMatrix)
+      : base(permutation) {
+        this.cities = cities;
+        this.dueTimeArray = dueTimeArray;
+        this.serviceTimeArray = serviceTimeArray;
+        this.readyTimeArray = readyTimeArray;
+        this.demandArray = demandArray;
+        this.capacity = capacity;
+        this.coordinates = coordinates;
+        this.useDistanceMatrix = useDistanceMatrix;
+    }
+
+    [StorableConstructor]
+    private ZhuEncoding(bool serializing)
+      : base(serializing) {
+    }
+
+    public static ZhuEncoding ConvertFrom(IVRPEncoding encoding, int cities,
+      DoubleArray dueTimeArray, DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
+      DoubleMatrix coordinates, ILookupParameter<DoubleMatrix> distanceMatrix, BoolValue useDistanceMatrix) {
+      List<Tour> tours = encoding.GetTours(distanceMatrix);
+      List<int> route = new List<int>();
+
+      foreach (Tour tour in tours) {
+        foreach (int city in tour.Cities)
+          route.Add(city - 1);
+      }
+
+      return new ZhuEncoding(
+        new Permutation(PermutationTypes.RelativeUndirected, route.ToArray()), cities,
+        dueTimeArray, serviceTimeArray, readyTimeArray, demandArray, capacity,
+        coordinates, useDistanceMatrix);
+    }
+
+    public static ZhuEncoding ConvertFrom(List<int> routeParam, int cities, 
+      DoubleArray dueTimeArray, DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
+      DoubleMatrix coordinates, BoolValue useDistanceMatrix) {
+      List<int> route = new List<int>(routeParam);
+
+      while (route.Remove(0)) { //remove all delimiters (0)
+      }
+
+      for (int i = 0; i < route.Count; i++)
+        route[i]--;
+
+      return new ZhuEncoding(
+        new Permutation(PermutationTypes.RelativeUndirected, route.ToArray()), cities, 
+        dueTimeArray, serviceTimeArray, readyTimeArray, demandArray, capacity,
+        coordinates, useDistanceMatrix);
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 4288)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 4293)
@@ -166,4 +166,13 @@
     <Compile Include="Encodings\Prins\Manipulators\PrinsPermutationManipulator.cs" />
     <Compile Include="Encodings\Prins\PrinsEncoding.cs" />
+    <Compile Include="Encodings\Zhu\Crossovers\ZhuMergeCrossover2.cs" />
+    <Compile Include="Encodings\Zhu\Crossovers\ZhuMergeCrossover1.cs" />
+    <Compile Include="Encodings\Zhu\Crossovers\ZhuHeuristicCrossover2.cs" />
+    <Compile Include="Encodings\Zhu\Crossovers\ZhuHeuristicCrossover1.cs" />
+    <Compile Include="Encodings\Zhu\Crossovers\ZhuCrossover.cs" />
+    <Compile Include="Encodings\Zhu\Crossovers\ZhuPermutationCrossover.cs" />
+    <Compile Include="Encodings\Zhu\Manipulators\ZhuPermutationManipulator.cs" />
+    <Compile Include="Encodings\Zhu\Manipulators\ZhuManipulator.cs" />
+    <Compile Include="Encodings\Zhu\ZhuEncoding.cs" />
     <Compile Include="Interfaces\IVRPMoveMaker.cs" />
     <Compile Include="TSPLIBParser.cs" />
