Exemplo n.º 1
0
        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;

            IHeterogenousCapacitatedProblemInstance cvrp = instance as IHeterogenousCapacitatedProblemInstance;
            double overloadPenalty = cvrp.OverloadPenalty.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;
                }
            }

            return(costs);
        }
    protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer,
      out bool feasible) {
      StopInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index);

      double costs = 0;
      feasible = true;
      double startDistance, endDistance;

      costs += instance.GetInsertionDistance(insertionInfo.Start, customer, insertionInfo.End, solution, out startDistance, out endDistance);

      return costs;
    }
Exemplo n.º 3
0
        protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer,
                                                        out bool feasible)
        {
            StopInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index);

            double costs = 0;

            feasible = true;
            double startDistance, endDistance;

            costs += instance.GetInsertionDistance(insertionInfo.Start, customer, insertionInfo.End, solution, out startDistance, out endDistance);

            return(costs);
        }
Exemplo n.º 4
0
    protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer,
      out bool feasible) {
      StopInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index);

      double costs = 0;
      feasible = true;

      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);

      return costs;
    }
Exemplo n.º 5
0
        protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer,
                                                        out bool feasible)
        {
            StopInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index);

            double costs = 0;

            feasible = true;

            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);

            return(costs);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 8
0
    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;
    }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
    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;
    }
Exemplo n.º 11
0
    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;

      IHeterogenousCapacitatedProblemInstance cvrp = instance as IHeterogenousCapacitatedProblemInstance;
      double overloadPenalty = cvrp.OverloadPenalty.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;
      }

      return costs;
    }
Exemplo n.º 12
0
    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;
    }