[8747] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
[8760] | 3 | using System.Diagnostics;
|
---|
[8747] | 4 | using System.Linq;
|
---|
| 5 | using HeuristicLab.Common;
|
---|
| 6 | using HeuristicLab.Core;
|
---|
[8760] | 7 | using HeuristicLab.Encodings.RealVectorEncoding;
|
---|
| 8 | using HeuristicLab.Parameters;
|
---|
[8747] | 9 | using HeuristicLab.PDPSimulation.DomainModel;
|
---|
[8760] | 10 | using HeuristicLab.PDPSimulation.Operators;
|
---|
[8747] | 11 | using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
|
---|
| 12 |
|
---|
| 13 | namespace HeuristicLab.PDPSimulation {
|
---|
| 14 | [Item("PriorityDispatching", "")]
|
---|
| 15 | [StorableClass]
|
---|
[8813] | 16 | public abstract class PriorityDispatching : Dispatching {
|
---|
[8747] | 17 | [StorableConstructor]
|
---|
[8808] | 18 | protected PriorityDispatching(bool deserializing) : base(deserializing) { }
|
---|
| 19 | protected PriorityDispatching(PriorityDispatching original, Cloner cloner) : base(original, cloner) { }
|
---|
| 20 | protected PriorityDispatching() {
|
---|
[8747] | 21 | }
|
---|
| 22 |
|
---|
[8808] | 23 | protected abstract double CalculatePriority(IDictionary<string, double> variables);
|
---|
| 24 |
|
---|
[8813] | 25 | protected override void GetHighestPriorityOrder(DynPDPProblemInstance instance, Vehicle vehicle, IEnumerable<Order> orders, out Order order, out double priority) {
|
---|
[8760] | 26 | Order best = null;
|
---|
| 27 | double bestPriority = double.MinValue;
|
---|
| 28 | var pickupOrdersByLocation = (from o in orders
|
---|
| 29 | where IsPickup(o, instance)
|
---|
| 30 | group o by new { X = o.PickupXCoord, Y = o.PickupYCoord })
|
---|
| 31 | .ToDictionary(x => new XY(x.Key.X, x.Key.Y), y => y.ToArray(), new XYEqComparer());
|
---|
| 32 | var deliveryOrdersByLocation = (from o in orders
|
---|
[8782] | 33 | where !IsPickup(o, instance) && o.Vehicle == vehicle.Id
|
---|
[8760] | 34 | group o by new { X = o.DeliveryXCoord, Y = o.DeliveryYCoord })
|
---|
| 35 | .ToDictionary(x => new XY(x.Key.X, x.Key.Y), y => y.ToArray(), new XYEqComparer());
|
---|
[8782] | 36 | var destinations = deliveryOrdersByLocation.Keys.ToArray();
|
---|
[8760] | 37 | foreach (var o in orders) {
|
---|
| 38 | if (IsPickup(o, instance) && o.Demand > vehicle.Capacity) continue;
|
---|
| 39 |
|
---|
[8782] | 40 | double prio;
|
---|
| 41 | if (!IsPickup(o, instance) && vehicle.TargetPositionX == o.DeliveryXCoord && vehicle.TargetPositionY == o.DeliveryYCoord) {
|
---|
| 42 | prio = double.MaxValue;
|
---|
| 43 | } else {
|
---|
| 44 | var target = new XY(o.PickupXCoord, o.PickupYCoord);
|
---|
| 45 | if (!IsPickup(o, instance)) target = new XY(o.DeliveryXCoord, o.DeliveryYCoord);
|
---|
[8747] | 46 |
|
---|
[8787] | 47 | var destinationDifference = destinations.Select(x => scenario.DistanceMeasure.GetDistance(target.X, target.Y, x.X, x.Y)).ToArray();
|
---|
[8782] | 48 | var courierDifference = GetVehicles().Where(x => x != vehicle).Select(x => new XY(x.TargetPositionX, x.TargetPositionY))
|
---|
| 49 | .Select(x => scenario.DistanceMeasure.GetDistance(target.X, target.Y, x.X, x.Y)).ToArray();
|
---|
[8747] | 50 |
|
---|
[8782] | 51 | var commonDestinations = orders.Where(x => !IsPickup(x, instance) && x.Vehicle == vehicle.Id &&
|
---|
| 52 | x.DeliveryXCoord == o.PickupXCoord &&
|
---|
| 53 | x.DeliveryYCoord == o.PickupYCoord);
|
---|
[8760] | 54 |
|
---|
[8782] | 55 | var variables = new Dictionary<string, double>();
|
---|
| 56 | variables.Add("Distance", scenario.DistanceMeasure.GetDistance(vehicle.TargetPositionX, vehicle.TargetPositionY, target.X, target.Y));
|
---|
| 57 | variables.Add("EarliestTimeOfArrival", vehicle.ReadyTime + variables["Distance"]);
|
---|
| 58 | variables.Add("DueDate", o.DeliveryDueTime - GetSimulationTime());
|
---|
| 59 | variables.Add("StartDate", IsPickup(o, instance) ? o.PickupReadyTime - GetSimulationTime() : 0);
|
---|
| 60 | variables.Add("PickupOrdersAtTarget", pickupOrdersByLocation.ContainsKey(target) ? pickupOrdersByLocation[target].Count() : 0);
|
---|
| 61 | variables.Add("PickupOrderItemsAtTarget", pickupOrdersByLocation.ContainsKey(target) ? pickupOrdersByLocation[target].Sum(x => x.Demand) : 0);
|
---|
| 62 | variables.Add("DeliveryOrdersAtTarget", deliveryOrdersByLocation.ContainsKey(target) ? deliveryOrdersByLocation[target].Count() : 0);
|
---|
| 63 | variables.Add("DeliveryOrderItemsAtTarget", deliveryOrdersByLocation.ContainsKey(target) ? deliveryOrdersByLocation[target].Sum(x => x.Demand) : 0);
|
---|
| 64 | variables.Add("AverageDistanceToDestinations", destinationDifference.Any() ? destinationDifference.Average() : 0);
|
---|
| 65 | variables.Add("MinimumDistanceToDestinations", destinationDifference.Any() ? destinationDifference.Min() : 0);
|
---|
| 66 | variables.Add("MaximumDistanceToDestinations", destinationDifference.Any() ? destinationDifference.Max() : 0);
|
---|
| 67 | variables.Add("NumberOfOtherCouriersToTarget", GetVehicles().Count > 2 ? GetVehicles().Where(x => x != vehicle).Count(x => target.X == x.TargetPositionX && target.Y == x.TargetPositionY) : 0);
|
---|
| 68 | variables.Add("AverageDistanceToOtherCouriers", courierDifference.Any() ? courierDifference.Average() : 0);
|
---|
| 69 | variables.Add("MinimumDistanceToOtherCouriers", courierDifference.Any() ? courierDifference.Min() : 0);
|
---|
| 70 | variables.Add("MaximumDistanceToOtherCouriers", courierDifference.Any() ? courierDifference.Max() : 0);
|
---|
| 71 | variables.Add("DemandSize", o.Demand);
|
---|
[8787] | 72 | variables.Add("EDD", commonDestinations.Any() ? commonDestinations.Min(d => d.DeliveryDueTime
|
---|
| 73 | - scenario.DistanceMeasure.GetDistance(vehicle.TargetPositionX, vehicle.TargetPositionY, d.DeliveryXCoord, d.DeliveryYCoord)
|
---|
| 74 | - GetSimulationTime()) : 0);
|
---|
| 75 | variables.Add("LeadTime", o.PickupReadyTime - GetSimulationTime());
|
---|
[8760] | 76 |
|
---|
[8808] | 77 | prio = CalculatePriority(variables);
|
---|
[8782] | 78 | }
|
---|
| 79 |
|
---|
[8760] | 80 | if (prio > bestPriority) {
|
---|
| 81 | bestPriority = prio;
|
---|
| 82 | best = o;
|
---|
[8747] | 83 | }
|
---|
| 84 | }
|
---|
| 85 |
|
---|
[8760] | 86 | order = best != null ? best : orders.First();
|
---|
| 87 | priority = bestPriority;
|
---|
| 88 | }
|
---|
[8747] | 89 | }
|
---|
| 90 | }
|
---|