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
Showing
with 595 additions and 93 deletions
......@@ -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:
/**
......@@ -51,8 +52,6 @@ std::function<void(ModificationType &&)> addToListIfValidTemplate(Solution const
return [&](ModificationType &&modification) {
if (solution.checkModification(modification))
{
std::cout << " => Insert Modification"
<< "\n";
list.push_front(std::make_unique<ModificationType>(modification));
}
};
......
#include "operator_selector.h"
#include "utils.h"
ReconstructionOperator &OperatorPair::reconstructor()
{
return reconstruct;
}
DestructionOperator &OperatorPair::destructor()
{
return destruct;
}
bool OperatorPair::forceTakeSolution() const
{
return forceAcceptance;
}
OperatorPair::OperatorPair(DestructionOperator &destruct, ReconstructionOperator &reconstruct, bool forceAcceptance)
: destruct(destruct), reconstruct(reconstruct), forceAcceptance(forceAcceptance)
{}
void OperatorPair::setForceAcceptance()
{
forceAcceptance = true;
}
OperatorPair SimpleOperatorSelector::getOperatorPair()
{
return {*destructOperators.at(destructDistribution(util::getRawRandom())),
*reconstructOperators.at(reconstructDistribution(util::getRawRandom()))};
}
#pragma once
#include "lns/operators/abstract_operator.h"
#include <algorithm>
#include <memory>
#include <random>
#include <utility>
#include <vector>
/**
* Represent a pair (destruction and reconstruction) of operators.
*/
class OperatorPair
{
DestructionOperator &destruct;
ReconstructionOperator &reconstruct;
/**
* Allow the operator pair to force to accept the solution that will be created with the last getOperatorPair();
* @return true to force the acceptance of the solution after the operators calls.
*/
bool forceAcceptance;
public:
OperatorPair(DestructionOperator &destruct, ReconstructionOperator &reconstruct, bool forceAcceptance = false);
DestructionOperator &destructor();
ReconstructionOperator &reconstructor();
// the solution obtained with this operator pair will be accepted by the lns
void setForceAcceptance();
bool forceTakeSolution() const;
};
/**
* Abstract class which defines an interface for an operator selector
*/
class OperatorSelector
{
public:
/**
* Called once per iteration, defines which destruction reconstruction pair is going to be used.
*/
virtual OperatorPair getOperatorPair() = 0;
/**
* Callback if a better solution has been found by the algorithm
*/
virtual void betterSolutionFound() = 0;
virtual ~OperatorSelector() = default;
};
/**
* Simple operator selector with weighted random distribution
*/
class SimpleOperatorSelector : public OperatorSelector
{
std::vector<std::unique_ptr<DestructionOperator>> destructOperators;
std::vector<std::unique_ptr<ReconstructionOperator>> reconstructOperators;
std::discrete_distribution<> destructDistribution;
std::discrete_distribution<> reconstructDistribution;
public:
SimpleOperatorSelector() = default;
SimpleOperatorSelector(SimpleOperatorSelector &rhs) = delete;
SimpleOperatorSelector &operator=(SimpleOperatorSelector &rhs) = delete;
SimpleOperatorSelector(SimpleOperatorSelector &&rhs) = default;
SimpleOperatorSelector &operator=(SimpleOperatorSelector &&rhs) noexcept = default;
template<std::derived_from<DestructionOperator> T>
void addDestructor(T destructor, int weight = 1);
template<std::derived_from<ReconstructionOperator> T>
void addReconstructor(T reconstructor, int weight = 1);
OperatorPair getOperatorPair() override;
void betterSolutionFound() override {}
};
template<std::derived_from<DestructionOperator> T>
void SimpleOperatorSelector::addDestructor(T destructor, int weight)
{
auto newDistribution = std::vector<double>(destructDistribution.probabilities());
int deconstructCount = destructOperators.size();
newDistribution.resize(deconstructCount);
std::ranges::transform(
newDistribution, newDistribution.begin(), [&](double elmt) { return elmt * deconstructCount; });
newDistribution.push_back(weight);
destructDistribution = std::discrete_distribution<>(newDistribution.begin(), newDistribution.end());
destructOperators.push_back(std::make_unique<T>(std::move(destructor)));
}
template<std::derived_from<ReconstructionOperator> T>
void SimpleOperatorSelector::addReconstructor(T reconstructor, int weight)
{
auto newDistribution = std::vector<double>(reconstructDistribution.probabilities());
int reconstructCount = reconstructOperators.size();
newDistribution.resize(reconstructCount);
std::ranges::transform(
newDistribution, newDistribution.begin(), [&](double elmt) { return elmt * reconstructCount; });
newDistribution.push_back(weight);
reconstructDistribution = std::discrete_distribution<>(newDistribution.begin(), newDistribution.end());
reconstructOperators.push_back(std::make_unique<T>(std::move(reconstructor)));
}
\ No newline at end of file
#include "small_large_selector.h"
#include <algorithm>
#include <spdlog/spdlog.h>
SmallLargeOperatorSelector::SmallLargeOperatorSelector(std::vector<StepSelector> selectorsList)
: iterationAtCurrentStep(0), selectorStep(0), selectorPerSize(std::move(selectorsList))
{
iterationForNextStep = selectorPerSize.at(0).first;
}
OperatorPair SmallLargeOperatorSelector::getOperatorPair()
{
if (iterationAtCurrentStep > iterationForNextStep) [[unlikely]]
{
++selectorStep;
if (selectorStep == selectorPerSize.size())
{
betterSolutionFound();
}
iterationForNextStep = selectorPerSize.at(selectorStep).first;
}
SimpleOperatorSelector &selector = selectorPerSize.at(selectorStep).second;
OperatorPair pair = selector.getOperatorPair();
// when we arrive at the last iteration of the last selector, we force the acceptance
if (iterationAtCurrentStep == iterationForNextStep - 1 && selectorStep == selectorPerSize.size()) [[unlikely]]
{
pair.setForceAcceptance();
}
++iterationAtCurrentStep;
return pair;
}
void SmallLargeOperatorSelector::betterSolutionFound()
{
iterationAtCurrentStep = 0;
selectorStep = 0;
}
#pragma once
#include "lns/operators/selector/operator_selector.h"
/**
*
*/
class SmallLargeOperatorSelector : public OperatorSelector
{
public:
using StepSelector = std::pair<unsigned int, SimpleOperatorSelector>;
private:
// the number of call to getOperatorPair (ie. lns iteration) done with the current step
unsigned int iterationAtCurrentStep;
// the index of the selector used, called step
unsigned int selectorStep;
// number of iterations needed to use the next selector
unsigned int iterationForNextStep;
// vector of all the selector and the number of iterations for each
std::vector<StepSelector> selectorPerSize;
public:
/**
* @param selectorPerSize each pair is the maximum of iterations for a given selector.
* ie. {{300,A},{700,B}} means that the A will be used for 300 iterations,
* then B is used for 700. Then cycle on A again.
*/
explicit SmallLargeOperatorSelector(std::vector<StepSelector> selectorPerSize);
OperatorPair getOperatorPair() override;
void betterSolutionFound() override;
};
#include "sorting_strategy.h"
#include "input/pdptw_data.h"
#include "input/data.h"
#include "utils.h"
#include <algorithm>
#include <ranges>
double getDistanceToDepot(PDPTWData const &data, int pairID)
{
return data::TravelTime(data, 0, pairID);
}
std::vector<int> const &sorting_strategy::Shuffle::sortPairs() const
{
auto &bank = getSolution().getPairBank();
std::ranges::shuffle(bank, util::getRawRandom());
return bank;
}
std::vector<int> const &sorting_strategy::Demand::sortPairs() const
{
auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getSolution().getData().getLocation(a).getDemand() > getSolution().getData().getLocation(b).getDemand();
});
return bank;
}
// Following sorting strategy are based on the pickup, TO DO, sort based on the pickup and the delivery
std::vector<int> const &sorting_strategy::Close::sortPairs() const
{
auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getDistanceToDepot(getSolution().getData(), a) < getDistanceToDepot(getSolution().getData(), b);
});
return bank;
}
std::vector<int> const &sorting_strategy::Far::sortPairs() const
{
auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getDistanceToDepot(getSolution().getData(), a) > getDistanceToDepot(getSolution().getData(), b);
});
return bank;
}
std::vector<int> const &sorting_strategy::TimeWindowWidth::sortPairs() const
{
auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getSolution().getData().getLocation(a).getTimeWindow().getWidth() < getSolution().getData().getLocation(b).getTimeWindow().getWidth();
});
return bank;
}
std::vector<int> const &sorting_strategy::TimeWindowStart::sortPairs() const
{
auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getSolution().getData().getLocation(a).getTimeWindow().getStart() < getSolution().getData().getLocation(b).getTimeWindow().getStart();
});
return bank;
}
std::vector<int> const &sorting_strategy::TimeWindowEnd::sortPairs() const
{
auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getSolution().getData().getLocation(a).getTimeWindow().getEnd() > getSolution().getData().getLocation(b).getTimeWindow().getEnd();
});
return bank;
}
\ No newline at end of file
#pragma once
#include "input/time_window.h"
#include "lns/solution/solution.h"
/**
* A type of sorting strategy for the bank of pairs
*/
enum class SortingStrategyType {
SHUFFLE
enum class SortingStrategyType
{
SHUFFLE,
DEMAND,
CLOSE,
FAR,
TWWIDTH,
TWSTART,
TWEND,
};
namespace sorting_strategy
......@@ -34,11 +42,69 @@ namespace sorting_strategy
*/
class Shuffle : public SortingStrategy
{
public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
/**
* Sort the bank by decreasing order of demand
*/
class Demand : public SortingStrategy
{
public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
/**
* Sort the bank by increasing distance from the depot
*/
class Close : public SortingStrategy
{
public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
/**
* Sort the bank by decreasing distance from the depot
*/
class Far : public SortingStrategy
{
public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
/**
* Sort the bank by increasing time window width
*/
class TimeWindowWidth : public SortingStrategy
{
public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
/**
* Sort the bank by inscreasing time window start
*/
class TimeWindowStart : public SortingStrategy
{
public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
/**
* Sort the bank by decreasing time window end
*/
class TimeWindowEnd : public SortingStrategy
{
public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
}// namespace sorting_strategy
\ No newline at end of file
......@@ -8,6 +8,7 @@
#include "lns/solution/route.h"
#include "output/solution_checker.h"
#include <bits/ranges_algo.h>
#include <bits/ranges_util.h>
#include <utility>
......@@ -35,10 +36,10 @@ void Solution::initConstraints()
void Solution::computeAndStoreSolutionCost()
{
routeCost = computeSolutionCost();
rawCost = computeSolutionCost();
// add penalty for solution in the pairBank ?
totalCost = routeCost + computePenalization();
totalCost = rawCost + computePenalisation();
}
double Solution::computeSolutionCost() const
......@@ -51,7 +52,7 @@ double Solution::computeSolutionCost() const
return cost;
}
double Solution::computePenalization() const
double Solution::computePenalisation() const
{
return getBank().size() * EXCLUSION_PENALTY;
}
......@@ -64,9 +65,9 @@ void Solution::init()
computeAndStoreSolutionCost();
}
Solution::Solution(PDPTWData const &data, Solution::PairBank pairbank, std::vector<Route> routes, double routeCost,
Solution::Solution(PDPTWData const &data, Solution::PairBank pairbank, std::vector<Route> routes, double rawCost,
double totalCost)
: data(data), pairBank(std::move(pairbank)), routes(std::move(routes)), routeCost(routeCost), totalCost(totalCost)
: data(data), pairBank(std::move(pairbank)), routes(std::move(routes)), rawCost(rawCost), totalCost(totalCost)
{}
Solution::Solution(PDPTWData const &data) : data(data)
......@@ -80,6 +81,64 @@ Solution Solution::emptySolution(PDPTWData const &data)
return s;
}
Solution::~Solution() noexcept = default;
Solution::Solution(Solution const &rhs) : Solution(rhs.getData())
{
*this = rhs;
}
Solution &Solution::operator=(Solution const &rhs)
{
if (&rhs == this)
{
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);
});
return *this;
}
Solution::Solution(Solution &&sol) noexcept : data(sol.data)
{
*this = std::move(sol);
}
Solution &Solution::operator=(Solution &&sol) noexcept
{
if (&sol == this)
{
return *this;
}
data = sol.data;
rawCost = sol.rawCost;
totalCost = sol.totalCost;
pairBank = std::move(sol.pairBank);
routes = std::move(sol.routes);
constraints = std::move(sol.constraints);
for (auto &constraint: constraints)
{
constraint->setSolution(*this);
}
return *this;
}
Solution::PairBank const &Solution::getBank() const
{
return pairBank;
......@@ -127,7 +186,12 @@ Route const &Solution::getRoute(int routeIndex) const
double Solution::getCost() const
{
return totalCost;
return rawCost + computePenalisation();
}
double Solution::getRawCost() const
{
return rawCost;
}
PDPTWData const &Solution::getData() const
......@@ -145,24 +209,23 @@ int Solution::requestsFulFilledCount() const
return count;
}
bool Solution::checkModification(AtomicRecreation const &modification) const
bool Solution::checkModification(AtomicRecreation const &modification) const
{
std::cout << "--- Check Modification Validity : ";
//std::cout << "--- Check Modification Validity : ";
ModificationCheckVariant const &checkVariant = modification.asCheckVariant();
// visitor pattern
for (std::unique_ptr<Constraint> const &constraint: constraints)
{
if (!constraint->checkVariant(checkVariant))
{
std::cout << "\n";
//std::cout << "\n";
return false;
}
}
std::cout << "\n";
return true;
//std::cout << "\n";
return true;
}
void Solution::beforeApplyModification(AtomicModification &modification)
{
// pre modification check
......@@ -199,8 +262,8 @@ void Solution::applyDestructSolution(AtomicDestruction &modification)
modification.modifySolution(*this);
// updating request bank
std::vector<int> const &deletedPair = modification.getDeletedPairs();
//pairBank.reserve(pairBank.size() + deletedPair.size());
//pairBank.reserve(pairBank.size() + deletedPair.size());
pairBank.insert(pairBank.end(), deletedPair.begin(), deletedPair.end());
afterApplyModification(modification);
......@@ -208,7 +271,7 @@ void Solution::applyDestructSolution(AtomicDestruction &modification)
void Solution::check() const
{
checker::checkSolutionCoherence(*this, getData());
checker::checkSolutionCoherence(*this, getData());
}
void Solution::print() const
......@@ -227,5 +290,11 @@ void Solution::print() const
{
std::cout << id << ", ";
}
std::cout << "\nConstraints : \n";
for (std::unique_ptr<Constraint> const &constraint: constraints)
{
constraint->print();
}
std::cout << "\n";
}
\ No newline at end of file
......@@ -34,16 +34,29 @@ private:
* Vector of routes representing the solution
*/
std::vector<Route> routes;
double routeCost;
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.
*/
static Solution emptySolution(PDPTWData const &data);
/**
* In depth copy of the solution
*/
Solution(Solution const &);
/**
* In depth copy of the solution
*/
Solution &operator=(Solution const &);
Solution(Solution &&) noexcept;
Solution &operator=(Solution &&) noexcept;
~Solution() noexcept;
explicit Solution(PDPTWData const &data);
......@@ -61,6 +74,7 @@ public:
std::vector<Route> const &getRoutes() const;
Route const &getRoute(int routeIndex) const;
PDPTWData const &getData() const;
double getRawCost() const;
double getCost() const;
/**
......@@ -104,6 +118,7 @@ public:
*/
void applyDestructSolution(AtomicDestruction &modification);
double computePenalisation() const;
// For route modification
std::vector<Route> &getRoutes();
......@@ -131,6 +146,4 @@ private:
* Compute the cost of the solution (routes cost)
*/
double computeSolutionCost() const;
double computePenalization() const;
};
\ No newline at end of file
#include <nlohmann/json.hpp>
#include <vector>
#include <iostream>
#include <string>
#include <filesystem>
#include <fstream>
#include <spdlog/spdlog.h>
#include "input/data.h"
#include "input/json_parser.h"
#include "input/location.h"
#include "input/pdptw_data.h"
#include "input/time_window.h"
#include "input/json_parser.h"
#include "input/data.h"
#include "lns/acceptance/threshold_acceptance.h"
#include "lns/constraints/capacity/capacity_constraint.h"
#include "lns/constraints/time_window/time_window_constraint.h"
#include "lns/operators/reconstruction/list_heuristic_cost_oriented.h"
#include "lns/solution/solution.h"
#include "lns/lns.h"
#include "lns/modification/pair/insert_pair.h"
#include "lns/modification/route/insert_route.h"
#include "lns/modification/pair/remove_pair.h"
#include "lns/modification/route/insert_route.h"
#include "lns/modification/route/remove_route.h"
#include "lns/operators/abstract_operator.h"
#include "lns/operators/destruction/random_destroy.h"
#include "lns/operators/reconstruction/enumerate.h"
#include "lns/operators/reconstruction/list_heuristic_cost_oriented.h"
#include "lns/operators/reconstruction/list_heuristic_insertion.h"
#include "lns/operators/selector/operator_selector.h"
#include "lns/operators/selector/small_large_selector.h"
#include "lns/operators/sorting_strategy.h"
#include "lns/operators/reconstruction/enumerate.h"
#include "lns/solution/solution.h"
#include "mains/main_interface.h"
#include "output/solution_exporter.h"
#include <filesystem>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <spdlog/spdlog.h>
#include <string>
#include <vector>
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
ThresholdAcceptance acceptor(0.05);
// lns operators
SimpleOperatorSelector RandomDestroy_ShuffleBestInsert;
addAllReconstructor(RandomDestroy_ShuffleBestInsert);
RandomDestroy_ShuffleBestInsert.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(10, std::move(RandomDestroy_ShuffleBestInsert));
// selectors.emplace_back(100, std::move(largeSelector));
// selectors.emplace_back(2, std::move(veryLargeSelector));
// selectors.emplace_back(2, std::move(hugeSelector));
// selectors.emplace_back(2, std::move(lastSelector));
SmallLargeOperatorSelector smallLargeSelector(std::move(selectors));
// run lns
output::LnsOutput result = lns::runLns(startingSolution, smallLargeSelector, acceptor);
result.getBestSolution().print();
}
int main(int argc, char const *argv[])
int main(int argc, char **argv)
{
//std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/test_inst.json";
//return mainInterface(argc, argv, &simpleLNS);
///////////////////////////////////////////////////////////////////////::
//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";
/*
* test
*/
Solution solution = Solution::emptySolution(data);
Solution startingSolution = Solution::emptySolution(data);
std::cout << "--- Empty Solution --- \n";
solution.print();
//simpleLNS(data, startingSolution);
double blinkRate = 0;
SortingStrategyType strategy = SortingStrategyType::SHUFFLE;
EnumerationType enumeration = EnumerationType::ALL_INSERT_PAIR;
///
std::cout << "===== TEST ===== \n";
Solution testSolution = Solution::emptySolution(data);
//ListHeuristicCostOriented reconstruction = ListHeuristicCostOriented(SortingStrategyType::SHUFFLE, EnumerationType::ALL_INSERT_PAIR);
//reconstruction.reconstructSolution(testSolution, 0.01);
std::cout << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR -> reconstruction (NO COST UPDATE)\n";
testSolution.print();
sorting_strategy::Shuffle(testSolution).sortPairs();
//ListHeuristicInsertion heuristicInsertion;
//heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration);
ListHeuristicCostOriented heuristic;
heuristic.reconstructSolution(solution, blinkRate, strategy, enumeration);
testSolution.print();
sorting_strategy::TimeWindowStart(testSolution).sortPairs();
solution.print();
testSolution.print();
output::exportToJson(solution);
return 0;
}
......@@ -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)
{
......@@ -36,6 +41,6 @@ int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solutio
return 1;
}
spdlog::info("Fin");
spdlog::info("End");
return 0;
}
#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);
#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
#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
......@@ -11,8 +11,6 @@
void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
{
std::cout << " --- Solution Coherence checker : ";
bool errorFlag = false;
// Vector that will store the route ID serving the location, (-1 if no routes)
......@@ -23,7 +21,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
int routeID = 0;
for (Route const &route: sol.getRoutes())
{
std::cout << "#";
// skip if it is an empty route
if (!route.getRoute().empty())
{
......@@ -31,8 +28,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
{
if (check.at(LocID -1) != -1)
{
std::cout << "#";
// Error the location is already attributed (doublon)
spdlog::error("Location {} has already been visited.", LocID);
errorFlag = true;
......@@ -54,10 +49,8 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
++routeID;
}
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
......@@ -74,8 +67,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
sol.print();
throw SolutionConstraintError("Error in the consistency of the solution.", sol);
}
std::cout << " : checker end ---\n";
}
void checker::checkCapacity(Solution const &sol, PDPTWData const &data)
......