using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; using HeuristicLab.PDPSimulation.Operators; using HeuristicLab.Problems.VehicleRouting; using HeuristicLab.Problems.VehicleRouting.Interfaces; using HeuristicLab.Parameters; using HeuristicLab.Data; namespace HeuristicLab.PDPSimulation { [Item("WaitFirstWaitingStrategy", "A pickup and delivery waiting strategy.")] [StorableClass] public class WaitFirstWaitingStrategy : WaitingStrategy { protected ValueParameter OnlyFirstStopParameter { get { return (ValueParameter)Parameters["OnlyFirstStop"]; } } public WaitFirstWaitingStrategy() : base() { Parameters.Add(new ValueParameter("OnlyFirstStop", "Indicates, if waiting should only occur at the first stop.", new BoolValue(false))); } [StorableConstructor] protected WaitFirstWaitingStrategy(bool deserializing) : base(deserializing) { } protected WaitFirstWaitingStrategy(WaitFirstWaitingStrategy original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new WaitFirstWaitingStrategy(this, cloner); } public static double GetSlack(double time, DynPDPProblemInstance instance, IVRPEncoding solution, Tour tour, int stop) { double slack = 0; double minBuffer = double.MaxValue; int count = tour.Stops.Count; if (!(instance as DynPDPProblemInstance).RelocateBackToDepot) count -= 1; for (int i = stop; i <= count; i++) { int customer = 0; if (i < tour.Stops.Count) customer = tour.Stops[i]; int prev = 0; if (i > 0) prev = tour.Stops[i - 1]; int depots = instance.Depots.Value; double distance = instance.GetDistance(prev, customer, solution); time += distance; double arrivalTime = time; double deadline = 0; if (customer > 0) { double readyTime = instance.ReadyTime[customer + depots - 1]; if (time < readyTime) { slack += readyTime - time; time = readyTime; arrivalTime = time; } double serviceTime = instance.ServiceTime[customer - 1]; time += serviceTime; deadline = instance.DueTime[customer + depots - 1]; } else { int depot = instance.GetDepot(prev, solution); deadline = instance.DueTime[depot]; } double buffer = Math.Max(0, Math.Max(slack, deadline - arrivalTime + slack)); if (buffer < minBuffer) minBuffer = buffer; } return Math.Floor(minBuffer * 100) / 100; } public override double GetWaitingTime(double time, DynPDPProblemInstance instance, IVRPEncoding solution, Tour tour, int stop) { bool onlyFirstStop = OnlyFirstStopParameter.Value.Value; int vehicle = solution.GetVehicleAssignment(solution.GetTourIndex(tour)); bool moving = instance.VehicleStates[vehicle] == DomainModel.VehicleState.Moving; if (onlyFirstStop) { if ((!moving && stop != 0) || (moving && stop != 1)) return 0; } else { if (moving && stop == 0) return 0; } return GetSlack(time, instance, solution, tour, stop); } } }