Beispiel #1
0
        public static PotvinPDRearrangeMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand)
        {
            List <int> cities = new List <int>();

            IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;

            for (int i = 1; i <= individual.Cities; i++)
            {
                if (pdp == null || pdp.GetDemand(i) >= 0)
                {
                    cities.Add(i);
                }
            }

            if (cities.Count > 0)
            {
                int city = cities[rand.Next(cities.Count)];
                int tour = individual.Tours.FindIndex(t => t.Stops.Contains(city));
                return(new PotvinPDRearrangeMove(city, tour, individual));
            }
            else
            {
                return(null);
            }
        }
Beispiel #2
0
        public static void Apply(PotvinEncoding solution, PotvinPDRearrangeMove move, IVRPProblemInstance problemInstance)
        {
            Tour tour     = solution.Tours[move.Tour];
            int  position = tour.Stops.IndexOf(move.City);

            IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;

            if (pdp != null)
            {
                int  location  = pdp.GetPickupDeliveryLocation(move.City);
                Tour tour2     = solution.Tours.Find(t => t.Stops.Contains(location));
                int  position2 = tour2.Stops.IndexOf(location);

                tour.Stops.Remove(move.City);
                tour2.Stops.Remove(location);

                solution.InsertPair(tour, move.City, location, problemInstance, position, position2);
            }
            else
            {
                tour.Stops.Remove(move.City);
                int place = solution.FindBestInsertionPlace(tour, move.City, position);
                tour.Stops.Insert(place, move.City);
            }

            solution.Repair();
        }
        protected override PotvinPDShiftMove[] GenerateMoves(PotvinEncoding individual, IVRPProblemInstance problemInstance)
        {
            List <PotvinPDShiftMove>          result = new List <PotvinPDShiftMove>();
            IPickupAndDeliveryProblemInstance pdp    = problemInstance as IPickupAndDeliveryProblemInstance;

            int max = individual.Tours.Count;

            if (individual.Tours.Count >= problemInstance.Vehicles.Value)
            {
                max = max - 1;
            }

            for (int i = 0; i < individual.Tours.Count; i++)
            {
                for (int j = 0; j < individual.Tours[i].Stops.Count; j++)
                {
                    for (int k = 0; k <= max; k++)
                    {
                        if (k != i)
                        {
                            int city = individual.Tours[i].Stops[j];
                            if (pdp == null || pdp.GetDemand(city) >= 0)
                            {
                                PotvinPDShiftMove move = new PotvinPDShiftMove(
                                    city, i, k, individual);

                                result.Add(move);
                            }
                        }
                    }
                }
            }

            return(result.ToArray());
        }
        public static PotvinPDExchangeMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand)
        {
            List <int> cities = new List <int>();

            IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;

            for (int i = 1; i <= individual.Cities; i++)
            {
                if (pdp == null || pdp.GetDemand(i) >= 0)
                {
                    cities.Add(i);
                }
            }

            if (cities.Count > 1 && individual.Tours.Count > 1)
            {
                PotvinPDExchangeMove move = null;
                while (cities.Count > 1 && move == null)
                {
                    int  city         = cities[rand.Next(cities.Count)];
                    Tour oldTour      = individual.Tours.Find(t => t.Stops.Contains(city));
                    int  oldTourIndex = individual.Tours.IndexOf(oldTour);

                    int max = individual.Tours.Count - 1;

                    int newTourIndex = rand.Next(max);
                    if (newTourIndex >= oldTourIndex)
                    {
                        newTourIndex++;
                    }

                    Tour       newTour    = individual.Tours[newTourIndex];
                    List <int> tourCities = new List <int>();
                    foreach (int stop in newTour.Stops)
                    {
                        if (pdp == null ||
                            (pdp.GetDemand(stop) >= 0 &&
                             pdp.GetPickupDeliveryLocation(stop) != pdp.GetPickupDeliveryLocation(city) &&
                             pdp.GetPickupDeliveryLocation(stop) != city &&
                             pdp.GetPickupDeliveryLocation(city) != stop))
                        {
                            tourCities.Add(stop);
                        }
                    }

                    if (tourCities.Count > 0)
                    {
                        int replaced = tourCities[rand.Next(tourCities.Count)];
                        move = new PotvinPDExchangeMove(city, oldTourIndex, newTourIndex, replaced, individual);
                    }
                }

                return(move);
            }
            else
            {
                return(null);
            }
        }
