Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • a24jacqb/pdptw-main
1 result
Show changes
Commits on Source (3)
  • awenjb's avatar
    Add Route Penalty · 4b30bfec
    awenjb authored
    4b30bfec
  • awenjb's avatar
    Some fixes · 7c427502
    awenjb authored
    - call clean empty route for every new best solution
    - add new elements in the config  file
    - clean up some of the code
    7c427502
  • awenjb's avatar
    Add code to run multiple instances · e462496a
    awenjb authored
    - add code to run multiple instances and store the result in a specific directory
    - add new config
    - add a complete json output
    e462496a
Showing
with 341 additions and 181 deletions
......@@ -49,6 +49,7 @@ add_executable(pdptw src/mains/main.cpp
src/lns/operators/selector/small_large_selector.cpp
src/lns/lns.cpp
src/utils.cpp
src/output/run.cpp
)
target_link_libraries(pdptw PRIVATE CLI11::CLI11 nlohmann_json::nlohmann_json spdlog::spdlog)
......
......@@ -188,7 +188,7 @@ end
function euclidean_distance(x1, y1, x2, y2)
return round(sqrt((x2 - x1)^2 + (y2 - y1)^2), digits=2)
return sqrt((x2 - x1)^2 + (y2 - y1)^2)
end
......
const int EXCLUSION_PENALTY = 100;
#include <string>
const int RANDOM_SEED = 100;
// Parameters
const int NUMBER_VEHICLE = 20;
\ No newline at end of file
// Penalty for excluding a certain pickup-delivery pair, aims to minimize the number of excluded pairs.
int const EXCLUSION_PENALTY = 1000000;
// Penalty applied to a route, aims to minimize the number of routes.
int const ROUTE_PENALTY = 0;
// Number of vehicles involved at the start of the optimization process (cannot be increased).
int const NUMBER_VEHICLE = 20;
// Number of iterations for the algorithm or simulation to run.
int const NUMBER_ITERATION = 500;
// Flags
// Flag indicating whether the random seed has been set (true means it is set).
bool const SEED_SET = true;
// Seed for random number generation (ensures reproducibility).
int const RANDOM_SEED = 100;
// Flag indicating whether we print during the execution.
bool const PRINT = true;
// Flag indicating whether the final solution is stored.
bool const STORE_SOLUTION = true;
// Flag indicating whether the solution is stored with complete information or not.
bool const COMPLETE_STORE = true;
// Directories
std::string const OUTPUT_DIRECTORY = "./../../output/100_complete";
\ No newline at end of file
#include "simulated_annealing_acceptance.h"
#pragma once
#include "acceptance_function.h"
class SimulatedAnnealingAcceptance : public AcceptanceFunction
{
};
\ No newline at end of file
#include "lns.h"
#include "lns/acceptance/acceptance_function.h"
#include "lns/operators/destruction/clean_empty_route.h"
#include "lns/operators/selector/operator_selector.h"
#include "output/solution_checker.h"
#include "config.h"
#include <chrono>
......@@ -81,7 +83,7 @@ output::LnsOutput lns::runLns(Solution const &initialSolution, OperatorSelector
LnsRuntimeData runtime = {actualSolution};
// temporary fixed iteration
int iterationMax = 100;
int iterationMax = NUMBER_ITERATION;
while (iterationMax > 0)
{
// Init iteration
......@@ -107,6 +109,10 @@ output::LnsOutput lns::runLns(Solution const &initialSolution, OperatorSelector
std::cout << "\n > new Best Solution \n";
checker::checkAll(candidateSolution, candidateSolution.getData(), false);
// remove empty route from the solution
CleanEmptyRoute clean = CleanEmptyRoute();
clean.destroySolution(candidateSolution);
runtime.bestSolution = candidateSolution;
opSelector.betterSolutionFound();
}
......
......@@ -5,7 +5,6 @@ CleanEmptyRoute::CleanEmptyRoute() {}
void CleanEmptyRoute::destroySolution(Solution &solution) const
{
std::cout << "Clean ";
for (int routeIndex = solution.getRoutes().size() - 1; routeIndex >= 0; --routeIndex)
{
if (solution.getRoute(routeIndex).getRoute().empty())
......
......@@ -11,7 +11,7 @@ void RandomDestroy::destroySolution(Solution &solution) const
{
std::cout << "RD ";
int nbRequests = solution.requestsFulFilledCount();
int nbRequests = solution.requestsFulfilledCount();
int actualNumberOfPairsToDestroy = std::min(nbRequests, numberOfPairsToDestroy);
int remainingPairToDelete = actualNumberOfPairsToDestroy;
......
#pragma once
#include <vector>
#include "input/pdptw_data.h"
#include "input/time_window.h"
/**
* Represent a route for the PDPTW
* A route does not include the depot at the begining and the end !
* Represents a route for the PDPTW.
* A route does not include the depot at the beginning and the end.
*/
class Route
{
private:
std::vector<int> route;
int cost;
public:
std::vector<int> route; // Stores the route as a sequence of location IDs.
int cost; // The cost of the route.
public:
// Constructors
Route();
Route(std::vector<int> route, int cost);
// Getters
int getCost() const;
const std::vector<int> & getRoute() const;
const std::vector<int>& getRoute() const;
// get Location
int getLocation(int index) const;
// Get the location at a given index in the route
int getLocation(int index) const;
/**
* Given a locationID, return the Index in the route.
* return -1 if no such location.
* Given a locationID, returns the index in the route.
* @return -1 if the locationID is not found in the route.
*/
int getIndex(int locationID) const;
/**
* Given the position of a location in a route, return the paired location position.
* Example, a pair of location ID 3 and 4 are in a route at position 7 and 18,
* getPairLocationPosition(7) must return 18 and vice versa.
* Given the position of a location in the route, returns the paired location position.
* Example: if location ID 3 and 4 are in the route at positions 7 and 18,
* getPairLocationPosition(7) should return 18 and vice versa.
*/
int getPairLocationPosition(int position, const PDPTWData &data) const;
int getPairLocationPosition(int position, const PDPTWData& data) const;
// Utility function to print the route details
void print() const;
/**
* Add a location index in the route (does not update the route cost)
* Adds a location index in the route at a specified position.
* Does not update the route cost.
*/
void insertAt(int locationIndex, int position);
/*
* Remove the element at "position"
*/
/**
* Removes the element at the specified position in the route.
*/
void deleteAt(int position);
// Returns the number of locations in the route
int getSize() const;
};
\ No newline at end of file
......@@ -30,7 +30,7 @@ void Solution::initRoutes()
routes.clear();
for (unsigned int i = 0; i < NUMBER_VEHICLE; ++i)
{
this->routes.emplace_back();
routes.emplace_back();
}
}
......@@ -44,8 +44,6 @@ void Solution::initConstraints()
void Solution::computeAndStoreSolutionCost()
{
rawCost = computeSolutionCost();
// add penalty for solution in the pairBank ?
totalCost = rawCost + computePenalisation();
}
......@@ -61,7 +59,20 @@ double Solution::computeSolutionCost() const
double Solution::computePenalisation() const
{
return getBank().size() * EXCLUSION_PENALTY;
return getBank().size() * EXCLUSION_PENALTY + getNumberOfRoutes() * ROUTE_PENALTY;
}
int Solution::getNumberOfRoutes() const
{
int count = 0;
for (Route const &route: getRoutes())
{
if (!route.getRoute().empty())
{
count++;
}
}
return count;
}
void Solution::init()
......@@ -84,7 +95,7 @@ Solution::Solution(PDPTWData const &data) : data(data)
Solution Solution::emptySolution(PDPTWData const &data)
{
Solution sol = Solution(data);
Solution sol(data);
return sol;
}
......@@ -97,19 +108,14 @@ Solution::Solution(Solution const &rhs) : Solution(rhs.getData())
Solution &Solution::operator=(Solution const &rhs)
{
if (&rhs == this)
{
return *this;
}
if (this == &rhs) return *this;
data = rhs.data;
rawCost = rhs.rawCost;
totalCost = rhs.totalCost;
pairBank = rhs.pairBank;
routes.clear();
routes = rhs.routes;
constraints.clear();
std::ranges::transform(rhs.constraints, std::back_inserter(constraints), [this](auto const &constraintPtr) {
return constraintPtr->clone(*this);
......@@ -118,21 +124,18 @@ Solution &Solution::operator=(Solution const &rhs)
return *this;
}
Solution::Solution(Solution &&sol) noexcept : data(sol.data)
Solution::Solution(Solution &&sol) noexcept : data(std::move(sol.data))
{
*this = std::move(sol);
}
Solution &Solution::operator=(Solution &&sol) noexcept
{
if (&sol == this)
{
return *this;
}
if (this == &sol) return *this;
data = sol.data;
rawCost = sol.rawCost;
totalCost = sol.totalCost;
data = std::move(sol.data);
rawCost = std::move(sol.rawCost);
totalCost = std::move(sol.totalCost);
pairBank = std::move(sol.pairBank);
routes = std::move(sol.routes);
......@@ -211,7 +214,7 @@ std::vector<std::unique_ptr<Constraint>> const &Solution::getConstraints() const
return constraints;
}
int Solution::requestsFulFilledCount() const
int Solution::requestsFulfilledCount() const
{
int count = 0;
for (Route const &route: getRoutes())
......@@ -242,34 +245,30 @@ unsigned int Solution::missingPairCount() const
return pairBank.size();
}
bool Solution::checkModification(AtomicRecreation const &modification) const
{
//std::cout << "--- Check Modification Validity : ";
ModificationCheckVariant const &checkVariant = modification.asCheckVariant();
// visitor pattern
for (std::unique_ptr<Constraint> const &constraint: constraints)
for (auto const &constraint: constraints)
{
if (!constraint->checkVariant(checkVariant))
{
//std::cout << "\n";
return false;
}
}
//std::cout << "\n";
return true;
}
void Solution::beforeApplyModification(AtomicModification &modification)
{
// pre modification check
// Pre-modification check
check();
}
void Solution::afterApplyModification(AtomicModification &modification)
{
// constraint status update
for (std::unique_ptr<Constraint> &constraint: constraints)
// Constraint status update
for (auto &constraint: constraints)
{
constraint->applyVariant(modification.asApplyVariant());
}
......@@ -278,9 +277,9 @@ void Solution::afterApplyModification(AtomicModification &modification)
void Solution::applyRecreateSolution(AtomicRecreation &modification)
{
beforeApplyModification(modification);
modification.modifySolution(*this);
// we update the request bank
// Update the request bank
if (int pairID = modification.getAddedPairs())
{
pairBank.erase(std::ranges::find(pairBank, pairID));
......@@ -292,12 +291,10 @@ void Solution::applyRecreateSolution(AtomicRecreation &modification)
void Solution::applyDestructSolution(AtomicDestruction &modification)
{
beforeApplyModification(modification);
modification.modifySolution(*this);
// updating request bank
std::vector<int> const &deletedPair = modification.getDeletedPairs();
//pairBank.reserve(pairBank.size() + deletedPair.size());
// Update the request bank
std::vector<int> const &deletedPair = modification.getDeletedPairs();
pairBank.insert(pairBank.end(), deletedPair.begin(), deletedPair.end());
afterApplyModification(modification);
......@@ -310,17 +307,16 @@ void Solution::check() const
void Solution::print() const
{
std::cout << "\nRawCost : " << rawCost << "\n"
<< "TotalCost : " << totalCost << "\n";
std::cout << "Pair Bank : \n";
std::cout << "\nRawCost: " << rawCost << "\n"
<< "TotalCost: " << totalCost << "\n";
std::cout << "Pair Bank:\n";
for (int const id: getBank())
{
std::cout << id << ", ";
}
std::cout << "\nRoutes : \n";
std::cout << "\nRoutes:\n";
int i = 0;
for (Route const &route: getRoutes())
{
......@@ -329,10 +325,11 @@ void Solution::print() const
++i;
}
std::cout << "Constraints : \n";
for (std::unique_ptr<Constraint> const &constraint: constraints)
std::cout << "Constraints:\n";
for (auto const &constraint: constraints)
{
constraint->print();
}
std::cout << "\n";
}
\ No newline at end of file
}
......@@ -6,6 +6,7 @@
#include "route.h"
#include <iostream>
#include <memory>
#include <spdlog/spdlog.h>
#include <vector>
......@@ -15,8 +16,8 @@ class AtomicDestruction;
class TimeWindowConstraint;
class CapacityConstraint;
/**
* Represent a solution of PDPTW
/*
* Represents a solution of the PDPTW problem.
*/
class Solution
{
......@@ -24,134 +25,169 @@ public:
using PairBank = std::vector<int>;
private:
std::reference_wrapper<PDPTWData const> data;
//PDPTWData const &data;
/*
* Store IDs of a pairs (Pickup & Delivery) that are not assigned yet to a route.
*/
PairBank pairBank;
/*
* Vector of routes representing the solution
*/
std::vector<Route> routes;
std::reference_wrapper<const PDPTWData> data;// Reference to PDPTW data
PairBank pairBank; // Unassigned pairs (Pickup & Delivery)
std::vector<Route> routes; // Routes in the solution
double rawCost;
double totalCost;
std::vector<std::unique_ptr<Constraint>> constraints;
public:
//========CONSTRUCTORS, COPY, MOVE, DESTRUCTORS===========
/**
* Expected way to construct a solution.
* Generate an empty solution with all pairs in the pairBank and one empty route.
/*
* Creates an empty solution with all pairs in the pairBank and one empty route.
*/
static Solution emptySolution(PDPTWData const &data);
/**
* In depth copy of the solution
/*
* In-depth copy of the solution.
*/
Solution(Solution const &);
/**
* In depth copy of the solution
/*
* Copy assignment.
*/
Solution &operator=(Solution const &);
/*
* Move constructor.
*/
Solution(Solution &&) noexcept;
/*
* Move assignment.
*/
Solution &operator=(Solution &&) noexcept;
/*
* Destructor.
*/
~Solution() noexcept;
/*
* Constructs a solution with given data.
*/
explicit Solution(PDPTWData const &data);
/**
* For testing/debugging.
* Use emptySolution(const PDPTWData &data) to create an initial empty solution.
/*
* Constructs a solution with specified parameters.
*/
Solution(PDPTWData const &data, Solution::PairBank pairbank, std::vector<Route> routes, double routeCost,
double totalCost);
Solution(PDPTWData const &data, PairBank pairbank, std::vector<Route> routes, double routeCost, double totalCost);
/*
* Returns the pair bank.
*/
PairBank const &getBank() const;
/*
* Returns the pair bank.
*/
PairBank const &getPairBank() const;
/*
* Returns a mutable reference to the pair bank.
*/
PairBank &getPairBank();
/*
* Returns the list of routes.
*/
std::vector<Route> const &getRoutes() const;
/*
* Returns a mutable reference to a specific route.
*/
Route &getRoute(int routeIndex);
/*
* Returns a constant reference to a specific route.
*/
Route const &getRoute(int routeIndex) const;
/*
* Returns the PDPTW data reference.
*/
PDPTWData const &getData() const;
/*
* Returns the raw cost of the solution.
*/
double getRawCost() const;
/*
* Returns the total cost of the solution.
*/
double getCost() const;
/*
* Returns the number of routes.
*/
int getNumberOfRoutes() const;
/*
* Returns the count of missing pairs.
*/
unsigned int missingPairCount() const;
/*
* Returns the constraints applied to the solution.
*/
std::vector<std::unique_ptr<Constraint>> const &getConstraints() const;
/**
* Return the route index associated to the given location ID.
* -1 if the location is not in a route.
/*
* Returns the route index associated with a given location ID, or -1 if not in a route.
*/
int getRouteIDOf(int locationID) const;
/**
* Return the number of fullfilled requests.
* The solution must be consistent !
* (compute this number by looking at the size of each routes)
/*
* Returns the number of fulfilled requests.
*/
int requestsFulFilledCount() const;
/**
* Check that the modification is valid regarding all the constraints
* @param modification
* @return true if the modification is valid
int requestsFulfilledCount() const;
/*
* Checks if the modification is valid according to all constraints.
*/
bool checkModification(AtomicRecreation const &modification) const;
// using solution checker to verify that the solution is correct. Most used for debug as it is correctness oriented and not performance oriented
/*
* Verifies the correctness of the solution, mainly for debugging.
*/
void check() const;
/**
* Pre modification check.
* @param modification Must be a valid modification.
/*
* Pre-modification check. The modification must be valid.
*/
void beforeApplyModification(AtomicModification &modification);
/**
* Update constraints, it is expected that the solution has already been modified.
* @param modification Must be a valid modification.
/*
* Updates constraints after modification is applied.
*/
void afterApplyModification(AtomicModification &modification);
/**
* Apply the given the modification on the solution. Does not check validity.
* @param modification Must be a valid recreation.
/*
* Applies recreation modification to the solution without validity checks.
*/
void applyRecreateSolution(AtomicRecreation &modification);
/**
* Apply the given the modification on the solution. Does not check validity.
* @param modification Must be a destruction.
/*
* Applies destruction modification to the solution without validity checks.
*/
void applyDestructSolution(AtomicDestruction &modification);
/*
* Computes and returns the penalty value.
*/
double computePenalisation() const;
// For route modification
/*
* Returns a mutable reference to the routes.
*/
std::vector<Route> &getRoutes();
Route &getRoute(int routeIndex);
/*
* Prints the solution details.
*/
void print() const;
/*
* Computes and stores the total solution cost.
*/
void computeAndStoreSolutionCost();
private:
/**
* Does the initialisation of the object, called by the constructor
/*
* Initializes the object, called by the constructor.
*/
void init();
/**
* Init/reset the constraints of the problem
/*
* Initializes or resets the problem constraints.
*/
void initConstraints();
/*
* Initializes the routes.
*/
void initRoutes();
/*
* Initializes the pair bank.
*/
void initPairBank();
/**
* Compute the cost of the solution (routes cost)
/*
* Computes the total cost of the solution.
*/
double computeSolutionCost() const;
};
\ No newline at end of file
double computeSolutionCost() const;
};
......@@ -28,6 +28,8 @@
#include "output/solution_checker.h"
#include "output/solution_exporter.h"
#include "types.h"
#include "output/run.h"
#include "config.h"
#include <filesystem>
#include <fstream>
......@@ -49,7 +51,7 @@ void simpleLNS(PDPTWData const &data, Solution &startingSolution)
int pairs = requests * 2 / 100;
int manyPairs = requests * 40 / 100;
// threshold function to do
// threshold function
ThresholdAcceptance acceptor(0.05);
// lns operators
......@@ -73,11 +75,10 @@ void simpleLNS(PDPTWData const &data, Solution &startingSolution)
// run lns
output::LnsOutput result = lns::runLns(startingSolution, smallLargeSelector, acceptor);
Solution sol = result.getBestSolution();
CleanEmptyRoute clean = CleanEmptyRoute();
clean.destroySolution(sol);
sol.print();
if (STORE_SOLUTION)
{
output::exportToJson(result);
}
}
int main(int argc, char **argv)
......@@ -86,14 +87,17 @@ 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/pdp_100/lc102.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/lc103.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";
PDPTWData data = parsing::parseJson(filepath);
Solution startingSolution = Solution::emptySolution(data);
simpleLNS(data, startingSolution);
// PDPTWData data = parsing::parseJson(filepath);
// Solution startingSolution = Solution::emptySolution(data);
// simpleLNS(data, startingSolution);
std::string path = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/pdp_100";
runAllInDirectory(path, simpleLNS);
return 0;
}
......@@ -20,8 +20,3 @@ unsigned long output::LnsOutput::getTimeSpent() const
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
......@@ -15,6 +15,5 @@ namespace output
unsigned int getNumberOfIteration() const;
Solution const &getBestSolution() const;
unsigned long getTimeSpent() const;
void writeSolutionToFile() const;
};
}// namespace output
\ No newline at end of file
#include "run.h"
#include "input/json_parser.h"
#include "lns/lns.h"
namespace fs = std::filesystem;
std::vector<std::string> getFilesInDirectory(std::string const &directoryPath)
{
std::vector<std::string> filePaths;
try
{
for (auto const &entry: fs::directory_iterator(directoryPath))
{
if (entry.is_regular_file())
{
filePaths.push_back(entry.path().string());
}
}
} catch (std::filesystem::filesystem_error const &e)
{
std::cerr << "Error : " << e.what() << std::endl;
}
return filePaths;
}
void runAllInDirectory(std::string const &directoryPath, std::function<void(PDPTWData &, Solution &)> function)
{
std::vector<std::string> files = getFilesInDirectory(directoryPath);
for (std::string file: files)
{
PDPTWData data = parsing::parseJson(file);
Solution startingSolution = Solution::emptySolution(data);
function(data, startingSolution);
}
}
#pragma once
#include "input/pdptw_data.h"
#include "lns/solution/solution.h"
#include <functional>
#include <iostream>
#include <vector>
#include <string>
#include <filesystem>
std::vector<std::string> getFilesInDirectory(const std::string& directoryPath);
void runAllInDirectory(const std::string& directoryPath, std::function<void(PDPTWData &, Solution &)> function);
\ No newline at end of file
#include "solution_exporter.h"
#include "config.h"
std::string getCurrentDate()
{
std::time_t t = std::time(nullptr);
......@@ -30,17 +32,35 @@ nlohmann::ordered_json output::getMinimalJson(Solution const &solution)
return jsonSolution;
}
nlohmann::ordered_json output::getCompleteJson(Solution const &solution)
nlohmann::ordered_json output::getCompleteJson(Solution const &solution, int iteration, double time)
{
nlohmann::ordered_json jsonSolution;
// TO DO
nlohmann::ordered_json jsonRoutes = nlohmann::ordered_json::array();
int routeID = 0;
for (auto const &route: solution.getRoutes())
{
jsonRoutes.push_back(routeToJson(routeID, route));
++routeID;
}
jsonSolution["InstanceName"] = solution.getData().getDataName();
jsonSolution["Authors"] = "...";
jsonSolution["Date"] = getCurrentDate();
jsonSolution["Reference"] = "...";
jsonSolution["Cost"] = std::ceil(solution.getRawCost() * 100.0) / 100.0;
jsonSolution["Time"] = time;
jsonSolution["Iteration"] = iteration;
jsonSolution["Unfullfilled"] = solution.getPairBank().size();
jsonSolution["routes"] = jsonRoutes;
return jsonSolution;
}
void output::exportToJson(Solution const &solution)
void output::exportToJson(output::LnsOutput result)
{
std::string directory = "./../../output";
std::string filename = directory + "/" + solution.getData().getDataName() + "_sol.json";
std::string directory = OUTPUT_DIRECTORY;
std::string filename = directory + "/" + result.getBestSolution().getData().getDataName() + "_sol.json";
if (!std::filesystem::exists(directory))
{
......@@ -55,8 +75,18 @@ void output::exportToJson(Solution const &solution)
return;
}
nlohmann::ordered_json jsonData = output::getMinimalJson(solution);
file << jsonData.dump();
nlohmann::ordered_json jsonData;
if (COMPLETE_STORE)
{
jsonData =
output::getCompleteJson(result.getBestSolution(), result.getNumberOfIteration(), result.getTimeSpent());
}
else
{
jsonData = output::getMinimalJson(result.getBestSolution());
}
file << jsonData.dump(4);
file.close();
std::cout << "Solution exported" << std::endl;
}
......
#pragma once
#include "lns/solution/solution.h"
#include "output/lns_output.h"
#include <nlohmann/json.hpp>
#include <ctime>
#include <ctime>
#include <fstream>
#include <nlohmann/json.hpp>
namespace output
{
......@@ -17,13 +17,13 @@ namespace output
/**
* Get a complete json representation of a solution (heavier)
*/
nlohmann::ordered_json getCompleteJson(Solution const &solution);
nlohmann::ordered_json getCompleteJson(Solution const &solution, int iteration, double time);
nlohmann::ordered_json routeToJson(int routeID, const Route& route);
nlohmann::ordered_json routeToJson(int routeID, Route const &route);
void exportToJson(Solution const &solution);
void exportToJson(output::LnsOutput result);
}// namespace output
......
......@@ -19,5 +19,4 @@ using TimeInteger = double;
TimeInteger constexpr UNDEF_TIMESTAMP = std::numeric_limits<TimeInteger>::max();
using Matrix = std::vector<std::vector<double>>;
using Matrix = std::vector<std::vector<double>>;
......@@ -7,7 +7,7 @@
namespace// anonymous namespace
{
std::mt19937_64 randomGenerator;// NOLINT(*-msc51-cpp) => deterministic random!
bool seedSet = false;
bool seedSet = SEED_SET;
std::uniform_real_distribution<> distribution(0, 1);
}// namespace
......