- Timestamp:
- 11/30/16 09:24:40 (8 years ago)
- Location:
- branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4
- Files:
-
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/Cluster.cs
r14424 r14430 7 7 using HeuristicLab.Core; 8 8 using HeuristicLab.Problems.VehicleRouting.Interfaces; 9 using HeuristicLab.Problems.VehicleRouting.Variants; 9 10 10 11 namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin { … … 42 43 public int Id; 43 44 protected readonly IVRPProblemInstance instance; 44 public List<T> Objects { get; private set; }45 public List<T> Elements { get; private set; } 45 46 46 47 public T Mean { get; set; } 48 49 public double Variance { get; set; } 47 50 48 51 public Cluster(IVRPProblemInstance instance, int id) { 49 52 this.instance = instance; 50 53 Id = id; 51 Objects = new List<T>();54 Elements = new List<T>(); 52 55 53 56 } 54 57 public bool AddObject(T o) { 55 Objects.Add(o);58 Elements.Add(o); 56 59 57 60 bool clusterChanged = o.ClusterId != Id; … … 67 70 public abstract void CalculateMean(); 68 71 72 public abstract void CalculateVariance(); 73 69 74 public abstract double CalculateImpact(T o); 70 75 … … 76 81 public override void CalculateMean() { 77 82 int dimensions = instance.Coordinates.Columns; 78 SpatialDistanceClusterElement mean = new SpatialDistanceClusterElement(-1, Id, dimensions);79 foreach (SpatialDistanceClusterElement o in Objects) {83 SpatialDistanceClusterElement mean = new SpatialDistanceClusterElement(-1, dimensions, Id); 84 foreach (SpatialDistanceClusterElement o in Elements) { 80 85 double[] coordinates = instance.GetCoordinates(o.Id); 81 86 for (int i = 0; i < coordinates.Length; i++) { 82 mean.Coordinates[i] += (coordinates[i] / Objects.Count);87 mean.Coordinates[i] += (coordinates[i] / Elements.Count); 83 88 } 84 89 } 85 90 Mean = mean; 91 } 92 93 public override void CalculateVariance() { 94 if(Mean == null) 95 CalculateMean(); 96 97 Variance = 0.0; 98 foreach (SpatialDistanceClusterElement o in Elements) { 99 Variance += Math.Pow(Mean.GetDistance(o), 2); 100 } 101 Variance /= Elements.Count; 86 102 } 87 103 … … 90 106 CalculateMean(); 91 107 92 return Math.Pow(Mean.GetDistance(o), 2) / ((Objects.Count > 0) ? Objects.Count : 1); 108 double newVariance = (Variance*Elements.Count + Math.Pow(Mean.GetDistance(o), 2))/(Elements.Count + 1); 109 return newVariance - Variance; 110 } 111 } 112 113 public class TemporalDistanceCluster : Cluster<TemporalDistanceClusterElement> { 114 public TemporalDistanceCluster(ITimeWindowedProblemInstance instance, int id) : base(instance, id) { 115 } 116 117 118 public override void CalculateMean() { 119 TemporalDistanceClusterElement mean = new TemporalDistanceClusterElement(-1, Id); 120 foreach (TemporalDistanceClusterElement e in Elements) { 121 mean.ReadyTime += e.ReadyTime/Elements.Count; 122 mean.DueTime += e.DueTime/Elements.Count; 123 } 124 Mean = mean; 125 } 126 127 public override void CalculateVariance() { 128 if (Mean == null) 129 CalculateMean(); 130 131 Variance = 0.0; 132 foreach (TemporalDistanceClusterElement e in Elements) { 133 Variance += Math.Pow(Math.Abs(Mean.ReadyTime - e.ReadyTime) + Math.Abs(Mean.DueTime - e.DueTime), 2); 134 } 135 Variance /= Elements.Count; 136 } 137 138 public override double CalculateImpact(TemporalDistanceClusterElement o) { 139 if(Mean == null) 140 CalculateMean(); 141 142 double newVariance = (Variance * Elements.Count + Math.Pow(Math.Abs(Mean.ReadyTime - o.ReadyTime) + Math.Abs(Mean.DueTime - o.DueTime), 2)) / (Elements.Count + 1); 143 return newVariance - Variance; 93 144 } 94 145 } … … 131 182 var other = o as SpatialDistanceClusterElement; 132 183 if (other == null) { 133 throw new Ar rayTypeMismatchException(string.Format("Distance calculation between {0} and {1} is not possible.",184 throw new ArgumentException(string.Format("Distance calculation between {0} and {1} is not possible.", 134 185 typeof(SpatialDistanceClusterElement), o.GetType())); 135 186 } … … 143 194 } 144 195 } 196 197 public class TemporalDistanceClusterElement : ClusterElement { 198 public double ReadyTime { get; set; } 199 public double DueTime { get; set; } 200 201 public TemporalDistanceClusterElement(int id, int clusterId = -1) : base(id, clusterId) { 202 } 203 204 public TemporalDistanceClusterElement(int id, double readyTime, double dueTime, int clusterId = -1) : base(id, clusterId) { 205 ReadyTime = readyTime; 206 DueTime = dueTime; 207 } 208 209 public override double GetDistance(IClusterElement o) { 210 var other = o as TemporalDistanceClusterElement; 211 if (other == null) { 212 throw new ArgumentException(string.Format("Distance calculation between {0} and {1} is not possible.", 213 typeof(TemporalDistanceClusterElement), o.GetType())); 214 } 215 216 double distance = 0.0; 217 distance += Math.Abs(ReadyTime - other.ReadyTime); 218 distance += Math.Abs(DueTime - other.DueTime); 219 220 return distance; 221 222 //return GetDistanceEuklid(other); 223 } 224 225 public double GetDistanceEuklid(TemporalDistanceClusterElement other) { 226 double distance = 0.0; 227 distance += Math.Pow(ReadyTime - other.ReadyTime, 2); 228 distance += Math.Pow(DueTime - other.DueTime, 2); 229 230 return Math.Sqrt(distance); 231 } 232 233 } 234 145 235 #endregion ClusterElement 146 236 } -
branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/GeographicDistanceClusterCreator.cs
r14424 r14430 83 83 if (creationOption == 0) { 84 84 // (a) shuffle 85 c. Objects.Shuffle(random);86 foreach (var o in c. Objects) {85 c.Elements.Shuffle(random); 86 foreach (var o in c.Elements) { 87 87 newTour.Stops.Add(o.Id); 88 88 } 89 89 } else { 90 90 // (b) greedy 91 foreach (var o in c. Objects) {91 foreach (var o in c.Elements) { 92 92 newTour.Stops.Add(o.Id); 93 93 } … … 128 128 129 129 // remove empty clusters 130 clusters.RemoveAll(c => c. Objects.Count.Equals(0));130 clusters.RemoveAll(c => c.Elements.Count.Equals(0)); 131 131 132 132 return clusters; … … 137 137 138 138 foreach (var c in clusters) { 139 c. Objects.Clear();139 c.Elements.Clear(); 140 140 } 141 141 142 142 foreach (var o in objects) { 143 int bestClusterIdx = -1;144 double minImpact = double.MaxValue;145 for (int i = 0; i < clusters.Count; i++) {143 int bestClusterIdx = 0; 144 double minImpact = clusters[0].CalculateImpact(o); 145 for (int i = 1; i < clusters.Count; i++) { 146 146 double impact = clusters[i].CalculateImpact(o); 147 147 if (impact < minImpact) { … … 156 156 foreach (var c in clusters) { 157 157 c.CalculateMean(); 158 c.CalculateVariance(); 158 159 } 159 160 -
branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/TemporalDistanceClusterCreator.cs
r14424 r14430 20 20 #endregion 21 21 22 using System; 22 23 using System.Collections.Generic; 23 24 using System.Linq; … … 30 31 31 32 namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin { 32 [Item(" GeographicDistanceClusterCreator", "Creates a VRP solution by clustering customers first with a KMeans-algorithm based on their geographic position and building tours afterwards alternatevly in a random or a greedy fashion.")]33 [Item("TemporalDistanceClusterCreator", "Creates a VRP solution by clustering customers first with a KMeans-algorithm based on their geographic position and building tours afterwards alternatevly in a random or a greedy fashion.")] 33 34 [StorableClass] 34 public sealed class GeographicDistanceClusterCreator : ClusterCreator {35 public sealed class TemporalDistanceClusterCreator : ClusterCreator { 35 36 36 37 [StorableConstructor] 37 private GeographicDistanceClusterCreator(bool deserializing) : base(deserializing) { }38 private TemporalDistanceClusterCreator(bool deserializing) : base(deserializing) { } 38 39 39 public GeographicDistanceClusterCreator() : base() {40 public TemporalDistanceClusterCreator() : base() { 40 41 } 41 42 42 private GeographicDistanceClusterCreator(GeographicDistanceClusterCreator original, Cloner cloner)43 private TemporalDistanceClusterCreator(TemporalDistanceClusterCreator original, Cloner cloner) 43 44 : base(original, cloner) { 44 45 } 45 46 46 47 public override IDeepCloneable Clone(Cloner cloner) { 47 return new GeographicDistanceClusterCreator(this, cloner);48 return new TemporalDistanceClusterCreator(this, cloner); 48 49 } 49 50 50 public static List< SpatialDistanceClusterElement> CreateClusterObjects(IVRPProblemInstance instance) {51 public static List<TemporalDistanceClusterElement> CreateClusterObjects(ITimeWindowedProblemInstance instance) { 51 52 IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; 52 53 … … 58 59 } 59 60 60 // wrap stops in SpatialDistanceClusterElement61 List< SpatialDistanceClusterElement> clusterObjects = new List<SpatialDistanceClusterElement>();61 // wrap stops in TemporalDistanceClusterElement 62 List<TemporalDistanceClusterElement> clusterObjects = new List<TemporalDistanceClusterElement>(); 62 63 foreach (int customer in customers) { 63 clusterObjects.Add(new SpatialDistanceClusterElement(customer, instance.GetCoordinates(customer)));64 clusterObjects.Add(new TemporalDistanceClusterElement(customer, instance.ReadyTime[customer], instance.DueTime[customer])); 64 65 } 65 66 return clusterObjects; 66 67 } 67 68 68 public static PotvinEncoding CreateSolution(I VRPProblemInstance instance, IRandom random, int minK, int maxK, double clusterChangeThreshold, int creationOption) {69 public static PotvinEncoding CreateSolution(ITimeWindowedProblemInstance instance, IRandom random, int minK, int maxK, double clusterChangeThreshold, int creationOption) { 69 70 PotvinEncoding result = new PotvinEncoding(instance); 70 71 71 List< SpatialDistanceClusterElement> clusterObjects = CreateClusterObjects(instance);72 List<TemporalDistanceClusterElement> clusterObjects = CreateClusterObjects(instance); 72 73 73 74 int k = random.Next(minK, maxK); 74 List< SpatialDistanceCluster> clusters = KMeans(instance, random, clusterObjects, k, clusterChangeThreshold);75 List<TemporalDistanceCluster> clusters = KMeans(instance, random, clusterObjects, k, clusterChangeThreshold); 75 76 76 77 // (3) build tours … … 83 84 if (creationOption == 0) { 84 85 // (a) shuffle 85 c. Objects.Shuffle(random);86 foreach (var o in c. Objects) {86 c.Elements.Shuffle(random); 87 foreach (var o in c.Elements) { 87 88 newTour.Stops.Add(o.Id); 88 89 } 89 90 } else { 90 91 // (b) greedy 91 foreach (var o in c. Objects) {92 foreach (var o in c.Elements) { 92 93 newTour.Stops.Add(o.Id); 93 94 } … … 99 100 } 100 101 101 private static List< SpatialDistanceCluster> KMeans(IVRPProblemInstance instance, IRandom random, List<SpatialDistanceClusterElement> objects, int k, double changeTreshold) {102 private static List<TemporalDistanceCluster> KMeans(ITimeWindowedProblemInstance instance, IRandom random, List<TemporalDistanceClusterElement> objects, int k, double changeTreshold) { 102 103 103 List< SpatialDistanceCluster> clusters = new List<SpatialDistanceCluster>();104 List<TemporalDistanceCluster> clusters = new List<TemporalDistanceCluster>(); 104 105 HashSet<int> initMeans = new HashSet<int>(); 105 106 int nextMean = -1; … … 107 108 // (1) initialize each cluster with a random first object (i.e. mean) 108 109 for (int i = 0; i < k && i < objects.Count; i++) { 109 SpatialDistanceCluster cluster = new SpatialDistanceCluster(instance, i);110 TemporalDistanceCluster cluster = new TemporalDistanceCluster(instance, i); 110 111 111 112 do { … … 128 129 129 130 // remove empty clusters 130 clusters.RemoveAll(c => c. Objects.Count.Equals(0));131 clusters.RemoveAll(c => c.Elements.Count.Equals(0)); 131 132 132 133 return clusters; 133 134 } 134 135 135 private static int KMeansRun(List< SpatialDistanceCluster> clusters, List<SpatialDistanceClusterElement> objects) {136 private static int KMeansRun(List<TemporalDistanceCluster> clusters, List<TemporalDistanceClusterElement> objects) { 136 137 int changes = 0; 137 138 138 139 foreach (var c in clusters) { 139 c. Objects.Clear();140 c.Elements.Clear(); 140 141 } 141 142 142 143 foreach (var o in objects) { 143 int bestClusterIdx = -1;144 double minImpact = double.MaxValue;145 for (int i = 0; i < clusters.Count; i++) {144 int bestClusterIdx = 0; 145 double minImpact = clusters[0].CalculateImpact(o); 146 for (int i = 1; i < clusters.Count; i++) { 146 147 double impact = clusters[i].CalculateImpact(o); 147 if (impact < minImpact) { 148 if ((minImpact > 0 && impact < minImpact) || (minImpact < 0 && impact > minImpact)) { // V1: min positive impact 149 //if(impact > minImpact) { // V2: max impact 148 150 minImpact = impact; 149 151 bestClusterIdx = i; … … 156 158 foreach (var c in clusters) { 157 159 c.CalculateMean(); 160 c.CalculateVariance(); 158 161 } 159 162 … … 181 184 int creationOption = creationOptions.SampleProportional(random, 1, probabilites, false, false).First(); 182 185 183 VRPToursParameter.ActualValue = CreateSolution(ProblemInstance, random, minK, maxK, clusterChangeThreshold, creationOption); 186 var instance = ProblemInstance as ITimeWindowedProblemInstance; 187 if (instance == null) { 188 throw new ArgumentException(string.Format("Cannot initialize {0} with data from {1}", instance.GetType(), ProblemInstance.GetType())); 189 } 190 191 VRPToursParameter.ActualValue = CreateSolution(instance, random, minK, maxK, clusterChangeThreshold, creationOption); 184 192 return base.InstrumentedApply(); 185 193 } -
branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj
r14424 r14430 198 198 <Compile Include="Encodings\Potvin\Creators\Cluster.cs" /> 199 199 <Compile Include="Encodings\Potvin\Creators\ClusterCreator.cs" /> 200 <Compile Include="Encodings\Potvin\Creators\TemporalDistanceClusterCreator.cs" /> 200 201 <Compile Include="Encodings\Potvin\Creators\GeographicDistanceClusterCreator.cs" /> 201 202 <Compile Include="Encodings\Potvin\Crossovers\PotvinEdgePreservingSequenceBasedCrossover.cs" />
Note: See TracChangeset
for help on using the changeset viewer.