Beispiel #5
0
        public override IOperation Apply()
        {
            IPickupAndDeliveryProblemInstance pdp = ProblemInstanceParameter.ActualValue as IPickupAndDeliveryProblemInstance;
            ResultCollection results = ResultsParameter.ActualValue;

            ItemArray <DoubleValue> qualities        = QualityParameter.ActualValue;
            ItemArray <IntValue>    pickupViolations = PickupViolationsParameter.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 -= pickupViolations[j].Value * pdp.PickupViolationPenalty.Value;
            }

            int validCount = 0;

            for (int j = 0; j < qualities.Length; j++)
            {
                if (pickupViolations[j].Value == 0)
                {
                    validCount++;
                }
            }

            double factor = 1.0 - ((double)validCount / (double)qualities.Length);

            double min = pdp.PickupViolationPenalty.Value / (1 + sigma);
            double max = pdp.PickupViolationPenalty.Value * (1 + phi);

            pdp.CurrentPickupViolationPenalty = new DoubleValue(min + (max - min) * factor);
            if (pdp.CurrentPickupViolationPenalty.Value < minPenalty)
            {
                pdp.CurrentPickupViolationPenalty.Value = minPenalty;
            }
            if (pdp.CurrentPickupViolationPenalty.Value > maxPenalty)
            {
                pdp.CurrentPickupViolationPenalty.Value = maxPenalty;
            }

            for (int j = 0; j < qualities.Length; j++)
            {
                qualities[j].Value += pickupViolations[j].Value * pdp.CurrentPickupViolationPenalty.Value;
            }

            if (!results.ContainsKey("Current Pickup Violation Penalty"))
            {
                results.Add(new Result("Current Pickup Violation Penalty", new DoubleValue(pdp.CurrentPickupViolationPenalty.Value)));
            }
            else
            {
                (results["Current Pickup Violation Penalty"].Value as DoubleValue).Value = pdp.CurrentPickupViolationPenalty.Value;
            }

            return(base.Apply());
        }
        protected override void Manipulate(IRandom random, PotvinEncoding individual)
        {
            bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;

            IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance;

            if (pdp != null)
            {
                ApplyManipulation(random, individual, pdp, allowInfeasible);
            }
        }
