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: ...@@ -22,10 +22,11 @@ private:
using AtomicRecreationPtr = std::unique_ptr<AtomicRecreation>; using AtomicRecreationPtr = std::unique_ptr<AtomicRecreation>;
public: public:
explicit ListHeuristicInsertion(); explicit ListHeuristicInsertion(SortingStrategyType strategy, EnumerationType enumeration);
void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, SortingStrategyType strategy;
EnumerationType enumeration) const override; EnumerationType enumeration;
void reconstructSolution(Solution &solution, double blinkRate) const override;
private: private:
/** /**
...@@ -51,8 +52,6 @@ std::function<void(ModificationType &&)> addToListIfValidTemplate(Solution const ...@@ -51,8 +52,6 @@ std::function<void(ModificationType &&)> addToListIfValidTemplate(Solution const
return [&](ModificationType &&modification) { return [&](ModificationType &&modification) {
if (solution.checkModification(modification)) if (solution.checkModification(modification))
{ {
std::cout << " => Insert Modification"
<< "\n";
list.push_front(std::make_unique<ModificationType>(modification)); 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 "sorting_strategy.h"
#include "input/pdptw_data.h"
#include "input/data.h"
#include "utils.h" #include "utils.h"
#include <algorithm> #include <algorithm>
#include <ranges> #include <ranges>
double getDistanceToDepot(PDPTWData const &data, int pairID)
{
return data::TravelTime(data, 0, pairID);
}
std::vector<int> const &sorting_strategy::Shuffle::sortPairs() const std::vector<int> const &sorting_strategy::Shuffle::sortPairs() const
{ {
auto &bank = getSolution().getPairBank(); auto &bank = getSolution().getPairBank();
std::ranges::shuffle(bank, util::getRawRandom()); std::ranges::shuffle(bank, util::getRawRandom());
return bank; 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 #pragma once
#include "input/time_window.h"
#include "lns/solution/solution.h" #include "lns/solution/solution.h"
/** /**
* A type of sorting strategy for the bank of pairs * A type of sorting strategy for the bank of pairs
*/ */
enum class SortingStrategyType { enum class SortingStrategyType
SHUFFLE {
SHUFFLE,
DEMAND,
CLOSE,
FAR,
TWWIDTH,
TWSTART,
TWEND,
}; };
namespace sorting_strategy namespace sorting_strategy
...@@ -34,11 +42,69 @@ namespace sorting_strategy ...@@ -34,11 +42,69 @@ namespace sorting_strategy
*/ */
class Shuffle : public SortingStrategy 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; using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override;
};
/**
* Sort the bank by decreasing distance from the depot
*/
class Far : public SortingStrategy
{
public: public:
using SortingStrategy::SortingStrategy;
std::vector<int> const &sortPairs() const override; 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 }// namespace sorting_strategy
\ No newline at end of file
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "lns/solution/route.h" #include "lns/solution/route.h"
#include "output/solution_checker.h" #include "output/solution_checker.h"
#include <bits/ranges_algo.h>
#include <bits/ranges_util.h> #include <bits/ranges_util.h>
#include <utility> #include <utility>
...@@ -35,10 +36,10 @@ void Solution::initConstraints() ...@@ -35,10 +36,10 @@ void Solution::initConstraints()
void Solution::computeAndStoreSolutionCost() void Solution::computeAndStoreSolutionCost()
{ {
routeCost = computeSolutionCost(); rawCost = computeSolutionCost();
// add penalty for solution in the pairBank ? // add penalty for solution in the pairBank ?
totalCost = routeCost + computePenalization(); totalCost = rawCost + computePenalisation();
} }
double Solution::computeSolutionCost() const double Solution::computeSolutionCost() const
...@@ -51,7 +52,7 @@ double Solution::computeSolutionCost() const ...@@ -51,7 +52,7 @@ double Solution::computeSolutionCost() const
return cost; return cost;
} }
double Solution::computePenalization() const double Solution::computePenalisation() const
{ {
return getBank().size() * EXCLUSION_PENALTY; return getBank().size() * EXCLUSION_PENALTY;
} }
...@@ -64,9 +65,9 @@ void Solution::init() ...@@ -64,9 +65,9 @@ void Solution::init()
computeAndStoreSolutionCost(); 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) 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) Solution::Solution(PDPTWData const &data) : data(data)
...@@ -80,6 +81,64 @@ Solution Solution::emptySolution(PDPTWData const &data) ...@@ -80,6 +81,64 @@ Solution Solution::emptySolution(PDPTWData const &data)
return s; 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 Solution::PairBank const &Solution::getBank() const
{ {
return pairBank; return pairBank;
...@@ -127,7 +186,12 @@ Route const &Solution::getRoute(int routeIndex) const ...@@ -127,7 +186,12 @@ Route const &Solution::getRoute(int routeIndex) const
double Solution::getCost() const double Solution::getCost() const
{ {
return totalCost; return rawCost + computePenalisation();
}
double Solution::getRawCost() const
{
return rawCost;
} }
PDPTWData const &Solution::getData() const PDPTWData const &Solution::getData() const
...@@ -145,24 +209,23 @@ int Solution::requestsFulFilledCount() const ...@@ -145,24 +209,23 @@ int Solution::requestsFulFilledCount() const
return count; 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(); ModificationCheckVariant const &checkVariant = modification.asCheckVariant();
// visitor pattern // visitor pattern
for (std::unique_ptr<Constraint> const &constraint: constraints) for (std::unique_ptr<Constraint> const &constraint: constraints)
{ {
if (!constraint->checkVariant(checkVariant)) if (!constraint->checkVariant(checkVariant))
{ {
std::cout << "\n"; //std::cout << "\n";
return false; return false;
} }
} }
std::cout << "\n"; //std::cout << "\n";
return true; return true;
} }
void Solution::beforeApplyModification(AtomicModification &modification) void Solution::beforeApplyModification(AtomicModification &modification)
{ {
// pre modification check // pre modification check
...@@ -199,8 +262,8 @@ void Solution::applyDestructSolution(AtomicDestruction &modification) ...@@ -199,8 +262,8 @@ void Solution::applyDestructSolution(AtomicDestruction &modification)
modification.modifySolution(*this); modification.modifySolution(*this);
// updating request bank // updating request bank
std::vector<int> const &deletedPair = modification.getDeletedPairs(); 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()); pairBank.insert(pairBank.end(), deletedPair.begin(), deletedPair.end());
afterApplyModification(modification); afterApplyModification(modification);
...@@ -208,7 +271,7 @@ void Solution::applyDestructSolution(AtomicDestruction &modification) ...@@ -208,7 +271,7 @@ void Solution::applyDestructSolution(AtomicDestruction &modification)
void Solution::check() const void Solution::check() const
{ {
checker::checkSolutionCoherence(*this, getData()); checker::checkSolutionCoherence(*this, getData());
} }
void Solution::print() const void Solution::print() const
...@@ -227,5 +290,11 @@ void Solution::print() const ...@@ -227,5 +290,11 @@ void Solution::print() const
{ {
std::cout << id << ", "; std::cout << id << ", ";
} }
std::cout << "\nConstraints : \n";
for (std::unique_ptr<Constraint> const &constraint: constraints)
{
constraint->print();
}
std::cout << "\n"; std::cout << "\n";
} }
\ No newline at end of file
...@@ -34,16 +34,29 @@ private: ...@@ -34,16 +34,29 @@ private:
* Vector of routes representing the solution * Vector of routes representing the solution
*/ */
std::vector<Route> routes; std::vector<Route> routes;
double routeCost; double rawCost;
double totalCost; double totalCost;
std::vector<std::unique_ptr<Constraint>> constraints; std::vector<std::unique_ptr<Constraint>> constraints;
public: public:
//========CONSTRUCTORS, COPY, MOVE, DESTRUCTORS===========
/** /**
* Expected way to construct a solution. * Expected way to construct a solution.
* Generate an empty solution with all pairs in the pairBank and one empty route. * Generate an empty solution with all pairs in the pairBank and one empty route.
*/ */
static Solution emptySolution(PDPTWData const &data); 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); explicit Solution(PDPTWData const &data);
...@@ -61,6 +74,7 @@ public: ...@@ -61,6 +74,7 @@ public:
std::vector<Route> const &getRoutes() const; std::vector<Route> const &getRoutes() const;
Route const &getRoute(int routeIndex) const; Route const &getRoute(int routeIndex) const;
PDPTWData const &getData() const; PDPTWData const &getData() const;
double getRawCost() const;
double getCost() const; double getCost() const;
/** /**
...@@ -104,6 +118,7 @@ public: ...@@ -104,6 +118,7 @@ public:
*/ */
void applyDestructSolution(AtomicDestruction &modification); void applyDestructSolution(AtomicDestruction &modification);
double computePenalisation() const;
// For route modification // For route modification
std::vector<Route> &getRoutes(); std::vector<Route> &getRoutes();
...@@ -131,6 +146,4 @@ private: ...@@ -131,6 +146,4 @@ private:
* Compute the cost of the solution (routes cost) * Compute the cost of the solution (routes cost)
*/ */
double computeSolutionCost() const; double computeSolutionCost() const;
double computePenalization() const;
}; };
\ No newline at end of file
#include <nlohmann/json.hpp> #include "input/data.h"
#include <vector> #include "input/json_parser.h"
#include <iostream>
#include <string>
#include <filesystem>
#include <fstream>
#include <spdlog/spdlog.h>
#include "input/location.h" #include "input/location.h"
#include "input/pdptw_data.h" #include "input/pdptw_data.h"
#include "input/time_window.h" #include "input/time_window.h"
#include "input/json_parser.h" #include "lns/acceptance/threshold_acceptance.h"
#include "input/data.h"
#include "lns/constraints/capacity/capacity_constraint.h" #include "lns/constraints/capacity/capacity_constraint.h"
#include "lns/constraints/time_window/time_window_constraint.h" #include "lns/constraints/time_window/time_window_constraint.h"
#include "lns/operators/reconstruction/list_heuristic_cost_oriented.h" #include "lns/lns.h"
#include "lns/solution/solution.h"
#include "lns/modification/pair/insert_pair.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/pair/remove_pair.h"
#include "lns/modification/route/insert_route.h"
#include "lns/modification/route/remove_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/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/sorting_strategy.h"
#include "lns/solution/solution.h"
#include "lns/operators/reconstruction/enumerate.h" #include "mains/main_interface.h"
#include "output/solution_exporter.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; using json = nlohmann::json;
void printForwardList(const std::forward_list<std::unique_ptr<AtomicRecreation>>& list) { void simpleLNS(PDPTWData const &data, Solution &startingSolution)
int cpt = 1; {
for (const auto& item : list) { // lns parameters
std::cout << cpt << "{ \n"; int requests = data.getPairCount();
// Affichage de l'emplacement ajouté à la solution
int pair = item->getAddedPairs(); int pairs = requests * 2 / 100;
if (pair > 0) { int manyPairs = requests * 40 / 100;
std::cout << "Added Location ID: \n";
std::cout << pair << "\n"; // threshold function to do
} else { ThresholdAcceptance acceptor(0.05);
std::cout << "No location added.\n";
} // lns operators
std::cout << "} \n"; SimpleOperatorSelector RandomDestroy_ShuffleBestInsert;
++cpt; 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/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/Nantes_1.json";
//std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/n5000/bar-n5000-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); PDPTWData data = parsing::parseJson(filepath);
data.checkData(); Solution startingSolution = Solution::emptySolution(data);
data.print();
std::cout << " \n";
/*
* test
*/
Solution solution = Solution::emptySolution(data);
std::cout << "--- Empty Solution --- \n"; //simpleLNS(data, startingSolution);
solution.print();
double blinkRate = 0; ///
SortingStrategyType strategy = SortingStrategyType::SHUFFLE; std::cout << "===== TEST ===== \n";
EnumerationType enumeration = EnumerationType::ALL_INSERT_PAIR; 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; testSolution.print();
//heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration);
sorting_strategy::TimeWindowStart(testSolution).sortPairs();
ListHeuristicCostOriented heuristic;
heuristic.reconstructSolution(solution, blinkRate, strategy, enumeration);
solution.print(); testSolution.print();
output::exportToJson(solution);
return 0; return 0;
} }
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <spdlog/spdlog.h> #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) 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 ...@@ -36,6 +41,6 @@ int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solutio
return 1; return 1;
} }
spdlog::info("Fin"); spdlog::info("End");
return 0; return 0;
} }
#pragma once #pragma once
#include "input/pdptw_data.h" #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 "lns/solution/solution.h"
#include <functional> #include <functional>
void addAllReconstructor(SimpleOperatorSelector &selector);
int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solution &)> function); 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 @@ ...@@ -11,8 +11,6 @@
void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data) void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
{ {
std::cout << " --- Solution Coherence checker : ";
bool errorFlag = false; bool errorFlag = false;
// Vector that will store the route ID serving the location, (-1 if no routes) // 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) ...@@ -23,7 +21,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
int routeID = 0; int routeID = 0;
for (Route const &route: sol.getRoutes()) for (Route const &route: sol.getRoutes())
{ {
std::cout << "#";
// skip if it is an empty route // skip if it is an empty route
if (!route.getRoute().empty()) if (!route.getRoute().empty())
{ {
...@@ -31,8 +28,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data) ...@@ -31,8 +28,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
{ {
if (check.at(LocID -1) != -1) if (check.at(LocID -1) != -1)
{ {
std::cout << "#";
// Error the location is already attributed (doublon) // Error the location is already attributed (doublon)
spdlog::error("Location {} has already been visited.", LocID); spdlog::error("Location {} has already been visited.", LocID);
errorFlag = true; errorFlag = true;
...@@ -54,10 +49,8 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data) ...@@ -54,10 +49,8 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
++routeID; ++routeID;
} }
std::cout << "#";
// checking PairBank coherence (given the routes) // checking PairBank coherence (given the routes)
std::vector<int> testbank = sol.getBank();
for (int pairID: sol.getBank()) for (int pairID: sol.getBank())
{ {
// check goes from 0 et n-1 // check goes from 0 et n-1
...@@ -74,8 +67,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data) ...@@ -74,8 +67,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
sol.print(); sol.print();
throw SolutionConstraintError("Error in the consistency of the solution.", sol); throw SolutionConstraintError("Error in the consistency of the solution.", sol);
} }
std::cout << " : checker end ---\n";
} }
void checker::checkCapacity(Solution const &sol, PDPTWData const &data) void checker::checkCapacity(Solution const &sol, PDPTWData const &data)
......