- Timestamp:
- 10/05/11 15:54:51 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/PushForwardInsertionCreator.cs
r6857 r6870 116 116 } 117 117 118 private static PotvinEncoding CreateSolution(IVRPProblemInstance problemInstance, IRandom random, 118 private static int GetNearestDepot(IVRPProblemInstance problemInstance, List<int> depots, int customer, 119 double alpha, double beta, double gamma, out double minCost) { 120 int nearest = -1; 121 minCost = double.MaxValue; 122 123 int depotCount = 1; 124 IMultiDepotProblemInstance mdp = problemInstance as IMultiDepotProblemInstance; 125 if (mdp != null) { 126 depotCount = mdp.Depots.Value; 127 } 128 129 foreach (int depot in depots) { 130 double x0 = problemInstance.Coordinates[depot, 0]; 131 double y0 = problemInstance.Coordinates[depot, 1]; 132 133 double distance = GetDistance(customer + depotCount - 1, depot, problemInstance); 134 135 double dueTime = 0; 136 if (problemInstance is ITimeWindowedProblemInstance) 137 dueTime = (problemInstance as ITimeWindowedProblemInstance).DueTime[customer + depotCount - 1]; 138 if (dueTime == double.MaxValue) 139 dueTime = 0; 140 141 double dist; 142 if (problemInstance.Coordinates[customer + depotCount - 1, 0] < x0) 143 dist = -distance; 144 else 145 dist = distance; 146 147 double cost = alpha * distance + // distance 0 <-> City[i] 148 -beta * dueTime + // latest arrival time 149 -gamma * (Math.Asin((problemInstance.Coordinates[customer + depotCount - 1, 1] - y0) / dist) / 360 * dist); // polar angle 150 151 if (cost < minCost) { 152 minCost = cost; 153 nearest = depot; 154 } 155 } 156 157 return nearest; 158 } 159 160 private static List<int> SortCustomers(IVRPProblemInstance problemInstance, List<int> customers, List<int> depots, 161 Dictionary<int, int> depotAssignment, 162 double alpha, double beta, double gamma) { 163 List<int> sortedCustomers = new List<int>(); 164 depotAssignment.Clear(); 165 166 List<double> costList = new List<double>(); 167 168 for (int i = 0; i < customers.Count; i++) { 169 double cost; 170 int depot = GetNearestDepot(problemInstance, depots, customers[i], 171 alpha, beta, gamma, 172 out cost); 173 depotAssignment[customers[i]] = depot; 174 175 int index = 0; 176 while (index < costList.Count && costList[index] < cost) index++; 177 costList.Insert(index, cost); 178 sortedCustomers.Insert(index, customers[i]); 179 } 180 181 return sortedCustomers; 182 } 183 184 private static bool RemoveUnusedDepots(List<int> depots, Dictionary<int, List<int>> vehicles) { 185 List<int> toBeRemoved = new List<int>(); 186 187 foreach (int depot in depots) { 188 if (vehicles[depot].Count == 0) 189 toBeRemoved.Add(depot); 190 } 191 192 foreach (int depot in toBeRemoved) { 193 depots.Remove(depot); 194 vehicles.Remove(depot); 195 } 196 197 return toBeRemoved.Count > 0; 198 } 199 200 public static PotvinEncoding CreateSolution(IVRPProblemInstance problemInstance, IRandom random, 119 201 double alphaValue = 0.7, double betaValue = 0.1, double gammaValue = 0.2, 120 202 double alphaVariance = 0.5, double betaVariance = 0.07, double gammaVariance = 0.14) { 121 203 PotvinEncoding result = new PotvinEncoding(problemInstance); 204 205 IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; 206 IMultiDepotProblemInstance mdp = problemInstance as IMultiDepotProblemInstance; 122 207 123 208 double alpha, beta, gamma; … … 126 211 gamma = N(gammaValue, Math.Sqrt(gammaVariance), random); 127 212 128 int totalTours = 0; 129 130 double distance = 0; 131 double cost = 0; 132 List<int> unroutedList = new List<int>(); 133 List<double> costList = new List<double>(); 134 135 IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; 136 IMultiDepotProblemInstance mdp = problemInstance as IMultiDepotProblemInstance; 137 138 int depots = 1; 213 List<int> unroutedCustomers = new List<int>(); 214 for (int i = 1; i <= problemInstance.Cities.Value; i++) { 215 if (pdp == null || 216 (problemInstance.GetDemand(i) >= 0 || 217 pdp.GetPickupDeliveryLocation(i) <= 0)) 218 unroutedCustomers.Add(i); 219 } 220 221 List<int> depots = new List<int>(); 139 222 if (mdp != null) { 140 depots = mdp.Depots.Value;141 for (int i = 0; i < result.VehicleAssignment.Length; i++)142 result.VehicleAssignment[i] = -1;143 } 144 145 List<int> unrouted = new List<int>();146 for (int i = 1; i <= problemInstance.Cities.Value; i++) 147 if (pdp == null || problemInstance.GetDemand(i) >= 0)148 unrouted.Add(i);149 150 for (int depot = 0; depot < depots; depot++) { 223 for (int i = 0; i < mdp.Depots.Value; i++) { 224 depots.Add(i); 225 } 226 } else { 227 depots.Add(0); 228 } 229 230 Dictionary<int, List<int>> vehicles = new Dictionary<int, List<int>>(); 231 foreach (int depot in depots) { 232 vehicles[depot] = new List<int>(); 233 151 234 int vehicleCount = problemInstance.Vehicles.Value; 152 List<int> vehicles = new List<int>();153 235 if (mdp != null) { 154 vehicleCount = 0; 155 for (int i = 0; i < mdp.VehicleDepotAssignment.Length; i++) { 156 if (mdp.VehicleDepotAssignment[i] == depot) { 157 vehicleCount++; 158 vehicles.Add(i); 236 for (int vehicle = 0; vehicle < mdp.VehicleDepotAssignment.Length; vehicle++) { 237 if (mdp.VehicleDepotAssignment[vehicle] == depot) { 238 vehicles[depot].Add(vehicle); 159 239 } 160 240 } 161 241 } else { 162 for (int i = 0; i < problemInstance.Vehicles.Value; i++) 163 vehicles.Add(i); 164 } 165 166 costList.Clear(); 167 unroutedList.Clear(); 168 169 double x0 = problemInstance.Coordinates[depot, 0]; 170 double y0 = problemInstance.Coordinates[depot, 1]; 171 172 /*----------------------------------------------------------------------------- 173 * generate cost list 174 *----------------------------------------------------------------------------- 175 */ 176 for (int i = 1; i <= problemInstance.Cities.Value; i++) { 177 //only insert sources 178 if (unrouted.Contains(i) && (pdp == null || problemInstance.GetDemand(i) >= 0)) { 179 distance = GetDistance(i + depots - 1, depot, problemInstance); 180 if (problemInstance.Coordinates[i + depots - 1, 0] < x0) distance = -distance; 181 182 double dueTime = 0; 183 if (problemInstance is ITimeWindowedProblemInstance) 184 dueTime = (problemInstance as ITimeWindowedProblemInstance).DueTime[i + depots - 1]; 185 186 cost = -alpha * distance + // distance 0 <-> City[i] 187 beta * dueTime + // latest arrival time 188 gamma * (Math.Asin((problemInstance.Coordinates[i + depots - 1, 0] - y0) / distance) / 360 * distance); // polar angle 189 190 int index = 0; 191 while (index < costList.Count && costList[index] < cost) index++; 192 193 costList.Insert(index, cost); 194 195 unroutedList.Insert(index, i); 196 } 197 } 198 199 int tours = 0; 242 for (int vehicle = 0; vehicle < vehicleCount; vehicle++) { 243 vehicles[depot].Add(vehicle); 244 } 245 } 246 } 247 248 RemoveUnusedDepots(depots, vehicles); 249 Dictionary<int, int> depotAssignment = new Dictionary<int, int>(); 250 251 unroutedCustomers = SortCustomers( 252 problemInstance, unroutedCustomers, depots, depotAssignment, 253 alpha, beta, gamma); 254 255 ///////// 256 Tour tour = new Tour(); 257 result.Tours.Add(tour); 258 int currentCustomer = unroutedCustomers[0]; 259 unroutedCustomers.RemoveAt(0); 260 261 int currentDepot = depotAssignment[currentCustomer]; 262 int currentVehicle = vehicles[currentDepot][0]; 263 vehicles[currentDepot].RemoveAt(0); 264 if (RemoveUnusedDepots(depots, vehicles)) { 265 unroutedCustomers = SortCustomers( 266 problemInstance, unroutedCustomers, depots, depotAssignment, 267 alpha, beta, gamma); 268 } 269 270 result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle; 271 272 tour.Stops.Add(currentCustomer); 273 if (pdp != null && pdp.GetPickupDeliveryLocation(currentCustomer) > 0) { 274 tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer)); 275 } 276 //////// 277 278 while (unroutedCustomers.Count > 0) { 200 279 double minimumCost = double.MaxValue; 280 int customer = -1; 201 281 int indexOfMinimumCost = -1; 202 282 int indexOfMinimumCost2 = -1; 203 int indexOfCustomer = -1; 204 205 Tour tour = new Tour(); 206 result.Tours.Add(tour); 207 result.VehicleAssignment[totalTours] = vehicles[0]; 208 vehicles.RemoveAt(0); 209 tours++; 210 totalTours++; 211 212 tour.Stops.Add(unroutedList[0]); 213 214 if (pdp != null) { 215 tour.Stops.Add(pdp.GetPickupDeliveryLocation(unroutedList[0])); 216 } 217 218 unrouted.Remove(unroutedList[0]); 219 unroutedList.RemoveAt(0); 220 221 while (unroutedList.Count > 0 && (tours < vehicleCount || depot == depots - 1)) { 222 for (int c = 0; c < unroutedList.Count; c++) { 223 VRPEvaluation eval = problemInstance.EvaluateTour(tour, result); 224 double originalCosts = eval.Quality; 225 int customer = unroutedList[c]; 226 227 for (int i = 0; i <= tour.Stops.Count; i++) { 228 tour.Stops.Insert(i, customer); 229 eval = problemInstance.EvaluateTour(tour, result); 230 double tourCost = eval.Quality - originalCosts; 231 232 if (pdp != null) { 233 for (int j = i + 1; j <= tour.Stops.Count; j++) { 234 bool feasible; 235 cost = tourCost + 236 problemInstance.GetInsertionCosts(eval, result, pdp.GetPickupDeliveryLocation(unroutedList[c]), 0, j, out feasible); 237 if (cost < minimumCost && feasible) { 238 minimumCost = cost; 239 indexOfMinimumCost = i; 240 indexOfMinimumCost2 = j; 241 indexOfCustomer = c; 242 } 243 } 244 } else { 245 cost = tourCost; 246 bool feasible = problemInstance.Feasible(eval); 283 284 foreach (int unrouted in unroutedCustomers) { 285 VRPEvaluation eval = problemInstance.EvaluateTour(tour, result); 286 double originalCosts = eval.Quality; 287 288 for (int i = 0; i <= tour.Stops.Count; i++) { 289 tour.Stops.Insert(i, unrouted); 290 eval = problemInstance.EvaluateTour(tour, result); 291 double tourCost = eval.Quality - originalCosts; 292 293 if (pdp != null && pdp.GetPickupDeliveryLocation(unrouted) > 0) { 294 for (int j = i + 1; j <= tour.Stops.Count; j++) { 295 bool feasible; 296 double cost = tourCost + 297 problemInstance.GetInsertionCosts(eval, result, pdp.GetPickupDeliveryLocation(unrouted), 0, j, out feasible); 247 298 if (cost < minimumCost && feasible) { 299 customer = unrouted; 248 300 minimumCost = cost; 249 301 indexOfMinimumCost = i; 250 indexOf Customer = c;302 indexOfMinimumCost2 = j; 251 303 } 252 304 } 253 254 tour.Stops.RemoveAt(i); 305 } else { 306 double cost = tourCost; 307 bool feasible = problemInstance.Feasible(eval); 308 if (cost < minimumCost && feasible) { 309 customer = unrouted; 310 minimumCost = cost; 311 indexOfMinimumCost = i; 312 } 255 313 } 256 } 257 258 // insert customer if found 259 if (indexOfMinimumCost != -1) { 260 tour.Stops.Insert(indexOfMinimumCost, unroutedList[indexOfCustomer]); 261 if (pdp != null) { 262 tour.Stops.Insert(indexOfMinimumCost2, pdp.GetPickupDeliveryLocation(unroutedList[indexOfCustomer])); 263 } 264 265 unrouted.Remove(unroutedList[indexOfCustomer]); 266 unroutedList.RemoveAt(indexOfCustomer); 267 } else if (tours < vehicleCount || depot == depots - 1) { // no feasible customer found 268 tour = new Tour(); 269 result.Tours.Add(tour); 270 result.VehicleAssignment[totalTours] = vehicles[0]; 271 vehicles.RemoveAt(0); 272 tours++; 273 totalTours++; 274 275 tour.Stops.Add(unroutedList[0]); 276 if (pdp != null) { 277 tour.Stops.Add(pdp.GetPickupDeliveryLocation(unroutedList[0])); 278 } 279 280 unrouted.Remove(unroutedList[0]); 281 unroutedList.RemoveAt(0); 282 } 283 // reset minimum 284 minimumCost = double.MaxValue; 285 indexOfMinimumCost = -1; 286 indexOfMinimumCost2 = -1; 287 indexOfCustomer = -1; 314 315 tour.Stops.RemoveAt(i); 316 } 317 } 318 319 if (indexOfMinimumCost == -1 && vehicles.Count == 0) { 320 indexOfMinimumCost = tour.Stops.Count; 321 indexOfMinimumCost2 = tour.Stops.Count + 1; 322 customer = unroutedCustomers[0]; 323 } 324 325 // insert customer if found 326 if (indexOfMinimumCost != -1) { 327 tour.Stops.Insert(indexOfMinimumCost, customer); 328 if (pdp != null && pdp.GetPickupDeliveryLocation(customer) > 0) { 329 tour.Stops.Insert(indexOfMinimumCost2, pdp.GetPickupDeliveryLocation(customer)); 330 } 331 332 unroutedCustomers.Remove(customer); 333 } else { // no feasible customer found 334 tour = new Tour(); 335 result.Tours.Add(tour); 336 currentCustomer = unroutedCustomers[0]; 337 unroutedCustomers.RemoveAt(0); 338 339 currentDepot = depotAssignment[currentCustomer]; 340 currentVehicle = vehicles[currentDepot][0]; 341 vehicles[currentDepot].RemoveAt(0); 342 if (RemoveUnusedDepots(depots, vehicles)) { 343 unroutedCustomers = SortCustomers( 344 problemInstance, unroutedCustomers, depots, depotAssignment, 345 alpha, beta, gamma); 346 } 347 348 result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle; 349 350 tour.Stops.Add(currentCustomer); 351 if (pdp != null && pdp.GetPickupDeliveryLocation(currentCustomer) > 0) { 352 tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer)); 353 } 288 354 } 289 355 }
Note: See TracChangeset
for help on using the changeset viewer.