Beispiel #7
0
        protected override PotvinPDExchangeMove[] GenerateMoves(PotvinEncoding individual, IVRPProblemInstance problemInstance)
        {
            List <PotvinPDExchangeMove>       result = new List <PotvinPDExchangeMove>();
            IPickupAndDeliveryProblemInstance pdp    = problemInstance as IPickupAndDeliveryProblemInstance;

            int max = individual.Tours.Count;

            if (individual.Tours.Count < problemInstance.Vehicles.Value)
            {
                max = max - 1;
            }

            for (int i = 0; i < individual.Tours.Count; i++)
            {
                for (int j = 0; j < individual.Tours[i].Stops.Count; j++)
                {
                    for (int k = 0; k <= max; k++)
                    {
                        if (k != i)
                        {
                            int city1 = individual.Tours[i].Stops[j];
                            if (pdp == null || pdp.GetDemand(city1) >= 0)
                            {
                                for (int l = 0; l < individual.Tours[k].Stops.Count; l++)
                                {
                                    int city2 = individual.Tours[k].Stops[l];
                                    if (pdp == null || pdp.GetDemand(city2) >= 0)
                                    {
                                        bool valid = pdp == null ||
                                                     (pdp.GetPickupDeliveryLocation(city2) != pdp.GetPickupDeliveryLocation(city1) &&
                                                      pdp.GetPickupDeliveryLocation(city2) != city1 &&
                                                      pdp.GetPickupDeliveryLocation(city1) != city2);

                                        if (valid)
                                        {
                                            PotvinPDExchangeMove move = new PotvinPDExchangeMove(
                                                city1, i, k, city2, individual);

                                            result.Add(move);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(result.ToArray());
        }
Beispiel #8
0
        protected override void Manipulate(IRandom random, PotvinEncoding individual)
        {
            bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
            IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance;

            if (pdp != null)
            {
                PotvinEncoding result = ApplyManipulation(random, individual, pdp, allowInfeasible);
                if (result != null)
                {
                    VRPToursParameter.ActualValue = result;
                }
            }
        }
        protected override PotvinPDRearrangeMove[] GenerateMoves(PotvinEncoding individual, IVRPProblemInstance problemInstance)
        {
            List <PotvinPDRearrangeMove>      result = new List <PotvinPDRearrangeMove>();
            IPickupAndDeliveryProblemInstance pdp    = problemInstance as IPickupAndDeliveryProblemInstance;

            for (int i = 1; i <= problemInstance.Cities.Value; i++)
            {
                if (pdp == null || pdp.GetDemand(i) >= 0)
                {
                    int tour = individual.Tours.FindIndex(t => t.Stops.Contains(i));

                    result.Add(new PotvinPDRearrangeMove(i, tour, individual));
                }
            }

            return(result.ToArray());
        }
        public static void Apply(PotvinEncoding solution, PotvinPDExchangeMove move, IVRPProblemInstance problemInstance)
        {
            if (move.Tour >= solution.Tours.Count)
            {
                solution.Tours.Add(new Tour());
            }
            Tour tour = solution.Tours[move.Tour];

            Tour oldTour = solution.Tours.Find(t => t.Stops.Contains(move.City));

            oldTour.Stops.Remove(move.City);

            if (problemInstance is IPickupAndDeliveryProblemInstance)
            {
                IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;

                int  location = pdp.GetPickupDeliveryLocation(move.City);
                Tour oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location));
                oldTour2.Stops.Remove(location);

                location = pdp.GetPickupDeliveryLocation(move.Replaced);
                oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location));

                oldTour2.Stops.Remove(location);
                tour.Stops.Remove(move.Replaced);

                solution.InsertPair(tour, move.City, pdp.GetPickupDeliveryLocation(move.City), problemInstance);
                solution.InsertPair(oldTour, move.Replaced, pdp.GetPickupDeliveryLocation(move.Replaced), problemInstance);
            }
            else
            {
                tour.Stops.Remove(move.Replaced);

                int place = solution.FindBestInsertionPlace(tour, move.City);
                tour.Stops.Insert(place, move.City);

                place = solution.FindBestInsertionPlace(oldTour, move.Replaced);
                oldTour.Stops.Insert(place, move.Replaced);
            }

            solution.Repair();
        }
        public static PotvinPDShiftMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand)
        {
            List <int> cities = new List <int>();

            IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;

            for (int i = 1; i <= individual.Cities; i++)
            {
                if (pdp == null || pdp.GetDemand(i) >= 0)
                {
                    cities.Add(i);
                }
            }

            if (cities.Count >= 1)
            {
                int  city         = cities[rand.Next(cities.Count)];
                Tour oldTour      = individual.Tours.Find(t => t.Stops.Contains(city));
                int  oldTourIndex = individual.Tours.IndexOf(oldTour);

                int max = individual.Tours.Count;
                if (individual.Tours.Count >= problemInstance.Vehicles.Value)
                {
                    max = max - 1;
                }

                int newTourIndex = rand.Next(max);
                if (newTourIndex >= oldTourIndex)
                {
                    newTourIndex++;
                }

                return(new PotvinPDShiftMove(city, oldTourIndex, newTourIndex, individual));
            }
            else
            {
                return(null);
            }
        }
    public static void ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible) {
      int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp);
      if (selectedIndex >= 0) {
        Tour route1 =
          individual.Tours[selectedIndex];

        int count = route1.Stops.Count;

        if (count > 0) {
          int i = random.Next(0, count);
          int city = route1.Stops[i];

          if (!PairwiseMove(individual, pdp, city, allowInfeasible))
            i++;

          count = route1.Stops.Count;
        }
      }
    }
        public override IOperation Apply()
        {
            ItemList <IItem>      tabuList      = TabuListParameter.ActualValue;
            double                moveQuality   = MoveQualityParameter.ActualValue.Value;
            bool                  useAspiration = UseAspirationCriterion.Value;
            bool                  isTabu        = false;
            PotvinPDRearrangeMove move          = PDRearrangeMoveParameter.ActualValue;

            foreach (IItem tabuMove in tabuList)
            {
                PotvinPDRelocateMoveAttribute attribute = tabuMove as PotvinPDRelocateMoveAttribute;

                if (attribute != null)
                {
                    double distance = 0;
                    if (MoveDistanceParameter.ActualValue != null)
                    {
                        distance = MoveDistanceParameter.ActualValue.Value;
                    }

                    double overload = 0;
                    if (MoveOverloadParameter.ActualValue != null)
                    {
                        overload = MoveOverloadParameter.ActualValue.Value;
                    }

                    double tardiness = 0;
                    if (MoveTardinessParameter.ActualValue != null)
                    {
                        tardiness = MoveTardinessParameter.ActualValue.Value;
                    }

                    IVRPProblemInstance instance = ProblemInstanceParameter.ActualValue;
                    double quality = attribute.Distance * instance.DistanceFactor.Value;

                    IHomogenousCapacitatedProblemInstance cvrp = instance as IHomogenousCapacitatedProblemInstance;
                    if (cvrp != null)
                    {
                        quality += attribute.Overload * cvrp.OverloadPenalty.Value;
                    }

                    ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
                    if (vrptw != null)
                    {
                        quality += attribute.Tardiness * vrptw.TardinessPenalty.Value;
                    }

                    IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
                    if (pdp != null)
                    {
                        quality += attribute.PickupViolations * pdp.PickupViolationPenalty.Value;
                    }

                    if (!useAspiration || moveQuality >= quality)
                    {
                        if (attribute.City == move.City && attribute.Tour == move.Tour)
                        {
                            isTabu = true;
                            break;
                        }

                        if (attribute.Distance == distance && attribute.Overload == overload && attribute.Tardiness == tardiness)
                        {
                            isTabu = true;
                            break;
                        }
                    }
                }
            }

            MoveTabuParameter.ActualValue = new BoolValue(isTabu);
            return(base.Apply());
        }
        public static bool PairwiseMove(PotvinEncoding individual, IVRPProblemInstance instance, int city, bool allowInfeasible)
        {
            bool success;

            IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;

            if (pdp != null)
            {
                Tour route1 = individual.Tours.Find(t => t.Stops.Contains(city));
                int  i      = route1.Stops.IndexOf(city);

                int  dest      = pdp.GetPickupDeliveryLocation(city);
                Tour destRoute = individual.Tours.Find(t => t.Stops.Contains(dest));
                int  j         = destRoute.Stops.IndexOf(dest);

                route1.Stops.Remove(city);
                destRoute.Stops.Remove(dest);

                int routeToAvoid = -1;
                if (route1 == destRoute)
                {
                    routeToAvoid = individual.Tours.IndexOf(route1);
                }

                int source, target;
                if (instance.GetDemand(city) >= 0)
                {
                    source = city;
                    target = dest;
                }
                else
                {
                    source = dest;
                    target = city;
                }

                double bestQuality        = double.MaxValue;
                int    bestTour           = -1;
                int    bestPositionSource = -1;
                int    bestPositionTarget = -1;

                for (int tourIdx = 0; tourIdx < individual.Tours.Count; tourIdx++)
                {
                    if (tourIdx != routeToAvoid)
                    {
                        Tour          tour = individual.Tours[tourIdx];
                        VRPEvaluation eval = instance.EvaluateTour(tour, individual);
                        individual.InsertPair(tour, source, target, instance);
                        VRPEvaluation evalNew = instance.EvaluateTour(tour, individual);

                        double delta = evalNew.Quality - eval.Quality;

                        if (delta < bestQuality &&
                            (instance.Feasible(evalNew) || allowInfeasible))
                        {
                            bestQuality        = delta;
                            bestTour           = tourIdx;
                            bestPositionSource = tour.Stops.IndexOf(source);
                            bestPositionTarget = tour.Stops.IndexOf(target);
                        }

                        tour.Stops.Remove(source);
                        tour.Stops.Remove(target);
                    }
                }

                if (bestTour >= 0)
                {
                    if (bestPositionTarget < bestPositionSource)
                    {
                        individual.Tours[bestTour].Stops.Insert(bestPositionTarget, target);
                        individual.Tours[bestTour].Stops.Insert(bestPositionSource, source);
                    }
                    else
                    {
                        individual.Tours[bestTour].Stops.Insert(bestPositionSource, source);
                        individual.Tours[bestTour].Stops.Insert(bestPositionTarget, target);
                    }

                    success = true;
                }
                else
                {
                    if (j < i)
                    {
                        destRoute.Stops.Insert(j, dest);
                        route1.Stops.Insert(i, city);
                    }
                    else
                    {
                        route1.Stops.Insert(i, city);
                        destRoute.Stops.Insert(j, dest);
                    }

                    success = false;
                }
            }
            else
            {
                success = false;
            }

            return(success);
        }
    public static PotvinEncoding ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible) {
      PotvinEncoding result = null;
      
      int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp);
      if (selectedIndex >= 0) {
        bool performed = false;
        Tour route1 = individual.Tours[selectedIndex];

        if (route1.Stops.Count > 0) {
          //randomize customer selection
          Permutation perm = new Permutation(PermutationTypes.Absolute, route1.Stops.Count, random);
          int customer1Position = 0;

          while (customer1Position < route1.Stops.Count) {
            performed = false;

            int customer1 = route1.Stops[perm[customer1Position]];
            int customer2 = -1;

            for (int i = 0; i < individual.Tours.Count; i++) {
              if (i != selectedIndex) {
                Tour tour = individual.Tours[i];
                for (int customer2Position = 0; customer2Position < tour.Stops.Count; customer2Position++) {
                  customer2 = tour.Stops[customer2Position];

                  if (pdp.GetPickupDeliveryLocation(customer1) != customer2) {
                    result = ReplacePair(individual, pdp, customer2, customer1, allowInfeasible);
                    if (result != null) {
                      individual = result;

                      route1 = individual.Tours[selectedIndex];
                      performed = true;
                      break;
                    }
                  }
                }
              }

              if (performed) {
                break;
              }
            }

            if (!performed)
              customer1Position++;
            else
              break;
          }
        }
      }

      return result;
    }
        public static void ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible)
        {
            int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp);

            if (selectedIndex >= 0)
            {
                Tour route1 =
                    individual.Tours[selectedIndex];

                int count = route1.Stops.Count;

                if (count > 0)
                {
                    int i    = random.Next(0, count);
                    int city = route1.Stops[i];

                    if (!PairwiseMove(individual, pdp, city, allowInfeasible))
                    {
                        i++;
                    }

                    count = route1.Stops.Count;
                }
            }
        }
        protected override void EvaluateTour(VRPEvaluation eval, IVRPProblemInstance instance, Tour tour, IVRPEncoding solution)
        {
            TourInsertionInfo tourInfo = new TourInsertionInfo(solution.GetVehicleAssignment(solution.GetTourIndex(tour)));

            eval.InsertionInfo.AddTourInsertionInfo(tourInfo);
            double originalQuality = eval.Quality;

            IHomogenousCapacitatedProblemInstance cvrpInstance = instance as IHomogenousCapacitatedProblemInstance;
            DoubleArray demand = instance.Demand;

            ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
            DoubleArray dueTime      = vrptw.DueTime;
            DoubleArray readyTime    = vrptw.ReadyTime;
            DoubleArray serviceTimes = vrptw.ServiceTime;

            IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
            IntArray pickupDeliveryLocation       = pdp.PickupDeliveryLocation;

            double capacity = cvrpInstance.Capacity.Value;

            double time        = 0.0;
            double waitingTime = 0.0;
            double serviceTime = 0.0;
            double tardiness   = 0.0;
            double overweight  = 0.0;
            double distance    = 0.0;

            double currentLoad           = 0.0;
            Dictionary <int, bool> stops = new Dictionary <int, bool>();
            int pickupViolations         = 0;

            double tourStartTime = readyTime[0];

            time = tourStartTime;

            //simulate a tour, start and end at depot
            for (int i = 0; i <= tour.Stops.Count; i++)
            {
                int start = 0;
                if (i > 0)
                {
                    start = tour.Stops[i - 1];
                }
                int end = 0;
                if (i < tour.Stops.Count)
                {
                    end = tour.Stops[i];
                }

                //drive there
                double currentDistace = vrptw.GetDistance(start, end, solution);
                time     += currentDistace;
                distance += currentDistace;

                double arrivalTime = time;

                //check if it was serviced on time
                if (time > dueTime[end])
                {
                    tardiness += time - dueTime[end];
                }

                //wait
                double currentWaitingTime = 0.0;
                if (time < readyTime[end])
                {
                    currentWaitingTime = readyTime[end] - time;
                }

                double waitTime = readyTime[end] - time;

                waitingTime += currentWaitingTime;
                time        += currentWaitingTime;

                double spareTime = dueTime[end] - time;

                //service
                double currentServiceTime = serviceTimes[end];
                serviceTime += currentServiceTime;
                time        += currentServiceTime;

                //Pickup / deliver
                double arrivalSpareCapacity = capacity - currentLoad;

                bool validPickupDelivery =
                    validPickupDelivery =
                        ((demand[end] >= 0) ||
                         (stops.ContainsKey(pickupDeliveryLocation[end])));

                if (validPickupDelivery)
                {
                    currentLoad += demand[end];
                }
                else
                {
                    pickupViolations++;
                }

                if (currentLoad > capacity)
                {
                    overweight += currentLoad - capacity;
                }

                double spareCapacity           = capacity - currentLoad;
                CVRPPDTWInsertionInfo stopInfo = new CVRPPDTWInsertionInfo(start, end, spareCapacity, tourStartTime,
                                                                           arrivalTime, time, spareTime, waitTime, new List <int>(stops.Keys), arrivalSpareCapacity);
                tourInfo.AddStopInsertionInfo(stopInfo);

                stops.Add(end, true);
            }

            eval.Quality            += instance.FleetUsageFactor.Value;
            eval.Quality            += instance.DistanceFactor.Value * distance;
            eval.Distance           += distance;
            eval.VehicleUtilization += 1;

            (eval as CVRPEvaluation).Overload += overweight;
            double tourPenalty = 0;
            double penalty     = overweight * cvrpInstance.OverloadPenalty.Value;

            eval.Penalty += penalty;
            eval.Quality += penalty;
            tourPenalty  += penalty;

            (eval as CVRPTWEvaluation).Tardiness  += tardiness;
            (eval as CVRPTWEvaluation).TravelTime += time;

            penalty       = tardiness * vrptw.TardinessPenalty.Value;
            eval.Penalty += penalty;
            eval.Quality += penalty;
            tourPenalty  += penalty;

            (eval as CVRPPDTWEvaluation).PickupViolations += pickupViolations;
            penalty       = pickupViolations * pdp.PickupViolationPenalty.Value;
            eval.Penalty += penalty;
            tourPenalty  += penalty;

            eval.Quality    += penalty;
            eval.Quality    += time * vrptw.TimeFactor.Value;
            tourInfo.Penalty = tourPenalty;
            tourInfo.Quality = eval.Quality - originalQuality;
        }
        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);
        }
