Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2893_BNLR/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPPDTW/MDCVRPPDTWEvaluator.cs

Last change on this file was 15583, checked in by swagner, 7 years ago

#2640: Updated year of copyrights in license headers

File size: 12.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Parameters;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29using HeuristicLab.Problems.VehicleRouting.Interfaces;
30using HeuristicLab.Problems.VehicleRouting.Variants;
31
32namespace HeuristicLab.Problems.VehicleRouting.ProblemInstances {
33  [Item("MDCVRPPDTWEvaluator", "Represents a multi depot CVRPPDTW evaluator.")]
34  [StorableClass]
35  public class MDCVRPPDTWEvaluator : MDCVRPTWEvaluator {
36    public ILookupParameter<IntValue> PickupViolationsParameter {
37      get { return (ILookupParameter<IntValue>)Parameters["PickupViolations"]; }
38    }
39
40    protected override VRPEvaluation CreateTourEvaluation() {
41      return new CVRPPDTWEvaluation();
42    }
43
44    protected override void EvaluateTour(VRPEvaluation eval, IVRPProblemInstance instance, Tour tour, IVRPEncoding solution) {
45      TourInsertionInfo tourInfo = new TourInsertionInfo(solution.GetVehicleAssignment(solution.GetTourIndex(tour)));
46      eval.InsertionInfo.AddTourInsertionInfo(tourInfo);
47      double originalQuality = eval.Quality;
48
49      IHeterogenousCapacitatedProblemInstance cvrpInstance = instance as IHeterogenousCapacitatedProblemInstance;
50      DoubleArray demand = instance.Demand;
51
52      ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
53      DoubleArray dueTime = vrptw.DueTime;
54      DoubleArray readyTime = vrptw.ReadyTime;
55      DoubleArray serviceTimes = vrptw.ServiceTime;
56
57      IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
58      IntArray pickupDeliveryLocation = pdp.PickupDeliveryLocation;
59
60      IMultiDepotProblemInstance mdp = instance as IMultiDepotProblemInstance;
61      IntArray vehicleAssignment = mdp.VehicleDepotAssignment;
62      int depots = mdp.Depots.Value;
63
64      double time = 0.0;
65      double waitingTime = 0.0;
66      double serviceTime = 0.0;
67      double tardiness = 0.0;
68      double overweight = 0.0;
69      double distance = 0.0;
70
71      int tourIndex = solution.GetTourIndex(tour);
72      int vehicle = solution.GetVehicleAssignment(tourIndex);
73      int depot = vehicleAssignment[vehicle];
74
75      double capacity = cvrpInstance.Capacity[vehicle];
76
77      double currentLoad = 0.0;
78      Dictionary<int, bool> stops = new Dictionary<int, bool>();
79      int pickupViolations = 0;
80
81      double tourStartTime = readyTime[0];
82      time = tourStartTime;
83
84      //simulate a tour, start and end at depot
85      for (int i = 0; i <= tour.Stops.Count; i++) {
86        int start = 0;
87        if (i > 0)
88          start = tour.Stops[i - 1];
89        int end = 0;
90        if (i < tour.Stops.Count)
91          end = tour.Stops[i];
92
93        //drive there
94        double currentDistace = vrptw.GetDistance(start, end, solution);
95        time += currentDistace;
96        distance += currentDistace;
97
98        double arrivalTime = time;
99
100        int endIndex;
101        if (end == 0)
102          endIndex = depot;
103        else
104          endIndex = end + depots - 1;
105
106        //check if it was serviced on time
107        if (time > dueTime[endIndex])
108          tardiness += time - dueTime[endIndex];
109
110        //wait
111        double currentWaitingTime = 0.0;
112        if (time < readyTime[endIndex])
113          currentWaitingTime = readyTime[endIndex] - time;
114
115        double waitTime = readyTime[endIndex] - time;
116
117        waitingTime += currentWaitingTime;
118        time += currentWaitingTime;
119
120        double spareTime = dueTime[endIndex] - time;
121        double arrivalSpareCapacity = capacity - currentLoad;
122
123        if (end > 0) {
124          //service
125          double currentServiceTime = serviceTimes[end - 1];
126          serviceTime += currentServiceTime;
127          time += currentServiceTime;
128
129          //Pickup / deliver
130          bool validPickupDelivery =
131            validPickupDelivery =
132            ((demand[end - 1] >= 0) ||
133             (stops.ContainsKey(pickupDeliveryLocation[end - 1])));
134
135          if (validPickupDelivery) {
136            currentLoad += demand[end - 1];
137          } else {
138            pickupViolations++;
139          }
140
141          if (currentLoad > capacity)
142            overweight += currentLoad - capacity;
143        }
144
145        double spareCapacity = capacity - currentLoad;
146        CVRPPDTWInsertionInfo stopInfo = new CVRPPDTWInsertionInfo(start, end, spareCapacity, tourStartTime,
147          arrivalTime, time, spareTime, waitTime, new List<int>(stops.Keys), arrivalSpareCapacity);
148        tourInfo.AddStopInsertionInfo(stopInfo);
149
150        stops.Add(end, true);
151      }
152
153      eval.Quality += instance.FleetUsageFactor.Value;
154      eval.Quality += instance.DistanceFactor.Value * distance;
155      eval.Distance += distance;
156      eval.VehicleUtilization += 1;
157
158      (eval as CVRPEvaluation).Overload += overweight;
159      double tourPenalty = 0;
160      double penalty = overweight * cvrpInstance.OverloadPenalty.Value;
161      eval.Penalty += penalty;
162      eval.Quality += penalty;
163      tourPenalty += penalty;
164
165      (eval as CVRPTWEvaluation).Tardiness += tardiness;
166      (eval as CVRPTWEvaluation).TravelTime += time;
167
168      penalty = tardiness * vrptw.TardinessPenalty.Value;
169      eval.Penalty += penalty;
170      eval.Quality += penalty;
171      tourPenalty += penalty;
172
173      (eval as CVRPPDTWEvaluation).PickupViolations += pickupViolations;
174      penalty = pickupViolations * pdp.PickupViolationPenalty.Value;
175      eval.Penalty += penalty;
176      tourPenalty += penalty;
177
178      eval.Quality += penalty;
179      eval.Quality += time * vrptw.TimeFactor.Value;
180      tourInfo.Penalty = tourPenalty;
181      tourInfo.Quality = eval.Quality - originalQuality;
182    }
183
184    protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer,
185      out bool feasible) {
186      CVRPPDTWInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index) as CVRPPDTWInsertionInfo;
187
188      double costs = 0;
189      feasible = tourInsertionInfo.Penalty < double.Epsilon;
190      bool tourFeasible = true;
191
192      ICapacitatedProblemInstance cvrp = instance as ICapacitatedProblemInstance;
193      double overloadPenalty = cvrp.OverloadPenalty.Value;
194
195      ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
196      DoubleArray dueTime = vrptw.DueTime;
197      DoubleArray readyTime = vrptw.ReadyTime;
198      DoubleArray serviceTimes = vrptw.ServiceTime;
199      double tardinessPenalty = vrptw.TardinessPenalty.Value;
200
201      IMultiDepotProblemInstance mdp = instance as IMultiDepotProblemInstance;
202      int depots = mdp.Depots.Value;
203
204      IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
205      IntArray pickupDeliveryLocation = pdp.PickupDeliveryLocation;
206      double pickupPenalty = pdp.PickupViolationPenalty.Value;
207
208      double startDistance, endDistance;
209      costs += instance.GetInsertionDistance(insertionInfo.Start, customer, insertionInfo.End, solution, out startDistance, out endDistance);
210
211      double demand = instance.GetDemand(customer);
212      if (demand > insertionInfo.ArrivalSpareCapacity) {
213        tourFeasible = feasible = false;
214        if (insertionInfo.ArrivalSpareCapacity >= 0)
215          costs += (demand - insertionInfo.ArrivalSpareCapacity) * overloadPenalty;
216        else
217          costs += demand * overloadPenalty;
218      }
219      int destination = pickupDeliveryLocation[customer - 1];
220
221      bool validPickup = true;
222      if (demand < 0 && !insertionInfo.Visited.Contains(destination)) {
223        tourFeasible = feasible = false;
224        validPickup = false;
225        costs += pickupPenalty;
226      }
227
228      double time = 0;
229      double tardiness = 0;
230
231      if (index > 0)
232        time = (tourInsertionInfo.GetStopInsertionInfo(index - 1) as CVRPTWInsertionInfo).LeaveTime;
233      else
234        time = insertionInfo.TourStartTime;
235
236      time += startDistance;
237
238      int customerIndex = customer + depots - 1;
239
240      if (time > dueTime[customerIndex]) {
241        tardiness += time - dueTime[customerIndex];
242      }
243      if (time < readyTime[customerIndex])
244        time += readyTime[customerIndex] - time;
245      time += serviceTimes[customer - 1];
246      time += endDistance;
247
248      double additionalTime = time - (tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo).ArrivalTime;
249      for (int i = index; i < tourInsertionInfo.GetStopCount(); i++) {
250        CVRPTWInsertionInfo nextStop = tourInsertionInfo.GetStopInsertionInfo(i) as CVRPTWInsertionInfo;
251
252        if (demand >= 0) {
253          if (nextStop.End == destination) {
254            demand = 0;
255            costs -= pickupPenalty;
256            if (tourInsertionInfo.Penalty == pickupPenalty && tourFeasible)
257              feasible = true;
258          } else if (nextStop.SpareCapacity < 0) {
259            costs += demand * overloadPenalty;
260          } else if (nextStop.SpareCapacity < demand) {
261            tourFeasible = feasible = false;
262            costs += (demand - nextStop.SpareCapacity) * overloadPenalty;
263          }
264        } else if (validPickup) {
265          if (nextStop.SpareCapacity < 0) {
266            costs += Math.Max(demand, nextStop.SpareCapacity) * overloadPenalty;
267          }
268        }
269
270        if (additionalTime < 0) {
271          //arrive earlier than before
272          //wait probably
273          if (nextStop.WaitingTime < 0) {
274            double wait = nextStop.WaitingTime - additionalTime;
275            if (wait > 0)
276              additionalTime += wait;
277          } else {
278            additionalTime = 0;
279          }
280
281          //check due date, decrease tardiness
282          if (nextStop.SpareTime < 0) {
283            costs += Math.Max(nextStop.SpareTime, additionalTime) * tardinessPenalty;
284          }
285        } else {
286          //arrive later than before, probably don't have to wait
287          if (nextStop.WaitingTime > 0) {
288            additionalTime -= Math.Min(additionalTime, nextStop.WaitingTime);
289          }
290
291          //check due date
292          if (nextStop.SpareTime > 0) {
293            double spare = nextStop.SpareTime - additionalTime;
294            if (spare < 0)
295              tardiness += -spare;
296          } else {
297            tardiness += additionalTime;
298          }
299        }
300      }
301
302      costs += additionalTime * vrptw.TimeFactor.Value;
303
304      if (tardiness > 0) {
305        tourFeasible = feasible = false;
306      }
307
308      costs += tardiness * tardinessPenalty;
309
310      return costs;
311    }
312
313    protected override void InitResultParameters() {
314      base.InitResultParameters();
315
316      PickupViolationsParameter.ActualValue = new IntValue(0);
317    }
318
319    protected override void SetResultParameters(VRPEvaluation tourEvaluation) {
320      base.SetResultParameters(tourEvaluation);
321
322      PickupViolationsParameter.ActualValue.Value = (tourEvaluation as CVRPPDTWEvaluation).PickupViolations;
323    }
324
325    [StorableConstructor]
326    protected MDCVRPPDTWEvaluator(bool deserializing) : base(deserializing) { }
327
328    public MDCVRPPDTWEvaluator() {
329      Parameters.Add(new LookupParameter<IntValue>("PickupViolations", "The number of pickup violations."));
330    }
331
332    public override IDeepCloneable Clone(Cloner cloner) {
333      return new MDCVRPPDTWEvaluator(this, cloner);
334    }
335
336    protected MDCVRPPDTWEvaluator(MDCVRPPDTWEvaluator original, Cloner cloner)
337      : base(original, cloner) {
338    }
339  }
340}
Note: See TracBrowser for help on using the repository browser.