public override IOperation Apply() { ICapacitatedProblemInstance cvrp = ProblemInstanceParameter.ActualValue as ICapacitatedProblemInstance; ResultCollection results = ResultsParameter.ActualValue; ItemArray <DoubleValue> qualities = QualityParameter.ActualValue; ItemArray <DoubleValue> overloads = OverloadParameter.ActualValue; double sigma = SigmaParameter.Value.Value; double phi = PhiParameter.Value.Value; double minPenalty = MinPenaltyFactorParameter.Value.Value; double maxPenalty = MaxPenaltyFactorParameter.Value.Value; for (int j = 0; j < qualities.Length; j++) { qualities[j].Value -= overloads[j].Value * cvrp.OverloadPenalty.Value; } int validCount = 0; for (int j = 0; j < qualities.Length; j++) { if (overloads[j].Value == 0) { validCount++; } } double factor = 1.0 - ((double)validCount / (double)qualities.Length); double min = cvrp.OverloadPenalty.Value / (1 + sigma); double max = cvrp.OverloadPenalty.Value * (1 + phi); cvrp.CurrentOverloadPenalty = new DoubleValue(min + (max - min) * factor); if (cvrp.CurrentOverloadPenalty.Value < minPenalty) { cvrp.CurrentOverloadPenalty.Value = minPenalty; } if (cvrp.CurrentOverloadPenalty.Value > maxPenalty) { cvrp.CurrentOverloadPenalty.Value = maxPenalty; } for (int j = 0; j < qualities.Length; j++) { qualities[j].Value += overloads[j].Value * cvrp.CurrentOverloadPenalty.Value; } if (!results.ContainsKey("Current Overload Penalty")) { results.Add(new Result("Current Overload Penalty", new DoubleValue(cvrp.CurrentOverloadPenalty.Value))); } else { (results["Current Overload Penalty"].Value as DoubleValue).Value = cvrp.CurrentOverloadPenalty.Value; } return(base.Apply()); }
protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer, out bool feasible) { CVRPInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index) as CVRPInsertionInfo; double costs = 0; feasible = tourInsertionInfo.Penalty < double.Epsilon; ICapacitatedProblemInstance cvrp = instance as ICapacitatedProblemInstance; double overloadPenalty = cvrp.OverloadPenalty.Value; double distance = instance.GetDistance(insertionInfo.Start, insertionInfo.End, solution); double newDistance = instance.GetDistance(insertionInfo.Start, customer, solution) + instance.GetDistance(customer, insertionInfo.End, solution); costs += instance.DistanceFactor.Value * (newDistance - distance); double demand = instance.Demand[customer]; if (demand > insertionInfo.SpareCapacity) { feasible = false; if (insertionInfo.SpareCapacity >= 0) { costs += (demand - insertionInfo.SpareCapacity) * overloadPenalty; } else { costs += demand * overloadPenalty; } } return(costs); }
protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer, out bool feasible) { CVRPPDTWInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index) as CVRPPDTWInsertionInfo; double costs = 0; feasible = tourInsertionInfo.Penalty < double.Epsilon; bool tourFeasible = true; ICapacitatedProblemInstance cvrp = instance as ICapacitatedProblemInstance; double overloadPenalty = cvrp.OverloadPenalty.Value; ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance; DoubleArray dueTime = vrptw.DueTime; DoubleArray readyTime = vrptw.ReadyTime; DoubleArray serviceTimes = vrptw.ServiceTime; double tardinessPenalty = vrptw.TardinessPenalty.Value; IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; IntArray pickupDeliveryLocation = pdp.PickupDeliveryLocation; double pickupPenalty = pdp.PickupViolationPenalty.Value; double distance = instance.GetDistance(insertionInfo.Start, insertionInfo.End, solution); double newDistance = instance.GetDistance(insertionInfo.Start, customer, solution) + instance.GetDistance(customer, insertionInfo.End, solution); costs += instance.DistanceFactor.Value * (newDistance - distance); double demand = instance.Demand[customer]; if (demand > insertionInfo.ArrivalSpareCapacity) { tourFeasible = feasible = false; if (insertionInfo.ArrivalSpareCapacity >= 0) { costs += (demand - insertionInfo.ArrivalSpareCapacity) * overloadPenalty; } else { costs += demand * overloadPenalty; } } int destination = pickupDeliveryLocation[customer]; bool validPickup = true; if (demand < 0 && !insertionInfo.Visited.Contains(destination)) { tourFeasible = feasible = false; validPickup = false; costs += pickupPenalty; } double time = 0; double tardiness = 0; if (index > 0) { time = (tourInsertionInfo.GetStopInsertionInfo(index - 1) as CVRPTWInsertionInfo).LeaveTime; } else { time = insertionInfo.TourStartTime; } time += instance.GetDistance(insertionInfo.Start, customer, solution); if (time > dueTime[customer]) { tardiness += time - dueTime[customer]; } if (time < readyTime[customer]) { time += readyTime[customer] - time; } time += serviceTimes[customer]; time += instance.GetDistance(customer, insertionInfo.End, solution); double additionalTime = time - (tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo).ArrivalTime; for (int i = index; i < tourInsertionInfo.GetStopCount(); i++) { CVRPTWInsertionInfo nextStop = tourInsertionInfo.GetStopInsertionInfo(i) as CVRPTWInsertionInfo; if (demand >= 0) { if (nextStop.End == destination) { demand = 0; costs -= pickupPenalty; if (tourInsertionInfo.Penalty == pickupPenalty && tourFeasible) { feasible = true; } } else if (nextStop.SpareCapacity < 0) { costs += demand * overloadPenalty; } else if (nextStop.SpareCapacity < demand) { tourFeasible = feasible = false; costs += (demand - nextStop.SpareCapacity) * overloadPenalty; } } else if (validPickup) { if (nextStop.SpareCapacity < 0) { costs += Math.Max(demand, nextStop.SpareCapacity) * overloadPenalty; } } if (additionalTime < 0) { //arrive earlier than before //wait probably if (nextStop.WaitingTime < 0) { double wait = nextStop.WaitingTime - additionalTime; if (wait > 0) { additionalTime += wait; } } else { additionalTime = 0; } //check due date, decrease tardiness if (nextStop.SpareTime < 0) { costs += Math.Max(nextStop.SpareTime, additionalTime) * tardinessPenalty; } } else { //arrive later than before, probably don't have to wait if (nextStop.WaitingTime > 0) { additionalTime -= Math.Min(additionalTime, nextStop.WaitingTime); } //check due date if (nextStop.SpareTime > 0) { double spare = nextStop.SpareTime - additionalTime; if (spare < 0) { tardiness += -spare; } } else { tardiness += additionalTime; } } } costs += additionalTime * vrptw.TimeFactor.Value; if (tardiness > 0) { tourFeasible = feasible = false; } costs += tardiness * tardinessPenalty; return(costs); }
protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer, out bool feasible) { CVRPTWInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo; double costs = 0; feasible = tourInsertionInfo.Penalty < double.Epsilon; ICapacitatedProblemInstance cvrp = instance as ICapacitatedProblemInstance; double overloadPenalty = cvrp.OverloadPenalty.Value; ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance; DoubleArray dueTime = vrptw.DueTime; DoubleArray readyTime = vrptw.ReadyTime; DoubleArray serviceTimes = vrptw.ServiceTime; double tardinessPenalty = vrptw.TardinessPenalty.Value; IMultiDepotProblemInstance mdp = instance as IMultiDepotProblemInstance; int depots = mdp.Depots.Value; double startDistance, endDistance; costs += instance.GetInsertionDistance(insertionInfo.Start, customer, insertionInfo.End, solution, out startDistance, out endDistance); double demand = instance.GetDemand(customer); if (demand > insertionInfo.SpareCapacity) { feasible = false; if (insertionInfo.SpareCapacity >= 0) { costs += (demand - insertionInfo.SpareCapacity) * overloadPenalty; } else { costs += demand * overloadPenalty; } } double time = 0; double tardiness = 0; if (index > 0) { time = (tourInsertionInfo.GetStopInsertionInfo(index - 1) as CVRPTWInsertionInfo).LeaveTime; } else { time = insertionInfo.TourStartTime; } time += startDistance; int customerIndex = customer + depots - 1; if (time > dueTime[customerIndex]) { tardiness += time - dueTime[customerIndex]; } if (time < readyTime[customerIndex]) { time += readyTime[customerIndex] - time; } time += serviceTimes[customer - 1]; time += endDistance; double additionalTime = time - (tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo).ArrivalTime; for (int i = index; i < tourInsertionInfo.GetStopCount(); i++) { CVRPTWInsertionInfo nextStop = tourInsertionInfo.GetStopInsertionInfo(i) as CVRPTWInsertionInfo; if (additionalTime < 0) { //arrive earlier than before //wait probably if (nextStop.WaitingTime < 0) { double wait = nextStop.WaitingTime - additionalTime; if (wait > 0) { additionalTime += wait; } } else { additionalTime = 0; } //check due date, decrease tardiness if (nextStop.SpareTime < 0) { costs += Math.Max(nextStop.SpareTime, additionalTime) * tardinessPenalty; } } else { //arrive later than before, probably don't have to wait if (nextStop.WaitingTime > 0) { additionalTime -= Math.Min(additionalTime, nextStop.WaitingTime); } //check due date if (nextStop.SpareTime > 0) { double spare = nextStop.SpareTime - additionalTime; if (spare < 0) { tardiness += -spare; } } else { tardiness += additionalTime; } } } costs += additionalTime * vrptw.TimeFactor.Value; if (tardiness > 0) { feasible = false; } costs += tardiness * tardinessPenalty; return(costs); }