Beispiel #19
0
        public static PotvinEncoding CreateSolution(IVRPProblemInstance instance, IRandom random, bool adhereTimeWindows)
        {
            PotvinEncoding result = new PotvinEncoding(instance);

            IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;

            List <int> customers = new List <int>();

            for (int i = 1; i <= instance.Cities.Value; i++)
            {
                if (pdp == null || pdp.GetDemand(i) >= 0)
                {
                    customers.Add(i);
                }
            }

            customers.Sort((city1, city2) => {
                double angle1 = CalculateAngleToDepot(instance, city1);
                double angle2 = CalculateAngleToDepot(instance, city2);

                return(angle1.CompareTo(angle2));
            });

            Tour currentTour = new Tour();

            result.Tours.Add(currentTour);

            int j = random.Next(customers.Count);

            for (int i = 0; i < customers.Count; i++)
            {
                int index = (i + j) % customers.Count;

                int stopIdx = 0;
                if (currentTour.Stops.Count > 0)
                {
                    stopIdx = result.FindBestInsertionPlace(currentTour, customers[index]);
                }
                currentTour.Stops.Insert(stopIdx, customers[index]);

                if (pdp != null)
                {
                    stopIdx = result.FindBestInsertionPlace(currentTour, pdp.GetPickupDeliveryLocation(customers[index]));
                    currentTour.Stops.Insert(stopIdx, pdp.GetPickupDeliveryLocation(customers[index]));
                }

                CVRPEvaluation evaluation = instance.EvaluateTour(currentTour, result) as CVRPEvaluation;
                if (result.Tours.Count < instance.Vehicles.Value &&
                    ((adhereTimeWindows && !instance.Feasible(evaluation)) || ((!adhereTimeWindows) && evaluation.Overload > double.Epsilon)))
                {
                    currentTour.Stops.Remove(customers[index]);
                    if (pdp != null)
                    {
                        currentTour.Stops.Remove(pdp.GetPickupDeliveryLocation(customers[index]));
                    }

                    if (currentTour.Stops.Count == 0)
                    {
                        result.Tours.Remove(currentTour);
                    }
                    currentTour = new Tour();
                    result.Tours.Add(currentTour);

                    currentTour.Stops.Add(customers[index]);
                    if (pdp != null)
                    {
                        currentTour.Stops.Add(pdp.GetPickupDeliveryLocation(customers[index]));
                    }
                }
            }

            if (currentTour.Stops.Count == 0)
            {
                result.Tours.Remove(currentTour);
            }

            return(result);
        }
        public static PotvinEncoding CreateSolution(IVRPProblemInstance problemInstance, IRandom random,
                                                    double alphaValue    = 0.7, double betaValue    = 0.1, double gammaValue     = 0.2,
                                                    double alphaVariance = 0.5, double betaVariance = 0.07, double gammaVariance = 0.14)
        {
            PotvinEncoding result = new PotvinEncoding(problemInstance);

            IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
            IMultiDepotProblemInstance        mdp = problemInstance as IMultiDepotProblemInstance;

            double alpha, beta, gamma;

            alpha = N(alphaValue, Math.Sqrt(alphaVariance), random);
            beta  = N(betaValue, Math.Sqrt(betaVariance), random);
            gamma = N(gammaValue, Math.Sqrt(gammaVariance), random);

            List <int> unroutedCustomers = new List <int>();

            for (int i = 1; i <= problemInstance.Cities.Value; i++)
            {
                if (pdp == null || (problemInstance.GetDemand(i) >= 0))
                {
                    unroutedCustomers.Add(i);
                }
            }

            List <int> depots = new List <int>();

            if (mdp != null)
            {
                for (int i = 0; i < mdp.Depots.Value; i++)
                {
                    depots.Add(i);
                }
            }
            else
            {
                depots.Add(0);
            }

            Dictionary <int, List <int> > vehicles = new Dictionary <int, List <int> >();

            foreach (int depot in depots)
            {
                vehicles[depot] = new List <int>();

                int vehicleCount = problemInstance.Vehicles.Value;
                if (mdp != null)
                {
                    for (int vehicle = 0; vehicle < mdp.VehicleDepotAssignment.Length; vehicle++)
                    {
                        if (mdp.VehicleDepotAssignment[vehicle] == depot)
                        {
                            vehicles[depot].Add(vehicle);
                        }
                    }
                }
                else
                {
                    for (int vehicle = 0; vehicle < vehicleCount; vehicle++)
                    {
                        vehicles[depot].Add(vehicle);
                    }
                }
            }

            RemoveUnusedDepots(depots, vehicles);
            Dictionary <int, int> depotAssignment = new Dictionary <int, int>();

            unroutedCustomers = SortCustomers(
                problemInstance, unroutedCustomers, depots, depotAssignment,
                alpha, beta, gamma);

            /////////
            Tour tour = new Tour();

            result.Tours.Add(tour);
            int currentCustomer = unroutedCustomers[0];

            unroutedCustomers.RemoveAt(0);

            int currentDepot   = depotAssignment[currentCustomer];
            int currentVehicle = vehicles[currentDepot][0];

            vehicles[currentDepot].RemoveAt(0);
            if (RemoveUnusedDepots(depots, vehicles))
            {
                unroutedCustomers = SortCustomers(
                    problemInstance, unroutedCustomers, depots, depotAssignment,
                    alpha, beta, gamma);
            }

            result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle;

            tour.Stops.Add(currentCustomer);
            if (pdp != null)
            {
                tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer));
            }
            ////////

            while (unroutedCustomers.Count > 0)
            {
                double minimumCost         = double.MaxValue;
                int    customer            = -1;
                int    indexOfMinimumCost  = -1;
                int    indexOfMinimumCost2 = -1;

                foreach (int unrouted in unroutedCustomers)
                {
                    VRPEvaluation eval          = problemInstance.EvaluateTour(tour, result);
                    double        originalCosts = eval.Quality;

                    for (int i = 0; i <= tour.Stops.Count; i++)
                    {
                        tour.Stops.Insert(i, unrouted);
                        eval = problemInstance.EvaluateTour(tour, result);
                        double tourCost = eval.Quality - originalCosts;

                        if (pdp != null)
                        {
                            for (int j = i + 1; j <= tour.Stops.Count; j++)
                            {
                                bool   feasible;
                                double cost = tourCost +
                                              problemInstance.GetInsertionCosts(eval, result, pdp.GetPickupDeliveryLocation(unrouted), 0, j, out feasible);
                                if (cost < minimumCost && feasible)
                                {
                                    customer            = unrouted;
                                    minimumCost         = cost;
                                    indexOfMinimumCost  = i;
                                    indexOfMinimumCost2 = j;
                                }
                            }
                        }
                        else
                        {
                            double cost     = tourCost;
                            bool   feasible = problemInstance.Feasible(eval);
                            if (cost < minimumCost && feasible)
                            {
                                customer           = unrouted;
                                minimumCost        = cost;
                                indexOfMinimumCost = i;
                            }
                        }

                        tour.Stops.RemoveAt(i);
                    }
                }

                if (indexOfMinimumCost == -1 && vehicles.Count == 0)
                {
                    indexOfMinimumCost  = tour.Stops.Count;
                    indexOfMinimumCost2 = tour.Stops.Count + 1;
                    customer            = unroutedCustomers[0];
                }

                // insert customer if found
                if (indexOfMinimumCost != -1)
                {
                    tour.Stops.Insert(indexOfMinimumCost, customer);
                    if (pdp != null)
                    {
                        tour.Stops.Insert(indexOfMinimumCost2, pdp.GetPickupDeliveryLocation(customer));
                    }

                    unroutedCustomers.Remove(customer);
                }
                else // no feasible customer found
                {
                    tour = new Tour();
                    result.Tours.Add(tour);
                    currentCustomer = unroutedCustomers[0];
                    unroutedCustomers.RemoveAt(0);

                    currentDepot   = depotAssignment[currentCustomer];
                    currentVehicle = vehicles[currentDepot][0];
                    vehicles[currentDepot].RemoveAt(0);
                    if (RemoveUnusedDepots(depots, vehicles))
                    {
                        unroutedCustomers = SortCustomers(
                            problemInstance, unroutedCustomers, depots, depotAssignment,
                            alpha, beta, gamma);
                    }

                    result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle;

                    tour.Stops.Add(currentCustomer);
                    if (pdp != null)
                    {
                        tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer));
                    }
                }
            }

            if (mdp != null)
            {
                List <int> availableVehicles = new List <int>();
                for (int i = 0; i < mdp.Vehicles.Value; i++)
                {
                    availableVehicles.Add(i);
                }

                for (int i = 0; i < result.VehicleAssignment.Length; i++)
                {
                    if (result.VehicleAssignment[i] != -1)
                    {
                        availableVehicles.Remove(result.VehicleAssignment[i]);
                    }
                }

                for (int i = 0; i < result.VehicleAssignment.Length; i++)
                {
                    if (result.VehicleAssignment[i] == -1)
                    {
                        result.VehicleAssignment[i] = availableVehicles[0];
                        availableVehicles.RemoveAt(0);
                    }
                }
            }

            return(result);
        }
