#include "insert_pair.h" #include "input/data.h" InsertPair::InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, Pair const &pair) : routeIndex(routeIndex), pickupInsertion(pickupInsertion), deliveryInsertion(deliveryInsertion), pickupLocation(pair.getPickup()), deliveryLocation(pair.getDelivery()), pair(pair) {} InsertPair::InsertPair(Index position, Pair const &pair) : routeIndex(std::get<0>(position)), pickupInsertion(std::get<1>(position)), deliveryInsertion(std::get<2>(position)), pickupLocation(pair.getPickup()), deliveryLocation(pair.getDelivery()), pair(pair) {} void InsertPair::modifySolution(Solution &solution) { Route &route = solution.getRoute(routeIndex); route.insertAt(pickupLocation.getId(), pickupInsertion); // + 1 because the pickup location was inserted earlier in the route route.insertAt(deliveryLocation.getId(), deliveryInsertion+1); } double InsertPair::evaluate(Solution const &solution) const { Route const &route = solution.getRoute(routeIndex); const std::vector<int> & routeIDs = route.getRoute(); const PDPTWData &data = solution.getData(); int prevPickup = (pickupInsertion == 0) ? 0 : routeIDs[pickupInsertion - 1]; int nextPickup = (pickupInsertion >= routeIDs.size()) ? 0 : routeIDs[pickupInsertion]; double pickupCost = data::addedCostForInsertion(data, prevPickup, pickupLocation.getId(), nextPickup); // if pickupInsertion == deliveryInsertion+1, then prevDelivery = pickupLocation.getId() // the insertion of the delivery is done just after the pickup without intermediate location // otherwise, the pickup and the delivery insertion are independant and the pickup insertion does not affect the delivery insertion cost int prevDelivery = (deliveryInsertion == 0) ? 0 : routeIDs[deliveryInsertion - 1]; if (pickupInsertion == deliveryInsertion) { prevDelivery = pickupLocation.getId(); } int nextDelivery = (deliveryInsertion >= routeIDs.size()) ? 0 : routeIDs[deliveryInsertion]; //std::cout << "insert " << prevDelivery << " + " << deliveryLocation.getId() << " + " << nextDelivery << "\n"; double deliveryCost = data::addedCostForInsertion(data, prevDelivery, deliveryLocation.getId(), nextDelivery); //std::cout << "insert " << pickupCost << " + " << deliveryCost << "\n"; return pickupCost + deliveryCost; } ModificationCheckVariant InsertPair::asCheckVariant() const { return *this; } int InsertPair::getPickupInsertion() const { return pickupInsertion; } int InsertPair::getDeliveryInsertion() const { return deliveryInsertion; } int InsertPair::getRouteIndex() const { return routeIndex; } Location const &InsertPair::getPickupLocation() const { return pickupLocation; } const Location &InsertPair::getDeliveryLocation() const { return deliveryLocation; } const Location *InsertPair::getAddedLocation() const { return &pickupLocation; } const Pair &InsertPair::getPair() const { return pair; } Index InsertPair::getIndex() const { return std::make_tuple(routeIndex, pickupInsertion, deliveryInsertion); } ModificationApplyVariant InsertPair::asApplyVariant() const { return (*this); }