From 4f74e41e0d760b02a2e05091358f60efefff4a1e Mon Sep 17 00:00:00 2001 From: awenjb <126257927+awenjb@users.noreply.github.com> Date: Tue, 11 Mar 2025 15:01:40 +0100 Subject: [PATCH] Replace template by switch case - replace template by switch case for the sorting strategy and the enumeration strategy in reconstruction operator - remove generator / modficiation generator --- CMakeLists.txt | 3 +- src/lns/operators/abstract_operator.h | 5 +- .../generators/modification_generator.cpp | 36 ------------ .../generators/modification_generator.h | 47 --------------- .../enumerate.cpp | 21 +++++-- .../enumerate.h | 18 ++++-- .../reconstruction/list_heuristic_insertion.h | 7 +-- .../list_heuristic_insertion.hpp | 58 +++++++++++++------ src/lns/operators/sorting_strategy.h | 7 +++ src/mains/main.cpp | 17 +++--- 10 files changed, 90 insertions(+), 129 deletions(-) delete mode 100644 src/lns/operators/generators/modification_generator.cpp delete mode 100644 src/lns/operators/generators/modification_generator.h rename src/lns/operators/{generators => reconstruction}/enumerate.cpp (52%) rename src/lns/operators/{generators => reconstruction}/enumerate.h (51%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f1351b..c546606 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,8 +37,7 @@ add_executable(pdptw src/mains/main.cpp src/output/solution_exporter.cpp src/lns/operators/sorting_strategy.cpp src/lns/operators/destruction/random_destroy.cpp - src/lns/operators/generators/enumerate.cpp - src/lns/operators/generators/modification_generator.cpp + src/lns/operators/reconstruction/enumerate.cpp src/lns/operators/reconstruction/list_heuristic_insertion.hpp src/lns/operators/selector/operator_selection.cpp src/utils.cpp diff --git a/src/lns/operators/abstract_operator.h b/src/lns/operators/abstract_operator.h index 2223e22..80f3f44 100644 --- a/src/lns/operators/abstract_operator.h +++ b/src/lns/operators/abstract_operator.h @@ -1,5 +1,8 @@ #pragma once +#include "lns/operators/reconstruction/enumerate.h" +#include "sorting_strategy.h" + class Solution; class DestructionOperator @@ -12,6 +15,6 @@ public: class ReconstructionOperator { public: - virtual void reconstructSolution(Solution &solution, double blinkRate) const = 0; + virtual void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const = 0; virtual ~ReconstructionOperator() = default; }; diff --git a/src/lns/operators/generators/modification_generator.cpp b/src/lns/operators/generators/modification_generator.cpp deleted file mode 100644 index 9139923..0000000 --- a/src/lns/operators/generators/modification_generator.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "modification_generator.h" - -#include "enumerate.h" - -namespace generator -{ - /** - * - * @tparam ModificationType the type of modification to be checked - * @param solution the solution to check the modification validity - * @param list the modification will be added to this list if valid - * @return a function that takes a ModificationType and add it to list iff it is valid - */ - template<std::derived_from<AtomicRecreation> ModificationType> - std::function<void(ModificationType &&)> addToListIfValidTemplate(Solution const &solution, - ModificationContainer &list) - { - return [&](ModificationType &&modification) { - if (solution.checkModification(modification)) - { - std::cout << " => Insert Modification" << "\n"; - list.push_front(std::make_unique<ModificationType>(modification)); - } - }; - std::cout << " => Insert Modification" << "\n"; - } - - void AllTypedModifications<InsertPair>::populate(Solution const &solution, Pair const &pair, - std::forward_list<std::unique_ptr<AtomicRecreation>> &list) - { - std::cout << "\n MODIFICATION GENERATOR : \n"; - enumeration::enumerateAllInsertPair( - solution, pair, addToListIfValidTemplate<InsertPair>(solution, list)); - } - -}// namespace generator diff --git a/src/lns/operators/generators/modification_generator.h b/src/lns/operators/generators/modification_generator.h deleted file mode 100644 index 23026bc..0000000 --- a/src/lns/operators/generators/modification_generator.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "input/pair.h" -#include "lns/modification/atomic_recreation.h" -#include "lns/modification/pair/insert_pair.h" - -#include <forward_list> -#include <memory> - -namespace generator -{ - using ModificationContainer = std::forward_list<std::unique_ptr<AtomicRecreation>>; - - /** - * Abstract class to generate valid modifications - */ - class ModificationGenerator - { - public: - /** - * Adds valid insertions of request to the solution in the list provided as argument - */ - virtual void populate(Solution const &solution, Pair const &, ModificationContainer &modificationList) = 0; - - virtual ~ModificationGenerator() = default; - }; - - /** - * Empty template class to generate ALL valid modification of a specific type - * @tparam T the type of modification to generate - */ - template<std::derived_from<AtomicRecreation> T> - class AllTypedModifications : public ModificationGenerator - { - // this assert will always fail. Needs a template specification - static_assert(sizeof(T) == 0, "The generator for type T has not been defined yet."); - }; - - template<> - class AllTypedModifications<InsertPair> : public ModificationGenerator - { - public: - void populate(Solution const &solution, Pair const &, ModificationContainer &list) override; - }; - - -}// namespace generator \ No newline at end of file diff --git a/src/lns/operators/generators/enumerate.cpp b/src/lns/operators/reconstruction/enumerate.cpp similarity index 52% rename from src/lns/operators/generators/enumerate.cpp rename to src/lns/operators/reconstruction/enumerate.cpp index 963b83d..24fabb6 100644 --- a/src/lns/operators/generators/enumerate.cpp +++ b/src/lns/operators/reconstruction/enumerate.cpp @@ -2,16 +2,25 @@ namespace enumeration { + + template<std::derived_from<AtomicRecreation> ModificationType> + void addToListIfValidTemplate(Solution const &solution, ModificationType const &modification, ModificationContainer &list) + { + if (solution.checkModification(modification)) + { + std::cout << " => Insert Modification" << "\n"; + list.push_front(std::make_unique<ModificationType>(modification)); + } + } + /** * Enumerate InsertPair modifications. - * consumeModification is called for each modification. * Does some checks to cut some loops. (TO DO) * @param solution * @param pair - * @param consumeModification called when a modification is created + * @param ModificationContainer */ - void enumerateAllInsertPair(Solution const &solution, Pair const &pair, - std::function<void(InsertPair &&)> const &consumeModification) + void enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list) { int routeIndex = 0; // Insert into existing routes @@ -22,8 +31,8 @@ namespace enumeration for (int d = p; d <= route.getSize(); 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)); + // add to list if valid modification + enumeration::addToListIfValidTemplate(solution, InsertPair(index, pair), list); } } ++routeIndex; diff --git a/src/lns/operators/generators/enumerate.h b/src/lns/operators/reconstruction/enumerate.h similarity index 51% rename from src/lns/operators/generators/enumerate.h rename to src/lns/operators/reconstruction/enumerate.h index 0e5a827..22cd2e2 100644 --- a/src/lns/operators/generators/enumerate.h +++ b/src/lns/operators/reconstruction/enumerate.h @@ -2,21 +2,29 @@ #include "lns/modification/pair/insert_pair.h" +#include <forward_list> #include <functional> +/** + * A type of enumeration for a specific modification + */ + enum class EnumerationType { + ALL_INSERT_PAIR +}; + + namespace enumeration { + using ModificationContainer = std::forward_list<std::unique_ptr<AtomicRecreation>>; /** * Enumerate InsertDelivery modifications. - * consumeModification is called for each modification. * Does some checks to cut some loops. * @param solution - * @param request - * @param consumeModification called when a modification is created (ex : keepBestSolution) + * @param Pair + * @param list */ - void enumerateAllInsertPair(Solution const &solution, Pair const &Pair, - std::function<void(InsertPair &&)> const &consumeModification); + void enumerateAllInsertPair(Solution const &solution, Pair const &Pair, ModificationContainer &list); }// namespace enumeration diff --git a/src/lns/operators/reconstruction/list_heuristic_insertion.h b/src/lns/operators/reconstruction/list_heuristic_insertion.h index 4570caf..895a47c 100644 --- a/src/lns/operators/reconstruction/list_heuristic_insertion.h +++ b/src/lns/operators/reconstruction/list_heuristic_insertion.h @@ -3,7 +3,6 @@ #include "input/data.h" #include "input/pdptw_data.h" #include "lns/operators/abstract_operator.h" -#include "lns/operators/generators/modification_generator.h" #include "lns/operators/sorting_strategy.h" #include "utils.h" @@ -17,8 +16,6 @@ class AtomicRecreation; * @tparam Strategy defines in which order we are treating the requests * @tparam Generator defines which modifications are going to be used */ -template<std::derived_from<sorting_strategy::SortingStrategy> Strategy, - std::derived_from<generator::ModificationGenerator> Generator> class ListHeuristicInsertion : public ReconstructionOperator { private: @@ -27,7 +24,7 @@ private: public: explicit ListHeuristicInsertion(); - void reconstructSolution(Solution &solution, double blinkRate) const override; + void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const override; private: /** @@ -35,5 +32,5 @@ private: * @return the best insertion found */ static std::unique_ptr<AtomicRecreation> choosingStrategy(Solution &solution, Pair const &pair, - double blinkRate); + double blinkRate, EnumerationType enumeration); }; diff --git a/src/lns/operators/reconstruction/list_heuristic_insertion.hpp b/src/lns/operators/reconstruction/list_heuristic_insertion.hpp index 31deee6..fa24123 100644 --- a/src/lns/operators/reconstruction/list_heuristic_insertion.hpp +++ b/src/lns/operators/reconstruction/list_heuristic_insertion.hpp @@ -1,28 +1,38 @@ #pragma once #include "list_heuristic_insertion.h" +#include "lns/operators/sorting_strategy.h" +#include "enumerate.h" // This is a header, but it does define templates, so we can't put them in .cpp file // for forward declaration you can use the .h file, but if you need to use the class, you must include this one instead -#include "lns/operators/generators/modification_generator.h" #include <concepts> -template<std::derived_from<sorting_strategy::SortingStrategy> Strategy, - std::derived_from<generator::ModificationGenerator> Generator> -ListHeuristicInsertion<Strategy, Generator>::ListHeuristicInsertion() = default; +ListHeuristicInsertion::ListHeuristicInsertion() = default; -template<std::derived_from<sorting_strategy::SortingStrategy> Strategy, - std::derived_from<generator::ModificationGenerator> Generator> -void ListHeuristicInsertion<Strategy, Generator>::reconstructSolution(Solution &solution, double blinkRate) const +void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const { - std::vector<int> sortedPairs = Strategy(solution).sortPairs(); + std::vector<int> sortedPairs; + // selection strategy + switch (strategy) { + case SortingStrategyType::SHUFFLE: + { + std::cout << " \n(Shuffle)\n"; + sortedPairs = sorting_strategy::Shuffle(solution).sortPairs(); + break; + } + default: + spdlog::error("Error, strategy selected."); + break; + } + AtomicRecreationPtr recreation; for (int pairID: sortedPairs) { Pair const &pair = solution.getData().getPair(pairID); - recreation = ListHeuristicInsertion::choosingStrategy(solution, pair, blinkRate); + recreation = ListHeuristicInsertion::choosingStrategy(solution, pair, blinkRate, enumeration); if (recreation) { std::cout << "\n --- Apply recreation --- \n"; @@ -31,17 +41,31 @@ void ListHeuristicInsertion<Strategy, Generator>::reconstructSolution(Solution & } } - -template<std::derived_from<sorting_strategy::SortingStrategy> Strategy, - std::derived_from<generator::ModificationGenerator> Generator> -std::unique_ptr<AtomicRecreation> ListHeuristicInsertion<Strategy, Generator>::choosingStrategy(Solution &solution, - Pair const &pair, - double blinkRate) +std::unique_ptr<AtomicRecreation> ListHeuristicInsertion::choosingStrategy(Solution &solution, Pair const &pair, + double blinkRate, EnumerationType enumeration) { AtomicRecreationPtr bestInsertion; double bestKnownInsertionCost = std::numeric_limits<double>::max(); - generator::ModificationContainer modifications; - Generator().populate(solution, pair, modifications); + + enumeration::ModificationContainer modifications; + //Generator().populate(solution, pair, modifications); + // + + // Enumeration strategy + switch (enumeration) { + case EnumerationType::ALL_INSERT_PAIR: + { + std::cout << " \n(All insert pair) \n"; + //enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list) + enumeration::enumerateAllInsertPair(solution, pair, modifications); + break; + } + default: + spdlog::error("Error, enumeration selected."); + break; + } + + // Keep the modification with the best cost for (AtomicRecreationPtr &possibleRecreation: modifications) { if (util::getRandom() <= 1 - blinkRate) diff --git a/src/lns/operators/sorting_strategy.h b/src/lns/operators/sorting_strategy.h index 590b698..4b33762 100644 --- a/src/lns/operators/sorting_strategy.h +++ b/src/lns/operators/sorting_strategy.h @@ -2,6 +2,13 @@ #include "lns/solution/solution.h" +/** + * A type of sorting strategy for the bank of pairs + */ +enum class SortingStrategyType { + SHUFFLE +}; + namespace sorting_strategy { /** diff --git a/src/mains/main.cpp b/src/mains/main.cpp index fb240d1..654c5c9 100644 --- a/src/mains/main.cpp +++ b/src/mains/main.cpp @@ -22,9 +22,10 @@ #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" +#include "lns/operators/reconstruction/enumerate.h" + #include "output/solution_exporter.h" using json = nlohmann::json; @@ -69,18 +70,14 @@ int main(int argc, char const *argv[]) std::cout << "--- Empty Solution --- \n"; solution.print(); - generator::AllTypedModifications<InsertPair> generator; - generator::ModificationContainer modificationList; - - - //ListHeuristicInsertion<std::derived_from<sorting_strategy::SortingStrategy> Strategy, std::derived_from<generator::ModificationGenerator> Generator> - double blinkRate = 0; + SortingStrategyType strategy = SortingStrategyType::SHUFFLE; + EnumerationType enumeration = EnumerationType::ALL_INSERT_PAIR; - std::cout << "\n --- Operator <SHUFFLE - ALL_INSERTPAIR> -> reconstruction (NO COST UPDATE)\n"; + std::cout << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR -> reconstruction (NO COST UPDATE)\n"; - ListHeuristicInsertion<sorting_strategy::Shuffle, generator::AllTypedModifications<InsertPair>> operatorInstance; - operatorInstance.reconstructSolution(solution, blinkRate); + ListHeuristicInsertion heuristicInsertion; + heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration); solution.print(); -- GitLab