Beispiel #21
0
        private static PotvinEncoding ReplacePair(PotvinEncoding individual, IVRPProblemInstance instance, int replaced, int replacing, bool allowInfeasible)
        {
            individual = individual.Clone() as PotvinEncoding;
            IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;

            int replacedDest = pdp.GetPickupDeliveryLocation(replaced);
            int replacedSource, replacedTarget;

            if (pdp.GetDemand(replaced) >= 0)
            {
                replacedSource = replaced;
                replacedTarget = replacedDest;
            }
            else
            {
                replacedSource = replacedDest;
                replacedTarget = replaced;
            }
            Tour replacedSourceTour = individual.Tours.Find(t => t.Stops.Contains(replacedSource));
            Tour replacedTargetTour = individual.Tours.Find(t => t.Stops.Contains(replacedTarget));

            int replacingDest = pdp.GetPickupDeliveryLocation(replacing);
            int replacingSource, replacingTarget;

            if (pdp.GetDemand(replacing) >= 0)
            {
                replacingSource = replacing;
                replacingTarget = replacingDest;
            }
            else
            {
                replacingSource = replacingDest;
                replacingTarget = replacing;
            }
            Tour replacingSourceTour = individual.Tours.Find(t => t.Stops.Contains(replacingSource));
            Tour replacingTargetTour = individual.Tours.Find(t => t.Stops.Contains(replacingTarget));

            replacingSourceTour.Stops.Remove(replacingSource);
            replacingTargetTour.Stops.Remove(replacingTarget);

            replacedSourceTour.Stops[replacedSourceTour.Stops.IndexOf(replacedSource)] = replacingSource;
            if (!allowInfeasible && !instance.TourFeasible(replacedSourceTour, individual))
            {
                return(null);
            }

            replacedTargetTour.Stops[replacedTargetTour.Stops.IndexOf(replacedTarget)] = replacingTarget;
            if (!allowInfeasible && !instance.TourFeasible(replacedTargetTour, individual))
            {
                return(null);
            }

            double bestQuality        = double.MaxValue;
            int    bestTour           = -1;
            int    bestPositionSource = -1;
            int    bestPositionTarget = -1;

            int routeToAvoid = individual.Tours.IndexOf(replacingSourceTour);

            for (int tourIdx = 0; tourIdx < individual.Tours.Count; tourIdx++)
            {
                if (tourIdx != routeToAvoid)
                {
                    Tour          tour = individual.Tours[tourIdx];
                    VRPEvaluation eval = instance.EvaluateTour(tour, individual);
                    individual.InsertPair(tour, replacedSource, replacedTarget, instance);
                    VRPEvaluation evalNew = instance.EvaluateTour(tour, individual);

                    double delta = evalNew.Quality - eval.Quality;

                    if (delta < bestQuality &&
                        (instance.Feasible(evalNew) || allowInfeasible))
                    {
                        bestQuality        = delta;
                        bestTour           = tourIdx;
                        bestPositionSource = tour.Stops.IndexOf(replacedSource);
                        bestPositionTarget = tour.Stops.IndexOf(replacedTarget);
                    }

                    tour.Stops.Remove(replacedSource);
                    tour.Stops.Remove(replacedTarget);
                }
            }

            if (bestTour != -1)
            {
                if (bestPositionTarget < bestPositionSource)
                {
                    individual.Tours[bestTour].Stops.Insert(bestPositionTarget, replacedTarget);
                    individual.Tours[bestTour].Stops.Insert(bestPositionSource, replacedSource);
                }
                else
                {
                    individual.Tours[bestTour].Stops.Insert(bestPositionSource, replacedSource);
                    individual.Tours[bestTour].Stops.Insert(bestPositionTarget, replacedTarget);
                }

                return(individual);
            }
            else
            {
                return(null);
            }
        }
