diff --git a/CMakeLists.txt b/CMakeLists.txt index 357cd492e33cedf097373193c8c2ad64420c4303..f9c35183d220599c85263d3930ffbd559597c882 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ add_executable(pdptw src/mains/main.cpp src/lns/modification/route/insert_route_with_pair.cpp src/lns/modification/route/insert_route.cpp src/lns/modification/route/remove_route.cpp + src/output/lns_output.cpp src/output/solution_checker.cpp src/output/solution_exporter.cpp src/lns/operators/sorting_strategy.cpp @@ -42,6 +43,7 @@ add_executable(pdptw src/mains/main.cpp src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp src/lns/operators/selector/operator_selector.cpp src/lns/operators/selector/small_large_selector.cpp + src/lns/lns.cpp src/utils.cpp ) diff --git a/src/input/pdptw_data.cpp b/src/input/pdptw_data.cpp index a21d8e6c858d11c794056d558a2dac1623371b44..9542f7e1253d4230018e53cb1697f616ef11b8f3 100644 --- a/src/input/pdptw_data.cpp +++ b/src/input/pdptw_data.cpp @@ -78,6 +78,12 @@ const Pair &PDPTWData::getPair(int id) const throw std::runtime_error("Pair not found"); } +int PDPTWData::getPairCount() const +{ + return getPairs().size(); +} + + void PDPTWData::print() const { std::cout << "Instance name : " << dataName << "\n"; diff --git a/src/input/pdptw_data.h b/src/input/pdptw_data.h index a0a7ae58e0e3f4f9d1c2bd9445b5f98d1b106269..735cecb85a99ac9630e4829221d942cd4293a875 100644 --- a/src/input/pdptw_data.h +++ b/src/input/pdptw_data.h @@ -1,12 +1,12 @@ #pragma once -#include <nlohmann/json_fwd.hpp> -#include <vector> - -#include "pair.h" #include "location.h" +#include "pair.h" #include "types.h" +#include <nlohmann/json_fwd.hpp> +#include <vector> + using json = nlohmann::json; /** @@ -28,7 +28,7 @@ class PDPTWData int capacity; Location depot; std::vector<Location> locations; - std::vector<Pair> pairs; // std::unordered_map<int, Pair> pair; if getPair(index) is needed ? + std::vector<Pair> pairs;// std::unordered_map<int, Pair> pair; if getPair(index) is needed ? Matrix distanceMatrix; public: @@ -43,7 +43,8 @@ public: * Constructs an empty PDPTWData. * @see parsing::parseJson */ - PDPTWData(std::string dataName, int size, int capacity, Location depot, std::vector<Location> locations, Matrix distanceMatrix); + PDPTWData(std::string dataName, int size, int capacity, Location depot, std::vector<Location> locations, + Matrix distanceMatrix); /** * Checks some data coherence */ @@ -54,8 +55,8 @@ public: std::vector<Location> const &getLocations() const; std::vector<Pair> const &getPairs() const; - - const Pair &getPair(int id) const; + int getPairCount() const; + Pair const &getPair(int id) const; /** * 0 return the depot. diff --git a/src/lns/lns.cpp b/src/lns/lns.cpp index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..661bbf35cdc2523ce42988ca0680f423edc4c032 100644 --- a/src/lns/lns.cpp +++ b/src/lns/lns.cpp @@ -0,0 +1,11 @@ +#include "lns.h" + +output::LnsOutput runLns(Solution const &initialSolution, OperatorSelector &opSelector, AcceptanceFunction const &acceptFunctor) +{ + + // TO DO + + + //auto result = output::LnsOutput(std::move(runtime.bestSolution), runtime.numberOfIteration, getTimeSinceInSec(runtime.start)); + //return result; +} \ No newline at end of file diff --git a/src/lns/lns.h b/src/lns/lns.h index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..be6de6cc1caf73fc20b2fcc84c5f07ce17f9fc5b 100644 --- a/src/lns/lns.h +++ b/src/lns/lns.h @@ -0,0 +1,15 @@ +#pragma once + +#include "output/lns_output.h" + +class Solution; +class OperatorSelector; +class AcceptanceFunction; + +namespace lns +{ + /** + * @param initialSolution must be a valid solution ! + */ + output::LnsOutput runLns(Solution const &initialSolution, OperatorSelector &opSelector, AcceptanceFunction const &acceptFunctor); +}// namespace lns \ No newline at end of file diff --git a/src/lns/operators/abstract_operator.h b/src/lns/operators/abstract_operator.h index 80f3f44635e92223aa18e323523466d13194efa3..470c732082f0025cbf69ea8a020d51213db4e8db 100644 --- a/src/lns/operators/abstract_operator.h +++ b/src/lns/operators/abstract_operator.h @@ -15,6 +15,6 @@ public: class ReconstructionOperator { public: - virtual void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const = 0; + virtual void reconstructSolution(Solution &solution, double blinkRate) const = 0; virtual ~ReconstructionOperator() = default; }; diff --git a/src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp index 47896e8c53b2db1b75a65a724f4be1d9fdf82fb1..55d94f1e231357b1eb4b5a8663c4fb575a0f7bb8 100644 --- a/src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp +++ b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp @@ -1,7 +1,10 @@ #include "list_heuristic_cost_oriented.h" -void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, - EnumerationType enumeration) const +ListHeuristicCostOriented::ListHeuristicCostOriented(SortingStrategyType strategy, EnumerationType enumeration) + : strategy(strategy), enumeration(enumeration) +{} + +void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double blinkRate) const { std::vector<int> sortedPairs; // selection strategy diff --git a/src/lns/operators/reconstruction/list_heuristic_cost_oriented.h b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.h index 24c633f9f92e0a0272349470b72ff2f00276e089..0833c845d5da56b0d22f5721a8989a7b7c5630b2 100644 --- a/src/lns/operators/reconstruction/list_heuristic_cost_oriented.h +++ b/src/lns/operators/reconstruction/list_heuristic_cost_oriented.h @@ -11,10 +11,15 @@ */ class ListHeuristicCostOriented : public ReconstructionOperator { +private: +SortingStrategyType strategy; +EnumerationType enumeration; + public: using AtomicRecreationPtr = std::unique_ptr<AtomicRecreation>; - void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, - EnumerationType enumeration) const override; + + ListHeuristicCostOriented(SortingStrategyType strategy, EnumerationType enumeration); + void reconstructSolution(Solution &solution, double blinkRate) const override; }; /** diff --git a/src/lns/operators/reconstruction/list_heuristic_insertion.cpp b/src/lns/operators/reconstruction/list_heuristic_insertion.cpp index bbe4dedecc7b2af810ed6a6318bcde342ea448fe..e12eacb0f02fef9507e0ba1c1f00034ab8bd83a2 100644 --- a/src/lns/operators/reconstruction/list_heuristic_insertion.cpp +++ b/src/lns/operators/reconstruction/list_heuristic_insertion.cpp @@ -7,9 +7,11 @@ #include <concepts> -ListHeuristicInsertion::ListHeuristicInsertion() = default; +ListHeuristicInsertion::ListHeuristicInsertion(SortingStrategyType strategy, EnumerationType enumeration) + : strategy(strategy), enumeration(enumeration) +{} -void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const +void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blinkRate) const { std::vector<int> sortedPairs; // selection strategy diff --git a/src/lns/operators/reconstruction/list_heuristic_insertion.h b/src/lns/operators/reconstruction/list_heuristic_insertion.h index 395f88e29ea1a1b7dd1611b2ff68369d3ed29ff2..66f1e985f281462a53c55fff5347c1b8c576c901 100644 --- a/src/lns/operators/reconstruction/list_heuristic_insertion.h +++ b/src/lns/operators/reconstruction/list_heuristic_insertion.h @@ -22,10 +22,11 @@ private: using AtomicRecreationPtr = std::unique_ptr<AtomicRecreation>; public: - explicit ListHeuristicInsertion(); + explicit ListHeuristicInsertion(SortingStrategyType strategy, EnumerationType enumeration); - void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, - EnumerationType enumeration) const override; + SortingStrategyType strategy; + EnumerationType enumeration; + void reconstructSolution(Solution &solution, double blinkRate) const override; private: /** diff --git a/src/mains/main.cpp b/src/mains/main.cpp index 41d5485992ee9fc2575541a09ea5379e8b484872..db4f2f9c4e8605f0f185b2d57fc96cbe9f60a153 100644 --- a/src/mains/main.cpp +++ b/src/mains/main.cpp @@ -16,6 +16,8 @@ #include "lns/constraints/time_window/time_window_constraint.h" #include "lns/operators/destruction/random_destroy.h" #include "lns/operators/reconstruction/list_heuristic_cost_oriented.h" +#include "lns/operators/selector/operator_selector.h" +#include "lns/operators/selector/small_large_selector.h" #include "lns/solution/solution.h" #include "lns/modification/pair/insert_pair.h" #include "lns/modification/route/insert_route.h" @@ -27,44 +29,68 @@ #include "lns/operators/reconstruction/enumerate.h" +#include "mains/main_interface.h" #include "output/solution_exporter.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 - int pair = item->getAddedPairs(); - if (pair > 0) { - std::cout << "Added Location ID: \n"; - std::cout << pair << "\n"; - } else { - std::cout << "No location added.\n"; - } - std::cout << "} \n"; - ++cpt; - } +void simpleLNS(PDPTWData const &data, Solution &startingSolution) +{ + // lns parameters + int requests = data.getPairCount(); + + int pairs = requests * 2 / 100; + int manyPairs = requests * 40 / 100; + + // threshold function to do + + + // lns operators + SimpleOperatorSelector smallSelector; + addAllReconstructor(smallSelector); + smallSelector.addDestructor(RandomDestroy(pairs)); + + SimpleOperatorSelector largeSelector; + addAllReconstructor(largeSelector); + largeSelector.addDestructor(RandomDestroy(pairs)); + + SimpleOperatorSelector veryLargeSelector; + addAllReconstructor(veryLargeSelector); + veryLargeSelector.addDestructor(RandomDestroy(pairs)); + + SimpleOperatorSelector hugeSelector; + addAllReconstructor(hugeSelector); + hugeSelector.addDestructor(RandomDestroy(pairs)); + + SimpleOperatorSelector lastSelector; + addAllReconstructor(lastSelector); + lastSelector.addDestructor(RandomDestroy(manyPairs)); + + std::vector<SmallLargeOperatorSelector::StepSelector> selectors; + selectors.emplace_back(500, std::move(smallSelector)); + selectors.emplace_back(1000, std::move(largeSelector)); + selectors.emplace_back(1000, std::move(veryLargeSelector)); + selectors.emplace_back(3000, std::move(hugeSelector)); + selectors.emplace_back(1, std::move(lastSelector)); + SmallLargeOperatorSelector smallLargeSelector(std::move(selectors)); + + // run lns + //lns::runLns(startingSolution, smallLargeSelector, acceptor); } int main(int argc, char const *argv[]) { - //std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/test_inst.json"; //std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/n100/bar-n100-1.json"; std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/Nantes_1.json"; //std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/n5000/bar-n5000-1.json"; - + ///////////////////////////////////////////////////////////////////////:: // std::cout << filepath << "\n"; - // PDPTWData data = parsing::parseJson(filepath); - // data.checkData(); - // data.print(); // std::cout << " \n"; diff --git a/src/mains/main_interface.cpp b/src/mains/main_interface.cpp index aeb283a90dc1c91e79f031d65c316b4196da484c..aeae80f34b5182c8f5c86687a4edcf29026f27ab 100644 --- a/src/mains/main_interface.cpp +++ b/src/mains/main_interface.cpp @@ -6,6 +6,11 @@ #include <nlohmann/json.hpp> #include <spdlog/spdlog.h> +void addAllReconstructor(SimpleOperatorSelector &selector) +{ + selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::SHUFFLE, EnumerationType::ALL_INSERT_PAIR)); +} + int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solution &)> function) { diff --git a/src/mains/main_interface.h b/src/mains/main_interface.h index 5efebfec400abd85c037c1d328c9bfe2930ab759..b4828d5436bed6c4428303abf1c6a8ee763f66cd 100644 --- a/src/mains/main_interface.h +++ b/src/mains/main_interface.h @@ -1,8 +1,12 @@ #pragma once #include "input/pdptw_data.h" +#include "lns/operators/reconstruction/list_heuristic_cost_oriented.h" +#include "lns/operators/selector/operator_selector.h" #include "lns/solution/solution.h" #include <functional> +void addAllReconstructor(SimpleOperatorSelector &selector); int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solution &)> function); + diff --git a/src/output/lns_output.cpp b/src/output/lns_output.cpp new file mode 100644 index 0000000000000000000000000000000000000000..95e75adc11be3945503a7599f93d4f417c4b1924 --- /dev/null +++ b/src/output/lns_output.cpp @@ -0,0 +1,27 @@ +#include "lns_output.h" + +#include "output/solution_exporter.h" + +unsigned int output::LnsOutput::getNumberOfIteration() const +{ + return numberOfIteration; +} + +Solution const &output::LnsOutput::getBestSolution() const +{ + return bestSolution; +} + +unsigned long output::LnsOutput::getTimeSpent() const +{ + return timeSpent; +} + +output::LnsOutput::LnsOutput(Solution &&bestSolution, unsigned int numberOfIteration, unsigned long timeSpent) + : bestSolution(std::move(bestSolution)), numberOfIteration(numberOfIteration), timeSpent(timeSpent) +{} + +void output::LnsOutput::writeSolutionToFile() const +{ + output::exportToJson(getBestSolution()); +} \ No newline at end of file diff --git a/src/output/lns_output.h b/src/output/lns_output.h new file mode 100644 index 0000000000000000000000000000000000000000..9b7c25a5eafabdcb08a8d7165412a8390ecbced9 --- /dev/null +++ b/src/output/lns_output.h @@ -0,0 +1,20 @@ +#pragma once + +#include "lns/solution/solution.h" + +namespace output +{ + class LnsOutput + { + Solution bestSolution; + unsigned int numberOfIteration; + unsigned long timeSpent; + + public: + LnsOutput(Solution &&bestSolution, unsigned int numberOfIteration, unsigned long timeSpent); + unsigned int getNumberOfIteration() const; + Solution const &getBestSolution() const; + unsigned long getTimeSpent() const; + void writeSolutionToFile() const; + }; +}// namespace output \ No newline at end of file diff --git a/src/output/solution_checker.cpp b/src/output/solution_checker.cpp index b86ab63f46d575f0290c27bdb108f59dbedea007..36ab18cb63d62263070bbdeee369feb4cc43f25f 100644 --- a/src/output/solution_checker.cpp +++ b/src/output/solution_checker.cpp @@ -57,7 +57,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data) std::cout << "#"; // checking PairBank coherence (given the routes) - std::vector<int> testbank = sol.getBank(); for (int pairID: sol.getBank()) { // check goes from 0 et n-1