diff --git a/src/config.h b/src/config.h index 7e6911c0866444ff327301911f4bfb11f01c11a0..574c5e47e7dbdda1b106a01ff7c31ca973a24e9a 100644 --- a/src/config.h +++ b/src/config.h @@ -4,4 +4,4 @@ const int EXCLUSION_PENALTY = 100; const int RANDOM_SEED = 100; -const int NUMBER_VEHICLE = 5; \ No newline at end of file +const int NUMBER_VEHICLE = 10; \ No newline at end of file diff --git a/src/lns/lns.cpp b/src/lns/lns.cpp index 278cd0969e7113c30a2eb91a683b1b079ac2bf75..5670a48101aaca73a25b4fe3cb142aacf5a7c94e 100644 --- a/src/lns/lns.cpp +++ b/src/lns/lns.cpp @@ -4,6 +4,8 @@ #include "lns/operators/selector/operator_selector.h" #include "output/solution_checker.h" +#include <chrono> + namespace { bool isBetterSolution(Solution const &candidateSolution, Solution const &bestKnownSol) @@ -11,22 +13,82 @@ namespace return candidateSolution.getCost() < bestKnownSol.getCost(); } + using lns_clock = std::chrono::high_resolution_clock; + using lns_time_point = std::chrono::time_point<lns_clock, std::chrono::nanoseconds>; + + struct LnsRuntimeData + { + Solution bestSolution; + unsigned int numberOfIteration = 0; + lns_time_point start = lns_clock::now(); + }; + + /** + * @return the number of seconds between point and now (the moment the function is called). + */ + unsigned long getTimeSinceInSec(lns_time_point point) + { + return std::chrono::duration_cast<std::chrono::seconds>(lns_clock::now() - point).count(); + } + + unsigned long getTimeSinceInMs(lns_time_point point) + { + return std::chrono::duration_cast<std::chrono::milliseconds>(lns_clock::now() - point).count(); + } + + bool triggerLogProgress(LnsRuntimeData const &) + { + static auto lastTrigger = lns_clock::now(); + if (getTimeSinceInSec(lastTrigger) >= 10) + { + lastTrigger = lns_clock::now(); + return true; + } + return false; + } + + void logProgress(LnsRuntimeData const &runtime, Solution const &actualSolution) + { + if (triggerLogProgress(runtime)) + { + unsigned long actualTime = getTimeSinceInMs(runtime.start); + double iterPerSecond = 1000 * runtime.numberOfIteration / static_cast<double>(actualTime); + std::string speedLog; + if (iterPerSecond < 1) + { + speedLog = fmt::format("{}s/100 iterations", 100 / iterPerSecond); + } + else + { + speedLog = fmt::format("{:.1f} i/s", iterPerSecond); + } + std::string missingRequestLog; + long requestsMissing = runtime.bestSolution.missingPairCount(); + //... log TO DO + } + } + }// namespace output::LnsOutput lns::runLns(Solution const &initialSolution, OperatorSelector &opSelector, - AcceptanceFunction const &acceptFunctor) + AcceptanceFunction const &acceptFunctor) { /** * The solution is the base solution used to create the neighbor solution. * It is constant unless we accept the candidate solution. */ Solution actualSolution = initialSolution; - Solution bestSolution = initialSolution; + LnsRuntimeData runtime = {actualSolution}; - int it = 100; - while (it > 0) - { - std::cout << "\n" << 101-it << " : "; + // temporary + int iterationMax = 200; + while (iterationMax > 0) + { + // Init iteration + ++runtime.numberOfIteration; + logProgress(runtime, actualSolution); + + std::cout << "\n" << runtime.numberOfIteration << " : "; /** * The solution on which we apply the operators. * It is discarded at the end of each loop if it is not accepted by the Acceptance Function. @@ -40,24 +102,26 @@ output::LnsOutput lns::runLns(Solution const &initialSolution, OperatorSelector destructReconstructPair.reconstructor().reconstructSolution(candidateSolution, 0.01); candidateSolution.computeAndStoreSolutionCost(); // Update best solution - if (isBetterSolution(candidateSolution, bestSolution)) + if (isBetterSolution(candidateSolution, runtime.bestSolution)) { std::cout << "\n > new Best Solution \n"; checker::checkAll(candidateSolution, candidateSolution.getData(), false); - bestSolution = candidateSolution; + runtime.bestSolution = candidateSolution; opSelector.betterSolutionFound(); } // Check if we use the candidate solution as the new actual solution // operator can force to take the new solution if (destructReconstructPair.forceTakeSolution() || - acceptFunctor(candidateSolution, actualSolution, bestSolution) == AcceptationStatus::ACCEPT) + acceptFunctor(candidateSolution, actualSolution, runtime.bestSolution) == AcceptationStatus::ACCEPT) { actualSolution = std::move(candidateSolution); } - --it; + --iterationMax; } - auto result = output::LnsOutput(std::move(bestSolution), it, it); + + 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/solution/solution.cpp b/src/lns/solution/solution.cpp index 797f8c79e9eefce67a93a547c21cb6c7668a51ff..1bb0132f589df8b07343f6a32ea4f4eb310d7a5b 100644 --- a/src/lns/solution/solution.cpp +++ b/src/lns/solution/solution.cpp @@ -231,6 +231,12 @@ int Solution::getRouteIDOf(int locationID) const return -1; } +unsigned int Solution::missingPairCount() const +{ + return pairBank.size(); +} + + bool Solution::checkModification(AtomicRecreation const &modification) const { //std::cout << "--- Check Modification Validity : "; diff --git a/src/lns/solution/solution.h b/src/lns/solution/solution.h index 59f6a4bc1a585b44fce93ea6566174836a3204f1..874c74186ad96bb9c2d2a18fc656fd1cc10f2815 100644 --- a/src/lns/solution/solution.h +++ b/src/lns/solution/solution.h @@ -76,7 +76,8 @@ public: PDPTWData const &getData() const; double getRawCost() const; double getCost() const; - + unsigned int missingPairCount() const; + /** * Return the route index associated to the given location ID. * -1 if the location is not in a route. diff --git a/src/mains/main.cpp b/src/mains/main.cpp index 889b5b3c8e1edf769db43b45fd50c53ada07d8c7..6228eab50ce71e01e39d918762e395cb54d31b6d 100644 --- a/src/mains/main.cpp +++ b/src/mains/main.cpp @@ -77,7 +77,10 @@ void simpleLNS(PDPTWData const &data, Solution &startingSolution) // run lns output::LnsOutput result = lns::runLns(startingSolution, smallLargeSelector, acceptor); + + result.getBestSolution().print(); + std::cout << result.getNumberOfIteration() << " " << result.getTimeSpent() << std::endl; } int main(int argc, char **argv) @@ -86,7 +89,8 @@ int main(int argc, char **argv) /////////////////////////////////////////////////////////////////////// - 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/n100/bar-n100-1.json"; + std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/pdp_100/lc101.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";