Beispiel #22
0
        public static PotvinEncoding ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible)
        {
            PotvinEncoding result = null;

            int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp);

            if (selectedIndex >= 0)
            {
                bool performed = false;
                Tour route1    = individual.Tours[selectedIndex];

                if (route1.Stops.Count > 0)
                {
                    //randomize customer selection
                    Permutation perm = new Permutation(PermutationTypes.Absolute, route1.Stops.Count, random);
                    int         customer1Position = 0;

                    while (customer1Position < route1.Stops.Count)
                    {
                        performed = false;

                        int customer1 = route1.Stops[perm[customer1Position]];
                        int customer2 = -1;

                        for (int i = 0; i < individual.Tours.Count; i++)
                        {
                            if (i != selectedIndex)
                            {
                                Tour tour = individual.Tours[i];
                                for (int customer2Position = 0; customer2Position < tour.Stops.Count; customer2Position++)
                                {
                                    customer2 = tour.Stops[customer2Position];

                                    if (pdp.GetPickupDeliveryLocation(customer1) != customer2)
                                    {
                                        result = ReplacePair(individual, pdp, customer2, customer1, allowInfeasible);
                                        if (result != null)
                                        {
                                            individual = result;

                                            route1    = individual.Tours[selectedIndex];
                                            performed = true;
                                            break;
                                        }
                                    }
                                }
                            }

                            if (performed)
                            {
                                break;
                            }
                        }

                        if (!performed)
                        {
                            customer1Position++;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            return(result);
        }
        public static void Apply(PotvinEncoding solution, PotvinPDShiftMove move, IVRPProblemInstance problemInstance)
        {
            bool newTour = false;

            if (move.Tour >= solution.Tours.Count)
            {
                solution.Tours.Add(new Tour());
                newTour = true;
            }
            Tour tour = solution.Tours[move.Tour];

            Tour oldTour = solution.Tours.Find(t => t.Stops.Contains(move.City));

            oldTour.Stops.Remove(move.City);

            if (problemInstance is IPickupAndDeliveryProblemInstance)
            {
                IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;

                int  location = pdp.GetPickupDeliveryLocation(move.City);
                Tour oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location));
                oldTour2.Stops.Remove(location);

                solution.InsertPair(tour, move.City, location, problemInstance);
            }
            else
            {
                int place = solution.FindBestInsertionPlace(tour, move.City);
                tour.Stops.Insert(place, move.City);
            }

            if (newTour)
            {
                List <int> vehicles = new List <int>();
                for (int i = move.Tour; i < problemInstance.Vehicles.Value; i++)
                {
                    vehicles.Add(solution.GetVehicleAssignment(i));
                }

                double bestQuality = double.MaxValue;
                int    bestVehicle = -1;

                int originalVehicle = solution.GetVehicleAssignment(move.Tour);
                foreach (int vehicle in vehicles)
                {
                    solution.VehicleAssignment[move.Tour] = vehicle;

                    double quality = problemInstance.EvaluateTour(tour, solution).Quality;
                    if (quality < bestQuality)
                    {
                        bestQuality = quality;
                        bestVehicle = vehicle;
                    }
                }

                solution.VehicleAssignment[move.Tour] = originalVehicle;

                int index = -1;
                for (int i = move.Tour; i < solution.VehicleAssignment.Length; i++)
                {
                    if (solution.VehicleAssignment[i] == bestVehicle)
                    {
                        index = i;
                        break;
                    }
                }
                solution.VehicleAssignment[index]     = originalVehicle;
                solution.VehicleAssignment[move.Tour] = bestVehicle;
            }

            solution.Repair();
        }