Free cookie consent management tool by TermsFeed Policy Generator

source: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPTWEvaluator.cs @ 7958

Last change on this file since 7958 was 7276, checked in by svonolfe, 13 years ago

Improved incremental evaluation (#1177)

File size: 10.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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 System.Linq;
25using System.Text;
26using HeuristicLab.Problems.VehicleRouting.Interfaces;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28using HeuristicLab.Core;
29using HeuristicLab.Parameters;
30using HeuristicLab.Data;
31using HeuristicLab.Optimization;
32using HeuristicLab.PluginInfrastructure;
33using HeuristicLab.Problems.VehicleRouting.Variants;
34using HeuristicLab.Problems.VehicleRouting.Encodings;
35using HeuristicLab.Common;
36
37namespace HeuristicLab.Problems.VehicleRouting.ProblemInstances {
38  [Item("MDCVRPTWEvaluator", "Represents a multi depot CVRPTW evaluator.")]
39  [StorableClass]
40  public class MDCVRPTWEvaluator: MDCVRPEvaluator {
41    public ILookupParameter<DoubleValue> TardinessParameter {
42      get { return (ILookupParameter<DoubleValue>)Parameters["Tardiness"]; }
43    }
44
45    public ILookupParameter<DoubleValue> TravelTimeParameter {
46      get { return (ILookupParameter<DoubleValue>)Parameters["TravelTime"]; }
47    }
48
49    protected override VRPEvaluation CreateTourEvaluation() {
50      return new CVRPTWEvaluation();
51    }
52
53    protected override void EvaluateTour(VRPEvaluation eval, IVRPProblemInstance instance, Tour tour, IVRPEncoding solution) {
54      TourInsertionInfo tourInfo = new TourInsertionInfo(solution.GetVehicleAssignment(solution.GetTourIndex(tour)));
55      eval.InsertionInfo.AddTourInsertionInfo(tourInfo);
56      double originalQuality = eval.Quality;
57
58      IHeterogenousCapacitatedProblemInstance cvrpInstance = instance as IHeterogenousCapacitatedProblemInstance;
59      DoubleArray demand = instance.Demand;
60
61      ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
62      DoubleArray dueTime = vrptw.DueTime;
63      DoubleArray readyTime = vrptw.ReadyTime;
64      DoubleArray serviceTimes = vrptw.ServiceTime;
65
66      IMultiDepotProblemInstance mdp = instance as IMultiDepotProblemInstance;
67      IntArray vehicleAssignment = mdp.VehicleDepotAssignment;
68      int depots = mdp.Depots.Value;
69
70      double time = 0.0;
71      double waitingTime = 0.0;
72      double serviceTime = 0.0;
73      double tardiness = 0.0;
74      double delivered = 0.0;
75      double overweight = 0.0;
76      double distance = 0.0;
77
78      int tourIndex = solution.GetTourIndex(tour);
79      int vehicle = solution.GetVehicleAssignment(tourIndex);
80      int depot = vehicleAssignment[vehicle];
81
82      double capacity = cvrpInstance.Capacity[vehicle];
83      for (int i = 0; i < tour.Stops.Count; i++) {
84        delivered += instance.GetDemand(tour.Stops[i]);
85      }
86
87      double spareCapacity = capacity - delivered;
88
89      double tourStartTime = vrptw.ReadyTime[depot];
90      time = tourStartTime;
91
92      //simulate a tour, start and end at depot
93      for (int i = 0; i <= tour.Stops.Count; i++) {
94        int start = 0;
95        if (i > 0)
96          start = tour.Stops[i - 1];
97        int end = 0;
98        if (i < tour.Stops.Count)
99          end = tour.Stops[i];
100
101        //drive there
102        double currentDistace = vrptw.GetDistance(start, end, solution);
103        time += currentDistace;
104        distance += currentDistace;
105
106        double arrivalTime = time;
107
108        int endIndex;
109        if (end == 0)
110          endIndex = depot;
111        else
112          endIndex = end + depots - 1;
113
114        //check if it was serviced on time
115        if (time > dueTime[endIndex])
116          tardiness += time - dueTime[endIndex];
117
118        //wait
119        double currentWaitingTime = 0.0;
120        if (time < readyTime[endIndex])
121          currentWaitingTime = readyTime[endIndex] - time;
122
123        double waitTime = readyTime[endIndex] - time;
124
125        waitingTime += currentWaitingTime;
126        time += currentWaitingTime;
127
128        double spareTime = dueTime[endIndex] - time;
129
130        //service
131        double currentServiceTime = 0;
132        if(end > 0)
133          currentServiceTime = serviceTimes[end - 1];
134        serviceTime += currentServiceTime;
135        time += currentServiceTime;
136
137        CVRPTWInsertionInfo stopInfo = new CVRPTWInsertionInfo(start, end, spareCapacity, tourStartTime, arrivalTime, time, spareTime, waitTime);
138        tourInfo.AddStopInsertionInfo(stopInfo);
139      }
140
141      eval.Quality += instance.FleetUsageFactor.Value;
142      eval.Quality += instance.DistanceFactor.Value * distance;
143      eval.Distance += distance;
144      eval.VehicleUtilization += 1;
145
146      if (delivered > capacity) {
147        overweight = delivered - capacity;
148      }
149
150      (eval as CVRPEvaluation).Overload += overweight;
151      double tourPenalty = 0;
152      double penalty = overweight * cvrpInstance.OverloadPenalty.Value;
153      eval.Penalty += penalty;
154      eval.Quality += penalty;
155      tourPenalty += penalty;
156
157      (eval as CVRPTWEvaluation).Tardiness += tardiness;
158      (eval as CVRPTWEvaluation).TravelTime += time;
159
160      penalty = tardiness * vrptw.TardinessPenalty.Value;
161      eval.Penalty += penalty;
162      eval.Quality += penalty;
163      tourPenalty += penalty;
164      eval.Quality += time * vrptw.TimeFactor.Value;
165      tourInfo.Penalty = tourPenalty;
166      tourInfo.Quality = eval.Quality - originalQuality;
167    }
168
169    protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer,
170      out bool feasible) {
171      CVRPTWInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo;
172
173      double costs = 0;
174      feasible = tourInsertionInfo.Penalty < double.Epsilon;
175
176      ICapacitatedProblemInstance cvrp = instance as ICapacitatedProblemInstance;
177      double overloadPenalty = cvrp.OverloadPenalty.Value;
178
179      ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
180      DoubleArray dueTime = vrptw.DueTime;
181      DoubleArray readyTime = vrptw.ReadyTime;
182      DoubleArray serviceTimes = vrptw.ServiceTime;
183      double tardinessPenalty = vrptw.TardinessPenalty.Value;
184
185      IMultiDepotProblemInstance mdp = instance as IMultiDepotProblemInstance;
186      int depots = mdp.Depots.Value;
187
188      double startDistance, endDistance;
189      costs += instance.GetInsertionDistance(insertionInfo.Start, customer, insertionInfo.End, solution, out startDistance, out endDistance);
190
191      double demand = instance.GetDemand(customer);
192      if (demand > insertionInfo.SpareCapacity) {
193        feasible = false;
194
195        if(insertionInfo.SpareCapacity >= 0)
196          costs += (demand - insertionInfo.SpareCapacity) * overloadPenalty;
197        else
198          costs += demand * overloadPenalty;
199      }
200
201      double time = 0;
202      double tardiness = 0;
203
204      if (index > 0)
205        time = (tourInsertionInfo.GetStopInsertionInfo(index - 1) as CVRPTWInsertionInfo).LeaveTime;
206      else
207        time = insertionInfo.TourStartTime;
208
209      time += startDistance;
210
211      int customerIndex = customer + depots - 1;
212
213      if (time > dueTime[customerIndex]) {
214        tardiness += time - dueTime[customerIndex];
215      }
216      if (time < readyTime[customerIndex])
217        time += readyTime[customerIndex] - time;
218      time += serviceTimes[customer - 1];
219      time += endDistance;
220
221      double additionalTime = time - (tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo).ArrivalTime;
222      for (int i = index; i < tourInsertionInfo.GetStopCount(); i++) {
223        CVRPTWInsertionInfo nextStop = tourInsertionInfo.GetStopInsertionInfo(i) as CVRPTWInsertionInfo;
224
225        if (additionalTime < 0) {
226          //arrive earlier than before
227          //wait probably
228          if (nextStop.WaitingTime < 0) {
229            double wait = nextStop.WaitingTime - additionalTime;
230            if (wait > 0)
231              additionalTime += wait;
232          } else {
233            additionalTime = 0;
234          }
235
236          //check due date, decrease tardiness
237          if (nextStop.SpareTime < 0) {
238            costs += Math.Max(nextStop.SpareTime, additionalTime) * tardinessPenalty;
239          }
240        } else {
241          //arrive later than before, probably don't have to wait
242          if (nextStop.WaitingTime > 0) {
243            additionalTime -= Math.Min(additionalTime, nextStop.WaitingTime);           
244          }
245
246          //check due date
247          if (nextStop.SpareTime > 0) {
248            double spare = nextStop.SpareTime - additionalTime;
249            if (spare < 0)
250              tardiness += -spare;
251          } else {
252            tardiness += additionalTime;
253          }
254        }
255      }
256
257      costs += additionalTime * vrptw.TimeFactor.Value;
258
259      if (tardiness > 0) {
260        feasible = false;
261      }
262
263      costs += tardiness * tardinessPenalty;
264
265      return costs;
266    }
267
268    protected override void InitResultParameters() {
269      base.InitResultParameters();
270
271      TardinessParameter.ActualValue = new DoubleValue(0);
272      TravelTimeParameter.ActualValue = new DoubleValue(0);
273    }
274
275    protected override void SetResultParameters(VRPEvaluation tourEvaluation) {
276      base.SetResultParameters(tourEvaluation);
277
278      TardinessParameter.ActualValue.Value = (tourEvaluation as CVRPTWEvaluation).Tardiness;
279      TravelTimeParameter.ActualValue.Value = (tourEvaluation as CVRPTWEvaluation).TravelTime;
280    }
281   
282    [StorableConstructor]
283    protected MDCVRPTWEvaluator(bool deserializing) : base(deserializing) { }
284
285    public MDCVRPTWEvaluator() {
286      Parameters.Add(new LookupParameter<DoubleValue>("Tardiness", "The tardiness."));
287      Parameters.Add(new LookupParameter<DoubleValue>("TravelTime", "The travel time."));
288    }
289
290    public override IDeepCloneable Clone(Cloner cloner) {
291      return new MDCVRPTWEvaluator(this, cloner);
292    }
293
294    protected MDCVRPTWEvaluator(MDCVRPTWEvaluator original, Cloner cloner)
295      : base(original, cloner) {
296    }
297  }
298}
Note: See TracBrowser for help on using the repository browser.