diff --git a/CMakeLists.txt b/CMakeLists.txt index e022547daa62330c6d8b5a06b631134ab94daf33..f6cae3907cf30cd7c3f5471e73399ae94462ede3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,9 @@ add_executable(pdptw src/mains/main.cpp src/output/solution_checker.cpp src/lns/operators/sorting_strategy.cpp src/lns/operators/destruction/random_destroy.cpp - src/lns/operators/generation/enumerate.cpp - src/lns/operators/generation/modification_generator.cpp + src/lns/operators/generators/enumerate.cpp + src/lns/operators/generators/modification_generator.cpp + src/lns/operators/reconstruction/list_heuristic_insertion.hpp src/lns/operators/selector/operator_selection.cpp src/utils.cpp ) diff --git a/src/config.h b/src/config.h index 6bb3f2bf9fef9c3a67843f5e1c2d1f8093dd2a1a..9cbc47d2513891218b8d4e318217e17ae1067a6b 100644 --- a/src/config.h +++ b/src/config.h @@ -2,4 +2,4 @@ const int EXCLUSION_PENALTY = 100; -const int RANDOM_SEED = 10; \ No newline at end of file +const int RANDOM_SEED = 100; \ No newline at end of file diff --git a/src/input/data.cpp b/src/input/data.cpp index 59448dc0837af48784c8d0d0779ac76569035371..223816cd45bfa259b14f8a1d1ef1973f8d8c9d87 100644 --- a/src/input/data.cpp +++ b/src/input/data.cpp @@ -26,8 +26,12 @@ double data::routeCost(PDPTWData const & data, Route const & route) const std::vector<int> & routeIDs = route.getRoute(); double cost = 0; + if (routeIDs.empty()) + { + return 0; + } // cost from and to the depot - cost += matrix[0][routeIDs[0]]; + cost += matrix[0][routeIDs.at(0)]; //std::cout << "\n route cost : " << matrix[0][routeIDs[0]] << " "; cost += matrix[routeIDs.back()][0]; diff --git a/src/input/location.cpp b/src/input/location.cpp index c0127014204aa70b8c06c517d378282854c92f44..a6b1fdb4c3d22238c422a6a294488e582b39054d 100644 --- a/src/input/location.cpp +++ b/src/input/location.cpp @@ -51,6 +51,6 @@ void Location::print() const { std::cout << "Location ID: " << id << ", Coordinates: (" << longitude << ", " << latitude << ")\n"; std::cout << "Location Type : " << Location::LocTypeToString(locType) << ", Associated location : " << pairedLocationID << "\n"; - std::cout << "Demand : " << demand << "\n"; + std::cout << "Demand : " << demand << ", Service Duration :" << serviceDuration << "\n"; timeWindow.print(); } \ No newline at end of file diff --git a/src/input/pdptw_data.cpp b/src/input/pdptw_data.cpp index 706bd09777f3dabf1b2cc7b7513d738c2fc2d4a4..ad31f15567312840209a9ea1a55877e5cf6f20eb 100644 --- a/src/input/pdptw_data.cpp +++ b/src/input/pdptw_data.cpp @@ -55,7 +55,7 @@ PDPTWData::PDPTWData(int size, int capacity, Location depot, std::vector<Locatio if( loc.getLocType() == LocType::PICKUP ) { // vector indexed from 0 / Location indexed from 1 - pairs.emplace_back(loc, locations[loc.getPair()-1], loc.getId()); + pairs.emplace_back(loc, this->locations[loc.getPair()-1], loc.getId()); } } } diff --git a/src/lns/constraints/capacity/capacity_constraint.cpp b/src/lns/constraints/capacity/capacity_constraint.cpp index 44d3c775a4fce4c7df4709d6e71e7c460c98e8fe..b455134178b1b97d0deb2323223a8fe6205a15ca 100644 --- a/src/lns/constraints/capacity/capacity_constraint.cpp +++ b/src/lns/constraints/capacity/capacity_constraint.cpp @@ -67,7 +67,7 @@ bool CapacityConstraint::checkModif(Pair const &pair, int routeIndex, int Pickup // not ideal void CapacityConstraint::applyModif(Pair const &pair, int routeIndex, int PickupPosition, int DeliveryPosition, bool addPair) { - std::cout << "ok \n"; + std::cout << "ApplyModif (capa constraint) \n"; if (addPair) { // Insert new values @@ -104,6 +104,7 @@ void CapacityConstraint::applyModif(Pair const &pair, int routeIndex, int Pickup bool CapacityConstraint::check(InsertPair const &op) const { + std::cout << "capa constraint \n"; return checkModif(op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion()); } void CapacityConstraint::apply(InsertPair const &op) diff --git a/src/lns/constraints/time_window/time_window_constraint.cpp b/src/lns/constraints/time_window/time_window_constraint.cpp index c0310483e1b7dd5b0b8ef0435b5b17a8f8875258..1886b6f222deb598f70fc7a7193994323b1565ae 100644 --- a/src/lns/constraints/time_window/time_window_constraint.cpp +++ b/src/lns/constraints/time_window/time_window_constraint.cpp @@ -63,6 +63,7 @@ void TimeWindowConstraint::initReachTimes() // refait l'ordo sur le nouveau vecteur bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pair, int routeIndex, int pickupPos, int deliveryPos) const { + ReachTimeVector const &reachTimes = allRouteReachTimes.at(routeIndex); // COPY route vector @@ -75,22 +76,22 @@ bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pa route.insert(route.begin() + pickupPos, pair.getPickup().getId()); - std::cout << "\n"; - for (auto pos : route) - { - std::cout << pos << " "; - } - std::cout << "\n"; + // std::cout << "\n"; + // for (auto pos : route) + // { + // std::cout << pos << " "; + // } + // std::cout << "\n"; // Compute new reach time computeReachTimes(data, route, newReachTimes); - std::cout << "\n"; - for (auto pos : newReachTimes) - { - std::cout << pos << " "; - } - std::cout << "\n"; + // std::cout << "\n"; + // for (auto pos : newReachTimes) + // { + // std::cout << pos << " "; + // } + // std::cout << "\n"; // Check Time Windows for (int i = 0; i < newReachTimes.size(); ++i) @@ -137,6 +138,7 @@ void TimeWindowConstraint::ApplyModif(const PDPTWData& data, const Pair & pair, bool TimeWindowConstraint::check(InsertPair const &op) const { + std::cout << "tw constraint \n"; return checkInsertion(getSolution().getData(), op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion()); } void TimeWindowConstraint::apply(InsertPair const &op) diff --git a/src/lns/modification/atomic_recreation.h b/src/lns/modification/atomic_recreation.h index 227b4f913b79e54cd9e4a5e6b4876028c9e4da75..7a5384abbcb4066f7124eb0b4c77d0971fec8043 100644 --- a/src/lns/modification/atomic_recreation.h +++ b/src/lns/modification/atomic_recreation.h @@ -1,6 +1,7 @@ #pragma once #include "atomic_modification.h" +#include "input/pair.h" class Location; @@ -20,7 +21,8 @@ public: virtual ModificationCheckVariant asCheckVariant() const = 0; /** - * @return the pickup location added to the solution, nullptr if none were added + * @return the pair added to the solution, nullptr if none were added + * (why return pointer and not juste a int ?) */ - virtual Location const *getAddedLocation() const = 0; + virtual Pair const *getAddedPairs() const = 0; }; \ No newline at end of file diff --git a/src/lns/modification/pair/insert_pair.cpp b/src/lns/modification/pair/insert_pair.cpp index 4206f3d7cdbb0110eac092c8c74d44eae32cdbb6..da5bf4fff088beefcb87201b7d4b2c341efa02bd 100644 --- a/src/lns/modification/pair/insert_pair.cpp +++ b/src/lns/modification/pair/insert_pair.cpp @@ -1,5 +1,6 @@ #include "insert_pair.h" #include "input/data.h" +#include "lns/constraints/constraint.h" InsertPair::InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, Pair const &pair) : @@ -87,9 +88,9 @@ const Location &InsertPair::getDeliveryLocation() const return deliveryLocation; } -const Location *InsertPair::getAddedLocation() const +const Pair *InsertPair::getAddedPairs() const { - return &pickupLocation; + return &pair; } const Pair &InsertPair::getPair() const diff --git a/src/lns/modification/pair/insert_pair.h b/src/lns/modification/pair/insert_pair.h index 14376aabf796ec6fc51f9a109948fe61e16d18b5..ceb40455c26d0aa4a136b78cc322ee8a3179d934 100644 --- a/src/lns/modification/pair/insert_pair.h +++ b/src/lns/modification/pair/insert_pair.h @@ -55,7 +55,7 @@ public: void modifySolution(Solution &solution) override; double evaluate(Solution const &solution) const override; - Location const *getAddedLocation() const override; + Pair const *getAddedPairs() const override; int getPickupInsertion() const; int getDeliveryInsertion() const; diff --git a/src/lns/modification/route/insert_route.cpp b/src/lns/modification/route/insert_route.cpp index 7a6be790ae6fb456ad94c3253c0ec0d3565e9018..160722e774ca379892047093fcf2a264d66993bb 100644 --- a/src/lns/modification/route/insert_route.cpp +++ b/src/lns/modification/route/insert_route.cpp @@ -14,7 +14,7 @@ double InsertRoute::evaluate(Solution const &solution) const return 0; } -Location const *InsertRoute::getAddedLocation() const +Pair const *InsertRoute::getAddedPairs() const { return nullptr; } diff --git a/src/lns/modification/route/insert_route.h b/src/lns/modification/route/insert_route.h index 877548964092882f44ac8292369c71ce2c9d8022..cbfdb27f627d05339a9b80723667221c616abfaa 100644 --- a/src/lns/modification/route/insert_route.h +++ b/src/lns/modification/route/insert_route.h @@ -16,7 +16,7 @@ public: void modifySolution(Solution &solution) override; double evaluate(Solution const &solution) const override; - Location const *getAddedLocation() const override; + Pair const *getAddedPairs() const override; ModificationCheckVariant asCheckVariant() const override; }; \ No newline at end of file diff --git a/src/lns/operators/generators/enumerate.cpp b/src/lns/operators/generators/enumerate.cpp index b06b8179c0774e710b2a83b76d705fc17c8c1963..963b83d66bfe0ed131cd2ebbdff12207791aec47 100644 --- a/src/lns/operators/generators/enumerate.cpp +++ b/src/lns/operators/generators/enumerate.cpp @@ -11,22 +11,22 @@ namespace enumeration * @param consumeModification called when a modification is created */ void enumerateAllInsertPair(Solution const &solution, Pair const &pair, - std::function<void(InsertPair &&)> const &consumeModification) - { + std::function<void(InsertPair &&)> const &consumeModification) + { int routeIndex = 0; - for (const Route &route : solution.getRoutes()) + // Insert into existing routes + for (Route const &route: solution.getRoutes()) { - for (int p=0; p <= route.getSize(); p++) + for (int p = 0; p <= route.getSize(); p++) { - for (int d=p; d <= route.getSize(); d++) + for (int d = p; d <= route.getSize(); d++) { - Index index = std::make_tuple(routeIndex, p,d); + Index index = std::make_tuple(routeIndex, p, d); + //std::cout << std::get<0>(index) << " " << std::get<1>(index) << " " << std::get<2>(index) << "\n"; consumeModification(InsertPair(index, pair)); } } ++routeIndex; } } - - }// namespace enumeration \ No newline at end of file diff --git a/src/lns/operators/generators/modification_generator.cpp b/src/lns/operators/generators/modification_generator.cpp index be8b0a290bd3726b9e72445b2ba02ff97f405248..756e7dfc0f695bddf71134bcc6e50b6f964a5223 100644 --- a/src/lns/operators/generators/modification_generator.cpp +++ b/src/lns/operators/generators/modification_generator.cpp @@ -15,19 +15,23 @@ namespace generator std::function<void(ModificationType &&)> addToListIfValidTemplate(Solution const &solution, ModificationContainer &list) { + std::cout << "avant error \n"; return [&](ModificationType &&modification) { + std::cout << "Check Modif \n"; if (solution.checkModification(modification)) { + std::cout << "insert modif to list \n"; list.push_front(std::make_unique<ModificationType>(modification)); } }; } - void AllTypedModifications<InsertPair>::populate(Solution const &solution, Pair const &request, + void AllTypedModifications<InsertPair>::populate(Solution const &solution, Pair const &pair, std::forward_list<std::unique_ptr<AtomicRecreation>> &list) { + std::cout << "dans modif_generator \n"; enumeration::enumerateAllInsertPair( - solution, request, addToListIfValidTemplate<InsertPair>(solution, list)); + solution, pair, addToListIfValidTemplate<InsertPair>(solution, list)); } }// namespace generator diff --git a/src/lns/operators/reconstruction/list_heuristic_insertion.hpp b/src/lns/operators/reconstruction/list_heuristic_insertion.hpp index 11fb7492121b61b5e34313d02f52d09484d4328f..e05e50591094875d5726a15c30e222409441b0b8 100644 --- a/src/lns/operators/reconstruction/list_heuristic_insertion.hpp +++ b/src/lns/operators/reconstruction/list_heuristic_insertion.hpp @@ -17,7 +17,7 @@ template<std::derived_from<sorting_strategy::SortingStrategy> Strategy, std::derived_from<generator::ModificationGenerator> Generator> void ListHeuristicInsertion<Strategy, Generator>::reconstructSolution(Solution &solution, double blinkRate) const { - std::vector<int> sortedPairs = Strategy(solution).sortRequests(); + std::vector<int> sortedPairs = Strategy(solution).sortPairs(); AtomicRecreationPtr recreation; for (int pairID: sortedPairs) { @@ -25,6 +25,7 @@ void ListHeuristicInsertion<Strategy, Generator>::reconstructSolution(Solution & recreation = ListHeuristicInsertion::choosingStrategy(solution, pair, blinkRate); if (recreation) { + std::cout << "\n apply recreation "<< " " << "\n \n"; solution.applyRecreateSolution(*recreation); } } @@ -43,7 +44,7 @@ std::unique_ptr<AtomicRecreation> ListHeuristicInsertion<Strategy, Generator>::c Generator().populate(solution, pair, modifications); for (AtomicRecreationPtr &possibleRecreation: modifications) { - if (util::getRandom() < 1 - blinkRate) + if (util::getRandom() <= 1 - blinkRate) { double newInsertionCost = possibleRecreation->evaluate(solution); if (newInsertionCost < bestKnownInsertionCost) diff --git a/src/lns/solution/solution.cpp b/src/lns/solution/solution.cpp index 21d0c48654ccab14c1fc2174b2cfa120b4a6df07..908ce690a65d0957b325c298b3b62953c9aa9494 100644 --- a/src/lns/solution/solution.cpp +++ b/src/lns/solution/solution.cpp @@ -21,6 +21,7 @@ void Solution::initPairBank() void Solution::initRoutes() { routes.clear(); + routes.emplace_back(); } void Solution::initConstraints() @@ -45,7 +46,6 @@ double Solution::computeSolutionCost() const { cost += data::routeCost(data, route); } - std::cout << "le cout " << cost << " \n"; return cost; } @@ -130,7 +130,7 @@ double Solution::getCost() const PDPTWData const &Solution::getData() const { - return data; + return data.get(); } int Solution::requestsFulFilledCount() const @@ -149,12 +149,15 @@ bool Solution::checkModification(AtomicRecreation const &modification) const // visitor pattern for (std::unique_ptr<Constraint> const &constraint: constraints) { + std::cout << "in check modif \n"; if (!constraint->checkVariant(checkVariant)) { + std::cout << "return false \n"; return false; } } return true; + std::cout << "return true \n"; } @@ -175,7 +178,7 @@ void Solution::afterApplyModification(AtomicModification &modification) void Solution::applyRecreateSolution(AtomicRecreation &modification) { // apply the modification to the solution - + std::cout << "not fonctionnal yet \n"; } void Solution::applyDestructSolution(AtomicDestruction &modification) diff --git a/src/lns/solution/solution.h b/src/lns/solution/solution.h index aa3ff6c0c6941312129cc136ace3f4321903b18c..cb2954aab63d35552ce171cab1c094a9edb422c4 100644 --- a/src/lns/solution/solution.h +++ b/src/lns/solution/solution.h @@ -1,6 +1,7 @@ #pragma once #include "input/pair.h" +#include "input/pdptw_data.h" #include "lns/constraints/constraint.h" #include "route.h" @@ -23,8 +24,8 @@ public: using PairBank = std::vector<int>; private: - // ref_wrapper - PDPTWData const &data; + std::reference_wrapper<PDPTWData const> data; + //PDPTWData const &data; /* * Store IDs of a pairs (Pickup & Delivery) that are not assigned yet to a route. */ @@ -40,6 +41,7 @@ private: public: /** * Expected way to construct a solution. + * Generate an empty solution with all pairs in the pairBank and one empty route. */ static Solution emptySolution(PDPTWData const &data); diff --git a/src/mains/main.cpp b/src/mains/main.cpp index d6fb7022565ea0374483464e0c7f0b974221834f..780bb7d7bd625786cfa160b6a05064bdaa93819e 100644 --- a/src/mains/main.cpp +++ b/src/mains/main.cpp @@ -8,6 +8,7 @@ #include <spdlog/spdlog.h> #include "input/location.h" +#include "input/pdptw_data.h" #include "input/time_window.h" #include "input/json_parser.h" #include "input/data.h" @@ -19,8 +20,31 @@ #include "lns/modification/pair/remove_pair.h" #include "lns/modification/route/remove_route.h" +#include "lns/operators/reconstruction/list_heuristic_insertion.h" +#include "lns/operators/reconstruction/list_heuristic_insertion.hpp" +#include "lns/operators/generators/modification_generator.h" +#include "lns/operators/sorting_strategy.h" + + using json = nlohmann::json; +void printForwardList(const std::forward_list<std::unique_ptr<AtomicRecreation>>& list) { + int cpt = 1; + for (const auto& item : list) { + std::cout << cpt << "{ \n"; + // Affichage de l'emplacement ajouté à la solution + const Pair* pair = item->getAddedPairs(); + if (pair != nullptr) { + std::cout << "Added Location ID: \n"; + pair->print(); + } else { + std::cout << "No location added.\n"; + } + std::cout << "} \n"; + ++cpt; + } +} + int main(int argc, char const *argv[]) { //std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/test_inst.json"; @@ -39,8 +63,53 @@ int main(int argc, char const *argv[]) /* * test */ - Solution emptySol = Solution::emptySolution(data); - emptySol.print(); + Solution solution = Solution::emptySolution(data); + + std::cout << "--- Empty Solution --- \n"; + solution.print(); + + sorting_strategy::Shuffle shuffleStrategy(solution); // Créer une instance de la stratégie de tri + auto sortedPairs = shuffleStrategy.sortPairs(); + + for (auto id : sortedPairs) + { + std::cout << id << " "; + } + std::cout << "\n"; + // ListHeuristicInsertion<sorting_strategy::SortingStrategy, generator::ModificationGenerator> operator; + + // double blinkRate = 0.1; // Par exemple, 10% de probabilité d'ignorer l'insertion + // operator.reconstructSolution(emptySol, blinkRate); + + std::cout << "---- \n"; + + generator::AllTypedModifications<InsertPair> generator; + generator::ModificationContainer modificationList; + + + std::cout << "---- \n"; + + int pairID = solution.getBank().front(); + Pair pair = solution.getData().getPair(pairID); + + pair.print(); + + std::cout << "---- \n"; + generator.populate(solution, pair, modificationList); + + // print the pair associated to each modif + printForwardList(modificationList); + + std::cout << "\n ---- \n \n"; + //ListHeuristicInsertion<std::derived_from<sorting_strategy::SortingStrategy> Strategy, std::derived_from<generator::ModificationGenerator> Generator> + + double blinkRate = 0; + + //operator.reconstructSolution(solution, blinkRate); + ListHeuristicInsertion<sorting_strategy::Shuffle, generator::AllTypedModifications<InsertPair>> operatorInstance; + + operatorInstance.reconstructSolution(solution, blinkRate); + solution.print(); return 0; }