Skip to content
Snippets Groups Projects
Commit e497baab authored by awenjb's avatar awenjb
Browse files

Add selector

parent 58ed359e
No related branches found
No related tags found
No related merge requests found
......@@ -40,7 +40,8 @@ add_executable(pdptw src/mains/main.cpp
src/lns/operators/reconstruction/enumerate.cpp
src/lns/operators/reconstruction/list_heuristic_insertion.cpp
src/lns/operators/reconstruction/list_heuristic_cost_oriented.cpp
src/lns/operators/selector/operator_selection.cpp
src/lns/operators/selector/operator_selector.cpp
src/lns/operators/selector/small_large_selector.cpp
src/utils.cpp
)
......
File moved
#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;
};
......@@ -55,49 +55,40 @@ int main(int argc, char const *argv[])
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);
std::cout << "--- Empty Solution --- \n";
solution.print();
double blinkRate = 0;
SortingStrategyType strategy = SortingStrategyType::SHUFFLE;
EnumerationType enumeration = EnumerationType::ALL_INSERT_PAIR;
std::cout << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR -> reconstruction (NO COST UPDATE)\n";
///////////////////////////////////////////////////////////////////////::
//ListHeuristicInsertion heuristicInsertion;
//heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration);
// std::cout << filepath << "\n";
ListHeuristicCostOriented heuristic;
heuristic.reconstructSolution(solution, blinkRate, strategy, enumeration);
// PDPTWData data = parsing::parseJson(filepath);
// data.checkData();
solution.print();
// data.print();
solution.print();
// std::cout << " \n";
// /*
// * test
// */
// Solution solution = Solution::emptySolution(data);
// std::cout << "--- Empty Solution --- \n";
// solution.print();
// double blinkRate = 0;
// SortingStrategyType strategy = SortingStrategyType::SHUFFLE;
// EnumerationType enumeration = EnumerationType::ALL_INSERT_PAIR;
// std::cout << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR -> reconstruction (NO COST UPDATE)\n";
std::cout << " --- supr !!! --- \n ";
// ListHeuristicCostOriented heuristic;
// heuristic.reconstructSolution(solution, blinkRate, strategy, enumeration);
RandomDestroy randomdestroy = RandomDestroy(5);
randomdestroy.destroySolution(solution);
// RandomDestroy randomdestroy = RandomDestroy(4);
// randomdestroy.destroySolution(solution);
//Index index = std::make_tuple(0,7,9);
//RemovePair remPair = RemovePair(index, solution.getData().getPair(2));
//solution.applyDestructSolution(remPair);
//solution.print();
//output::exportToJson(solution);
//output::exportToJson(solution);
return 0;
}
......@@ -36,6 +36,6 @@ int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solutio
return 1;
}
spdlog::info("Fin");
spdlog::info("End");
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment