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 (5)
Showing
with 345 additions and 95 deletions
......@@ -23,6 +23,7 @@ add_executable(pdptw src/mains/main.cpp
src/input/pdptw_data.cpp
src/input/time_window.cpp
src/input/json_parser.cpp
src/lns/acceptance/threshold_acceptance.cpp
src/lns/solution/route.cpp
src/lns/solution/solution.cpp
src/lns/constraints/constraint.cpp
......@@ -33,6 +34,7 @@ add_executable(pdptw src/mains/main.cpp
src/lns/modification/route/insert_route_with_pair.cpp
src/lns/modification/route/insert_route.cpp
src/lns/modification/route/remove_route.cpp
src/output/lns_output.cpp
src/output/solution_checker.cpp
src/output/solution_exporter.cpp
src/lns/operators/sorting_strategy.cpp
......@@ -40,7 +42,9 @@ 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/lns/lns.cpp
src/utils.cpp
)
......
......@@ -78,6 +78,12 @@ const Pair &PDPTWData::getPair(int id) const
throw std::runtime_error("Pair not found");
}
int PDPTWData::getPairCount() const
{
return getPairs().size();
}
void PDPTWData::print() const
{
std::cout << "Instance name : " << dataName << "\n";
......
#pragma once
#include <nlohmann/json_fwd.hpp>
#include <vector>
#include "pair.h"
#include "location.h"
#include "pair.h"
#include "types.h"
#include <nlohmann/json_fwd.hpp>
#include <vector>
using json = nlohmann::json;
/**
......@@ -28,7 +28,7 @@ class PDPTWData
int capacity;
Location depot;
std::vector<Location> locations;
std::vector<Pair> pairs; // std::unordered_map<int, Pair> pair; if getPair(index) is needed ?
std::vector<Pair> pairs;// std::unordered_map<int, Pair> pair; if getPair(index) is needed ?
Matrix distanceMatrix;
public:
......@@ -43,7 +43,8 @@ public:
* Constructs an empty PDPTWData.
* @see parsing::parseJson
*/
PDPTWData(std::string dataName, int size, int capacity, Location depot, std::vector<Location> locations, Matrix distanceMatrix);
PDPTWData(std::string dataName, int size, int capacity, Location depot, std::vector<Location> locations,
Matrix distanceMatrix);
/**
* Checks some data coherence
*/
......@@ -54,8 +55,8 @@ public:
std::vector<Location> const &getLocations() const;
std::vector<Pair> const &getPairs() const;
const Pair &getPair(int id) const;
int getPairCount() const;
Pair const &getPair(int id) const;
/**
* 0 return the depot.
......
#pragma once
class Solution;
/**
* see AcceptanceFunction::operator()
*/
enum class AcceptationStatus
{
ACCEPT,
REFUSE
};
/**
* Function object that accept or not a solution as the new solution for the next LNS iteration.
*/
class AcceptanceFunction
{
public:
virtual ~AcceptanceFunction() = default;
/**
* Indicate which solution must be used for the next iteration.
* @param candidateSolution the solution that can be accepted
* @param actualSolution the solution used to create the candidate solution
* @param bestSolution the best known solution known to this point.
* @return ACCEPT to use \p candidateSolution for next iteration, REFUSE to continue to use \p actualSolution.
*/
virtual AcceptationStatus operator()(Solution const &candidateSolution, Solution const &actualSolution,
Solution const &bestSolution) const = 0;
};
\ No newline at end of file
#include "threshold_acceptance.h"
#include "lns/solution/solution.h"
AcceptationStatus ThresholdAcceptance::operator()(Solution const &candidateSolution, Solution const &actualSolution,
Solution const &bestSolution) const
{
// the threshold does not take into account the penalisation cost.
if (candidateSolution.getCost() < bestSolution.getRawCost() * thresholdValue + bestSolution.computePenalisation())
{
// accept because of threshold on best solution
return AcceptationStatus::ACCEPT;
}
if (candidateSolution.getCost() < actualSolution.getCost())
{
// accept because better than the actual solution
return AcceptationStatus::ACCEPT;
}
return AcceptationStatus::REFUSE;
}
ThresholdAcceptance::ThresholdAcceptance(double threshold) : thresholdValue(1 + threshold) {}
\ No newline at end of file
#pragma once
#include "acceptance_function.h"
/**
* Simple implementation of AcceptanceFunction.
* If the candidate is not better than the best solution, we accept it if the relative difference is under a threshold.
* ACCEPT If better than the actual solution.
*/
class ThresholdAcceptance : public AcceptanceFunction
{
double thresholdValue = 1.05;
public:
/**
* @param threshold 0.05 means that a solution with a ratio with a solution worse by less than 5% will be accepted
*/
explicit ThresholdAcceptance(double threshold = 0.05);
AcceptationStatus operator()(Solution const &candidateSolution, Solution const &actualSolution,
Solution const &bestSolution) const override;
};
\ No newline at end of file
......@@ -102,12 +102,12 @@ void CapacityConstraint::applyModif(Pair const &pair, int routeIndex, int Pickup
bool CapacityConstraint::check(InsertPair const &op) const
{
std::cout << " #Capa Check";
//std::cout << " #Capa Check";
return checkModif(op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion());
}
void CapacityConstraint::apply(InsertPair const &op)
{
std::cout << "-> Apply Modification on Capacity \n";
//std::cout << "-> Apply Modification on Capacity \n";
applyModif(op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion(), true);
}
......
......@@ -64,5 +64,5 @@ public:
*/
void applyModif(Pair const &pair, int routeIndex, int PickupPosition, int DeliveryPosition, bool addPair);
void print() const;
void print() const override;
};
\ No newline at end of file
......@@ -99,4 +99,6 @@ public:
* Defaults to no op
*/
virtual void endOfDestructionCallback() {}
virtual void print() const = 0;
};
\ No newline at end of file
......@@ -8,32 +8,33 @@
#include "lns/modification/route/remove_route.h"
#include "lns/solution/solution.h"
TimeWindowConstraint::TimeWindowConstraint(const Solution& solution) : Constraint(solution)
TimeWindowConstraint::TimeWindowConstraint(Solution const &solution) : Constraint(solution)
{
allRouteReachTimes.resize(getSolution().getRoutes().size());
}
TimeWindowConstraint::~TimeWindowConstraint()
TimeWindowConstraint::~TimeWindowConstraint()
{
allRouteReachTimes.clear();
}
std::unique_ptr<Constraint> TimeWindowConstraint::clone(Solution const &newOwningSolution) const {
std::unique_ptr<Constraint> TimeWindowConstraint::clone(Solution const &newOwningSolution) const
{
std::unique_ptr<TimeWindowConstraint> clonePtr = std::make_unique<TimeWindowConstraint>(newOwningSolution);
clonePtr->allRouteReachTimes = allRouteReachTimes;
return clonePtr;
}
void TimeWindowConstraint::computeReachTimes(const PDPTWData& data, const std::vector<int> & routeIDs, ReachTimeVector & reachTimes) const
void TimeWindowConstraint::computeReachTimes(PDPTWData const &data, std::vector<int> const &routeIDs,
ReachTimeVector &reachTimes) const
{
// Adjust the size of reachTimes vector
reachTimes.resize(routeIDs.size(), 0);
// Time to the first location
reachTimes.at(0) = data.getDepot().getTimeWindow().getStart() + data::TravelTime(data, 0, routeIDs.at(0));
// Compute other reachTimes (max between arrival and start of the time window + previous service time + travel time)
for (int i = 1; i < routeIDs.size(); ++i) {
for (int i = 1; i < routeIDs.size(); ++i)
{
TimeInteger travelTime = data::TravelTime(data, routeIDs.at(i - 1), routeIDs.at(i));
// locations are indexed from 0 to n-1,
TimeInteger serviceTime = data.getLocation(routeIDs.at(i - 1)).getServiceDuration();
......@@ -47,7 +48,7 @@ void TimeWindowConstraint::initReachTimes()
{
allRouteReachTimes = std::vector<ReachTimeVector>();
int i = 0;
for (const Route& route : getSolution().getRoutes())
for (Route const &route: getSolution().getRoutes())
{
// init and calculate reach time value
allRouteReachTimes.emplace_back();
......@@ -56,25 +57,24 @@ void TimeWindowConstraint::initReachTimes()
}
}
// Copie le vecteur de reach time de la route concernée
// Insère les positions pickup/delivery
// refait l'ordo sur le nouveau vecteur
bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pair, int routeIndex, int pickupPos, int deliveryPos) const
bool TimeWindowConstraint::checkInsertion(PDPTWData const &data, Pair const &pair, int routeIndex, int pickupPos,
int deliveryPos) const
{
ReachTimeVector const &reachTimes = allRouteReachTimes.at(routeIndex);
// COPY route vector
std::vector<int> route(getSolution().getRoute(routeIndex).getRoute().begin(), getSolution().getRoute(routeIndex).getRoute().end()) ;
std::vector<int> route(getSolution().getRoute(routeIndex).getRoute().begin(),
getSolution().getRoute(routeIndex).getRoute().end());
// COPY reachTimes vector
ReachTimeVector newReachTimes(reachTimes.begin(), reachTimes.end());
// Insert pickup and delivery
route.insert(route.begin() + deliveryPos, pair.getDelivery().getId());
route.insert(route.begin() + pickupPos, pair.getPickup().getId());
// std::cout << "\n";
// for (auto pos : route)
......@@ -94,89 +94,147 @@ bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pa
// std::cout << "\n";
// Check Time Windows
for (int i = 0; i < newReachTimes.size(); ++i)
for (int i = 0; i < newReachTimes.size(); ++i)
{
if (! data.getLocation(route.at(i)).getTimeWindow().isValid(newReachTimes.at(i)) )
if (!data.getLocation(route.at(i)).getTimeWindow().isValid(newReachTimes.at(i)))
{
return false;
}
}
return true;
return true;
}
// A lot of check here because i had problems with this function
void TimeWindowConstraint::ApplyModif(PDPTWData const &data, Pair const &pair, int routeIndex, int pickupPos,
int deliveryPos, bool addPair)
{
// Check the routeIndex validity
if (routeIndex < 0 || routeIndex >= getSolution().getRoutes().size())
{
spdlog::error("Error: routeIndex out of bounds ({})", routeIndex);
return;
}
// Copy of the route vector (problem that cause a duplication of the TW)
std::vector<int> routeIDs = getSolution().getRoute(routeIndex).getRoute();
void TimeWindowConstraint::ApplyModif(const PDPTWData& data, const Pair & pair, int routeIndex, int pickupPos, int deliveryPos, bool addPair)
{
// COPY route vector
std::vector<int> routeIDs(getSolution().getRoute(routeIndex).getRoute().begin(), getSolution().getRoute(routeIndex).getRoute().end());
// Adjust pickup and delivery
if (addPair)
// // Check Position validity
// if (pickupPos < 0 || pickupPos > routeIDs.size() ||
// deliveryPos < 0 || deliveryPos > routeIDs.size()) {
// spdlog::error("Error: Indices pickupPos ({}) or deliveryPos ({}) are invalid for a route size of {}.",
// pickupPos, deliveryPos, routeIDs.size());
// return;
// }
// if (addPair) {
// routeIDs.insert(routeIDs.begin() + deliveryPos, pair.getDelivery().getId());
// routeIDs.insert(routeIDs.begin() + pickupPos, pair.getPickup().getId());
// }
// else {
// if (deliveryPos < routeIDs.size() && pickupPos < routeIDs.size() && pickupPos != deliveryPos) {
// if (deliveryPos > pickupPos) {
// routeIDs.erase(routeIDs.begin() + deliveryPos);
// routeIDs.erase(routeIDs.begin() + pickupPos);
// } else {
// routeIDs.erase(routeIDs.begin() + pickupPos);
// routeIDs.erase(routeIDs.begin() + deliveryPos);
// }
// } else {
// spdlog::error("Error: Invalid indices for removal (pickupPos: {}, deliveryPos: {}).", pickupPos, deliveryPos);
// return;
// }
// }
// the route is empty !
if (routeIDs.empty())
{
routeIDs.insert(routeIDs.begin() + deliveryPos, pair.getDelivery().getId());
routeIDs.insert(routeIDs.begin() + pickupPos, pair.getPickup().getId());
allRouteReachTimes.at(routeIndex).clear();
}
else
{
routeIDs.erase(routeIDs.begin() + deliveryPos);
routeIDs.erase(routeIDs.begin() + pickupPos);
}
allRouteReachTimes.at(routeIndex).resize(routeIDs.size(), 0);
// Adjust the size of reachTimes vector
allRouteReachTimes.at(routeIndex).resize(routeIDs.size(), 0);
// Time to the first location
allRouteReachTimes.at(routeIndex).at(0) = data.getDepot().getTimeWindow().getStart() + data::TravelTime(data, 0, routeIDs.at(0));
// Compute other reachTimes (max between arrival and start of the time window)
for (int i = 1; i < routeIDs.size(); ++i) {
TimeInteger travelTime = data::TravelTime(data, routeIDs.at(i - 1), routeIDs.at(i));
TimeInteger serviceTime = data.getLocation(routeIDs.at(i - 1)).getServiceDuration();
TimeInteger startTW = data.getLocation(routeIDs.at(i - 1)).getTimeWindow().getStart();
allRouteReachTimes.at(routeIndex).at(i) = std::max(allRouteReachTimes.at(routeIndex).at(i - 1), startTW) + serviceTime + travelTime;
allRouteReachTimes.at(routeIndex).at(0) =
data.getDepot().getTimeWindow().getStart() + data::TravelTime(data, 0, routeIDs.at(0));
// Compute reach times
for (size_t i = 1; i < routeIDs.size(); ++i)
{
if (i - 1 >= routeIDs.size() || i >= routeIDs.size())
{
spdlog::error("Error: Out-of-bounds access to routeIDs in the computation loop.");
return;
}
TimeInteger travelTime = data::TravelTime(data, routeIDs.at(i - 1), routeIDs.at(i));
TimeInteger serviceTime = data.getLocation(routeIDs.at(i - 1)).getServiceDuration();
TimeInteger startTW = data.getLocation(routeIDs.at(i - 1)).getTimeWindow().getStart();
allRouteReachTimes.at(routeIndex).at(i) =
std::max(allRouteReachTimes.at(routeIndex).at(i - 1), startTW) + serviceTime + travelTime;
}
}
}
bool TimeWindowConstraint::check(InsertPair const &op) const
{
std::cout << " #TW Check";
return checkInsertion(getSolution().getData(), op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion());
//std::cout << " #TW Check";
return checkInsertion(getSolution().getData(),
op.getPair(),
op.getRouteIndex(),
op.getPickupInsertion(),
op.getDeliveryInsertion());
}
void TimeWindowConstraint::apply(InsertPair const &op)
{
std::cout << "-> Apply Modification on Time Windows \n";
ApplyModif(getSolution().getData(), op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion(), true);
//std::cout << "-> Apply Modification on Time Windows \n";
ApplyModif(getSolution().getData(),
op.getPair(),
op.getRouteIndex(),
op.getPickupInsertion(),
op.getDeliveryInsertion(),
true);
}
bool TimeWindowConstraint::check(InsertRoute const &op) const
{
return true;
}
void TimeWindowConstraint::apply(InsertRoute const &op)
{
allRouteReachTimes.emplace_back();
}
bool TimeWindowConstraint::check(RemovePair const &op) const
{
return true;
}
void TimeWindowConstraint::apply(RemovePair const &op)
{
ApplyModif(getSolution().getData(), op.getPair(), op.getRouteIndex(), op.getPickupDeletion(), op.getDeliveryDeletion(), false);
ApplyModif(getSolution().getData(),
op.getPair(),
op.getRouteIndex(),
op.getPickupDeletion(),
op.getDeliveryDeletion(),
false);
}
bool TimeWindowConstraint::check(RemoveRoute const &op) const
{
return true;
}
void TimeWindowConstraint::apply(RemoveRoute const &op)
{
allRouteReachTimes.erase(allRouteReachTimes.begin() + op.getRouteIndex());
}
const std::vector<TimeWindowConstraint::ReachTimeVector>& TimeWindowConstraint::getallRouteReachTimes() const {
std::vector<TimeWindowConstraint::ReachTimeVector> const &TimeWindowConstraint::getallRouteReachTimes() const
{
return allRouteReachTimes;
}
......@@ -184,17 +242,22 @@ void TimeWindowConstraint::print() const
{
std::cout << "Reach Times : \n";
int i = 0;
for (const auto& reachTimes : getallRouteReachTimes())
for (auto const &reachTimes: getallRouteReachTimes())
{
//std::cout << reachTimes.size() << ", ";
std::cout << "#" << i << " : ";
for (const TimeInteger reachTime : reachTimes)
for (const TimeInteger reachTime: reachTimes)
{
std::cout << reachTime << ", ";
}
std::cout << "\n";
std::cout << "#" << i << " : ";
for (int locID: getSolution().getRoute(i).getRoute())
{
std::cout << locID << ", ";
}
std::cout << "\n ";
i++;
}
std::cout << "\n";
}
......@@ -29,7 +29,7 @@ public:
const std::vector<ReachTimeVector> & getallRouteReachTimes() const;
void print() const;
void print() const override;
private:
/**
......
#include "lns.h"
#include "lns/acceptance/acceptance_function.h"
#include "lns/operators/selector/operator_selector.h"
#include "output/solution_checker.h"
namespace
{
bool isBetterSolution(Solution const &candidateSolution, Solution const &bestKnownSol)
{
return candidateSolution.getCost() < bestKnownSol.getCost();
}
}// namespace
output::LnsOutput lns::runLns(Solution const &initialSolution, OperatorSelector &opSelector,
AcceptanceFunction const &acceptFunctor)
{
/**
* The solution is the base solution used to create the neighbor solution.
* It is constant unless we accept the candidate solution.
*/
Solution actualSolution = initialSolution;
Solution bestSolution = initialSolution;
int it = 100;
while (it > 0)
{
std::cout << "\n" << 101-it << " : ";
/**
* The solution on which we apply the operators.
* It is discarded at the end of each loop if it is not accepted by the Acceptance Function.
*/
Solution candidateSolution = actualSolution;
// Chose operator pair
auto destructReconstructPair = opSelector.getOperatorPair();
// Apply operators
destructReconstructPair.destructor().destroySolution(candidateSolution);
destructReconstructPair.reconstructor().reconstructSolution(candidateSolution, 0.01);
// Update best solution
if (isBetterSolution(candidateSolution, bestSolution))
{
std::cout << "\n > new Best Solution \n";
checker::checkAll(candidateSolution, candidateSolution.getData(), false);
bestSolution = candidateSolution;
opSelector.betterSolutionFound();
}
// Check if we use the candidate solution as the new actual solution
// operator can force to take the new solution
if (destructReconstructPair.forceTakeSolution() ||
acceptFunctor(candidateSolution, actualSolution, bestSolution) == AcceptationStatus::ACCEPT)
{
actualSolution = std::move(candidateSolution);
}
--it;
}
auto result = output::LnsOutput(std::move(bestSolution), it, it);
return result;
}
\ No newline at end of file
#pragma once
#include "output/lns_output.h"
class Solution;
class OperatorSelector;
class AcceptanceFunction;
namespace lns
{
/**
* @param initialSolution must be a valid solution !
*/
output::LnsOutput runLns(Solution const &initialSolution, OperatorSelector &opSelector, AcceptanceFunction const &acceptFunctor);
}// namespace lns
\ No newline at end of file
......@@ -105,5 +105,5 @@ Index InsertPair::getIndex() const
ModificationApplyVariant InsertPair::asApplyVariant() const
{
return (*this);
return *this;
}
\ No newline at end of file
......@@ -91,5 +91,5 @@ Index RemovePair::getIndex() const
ModificationApplyVariant RemovePair::asApplyVariant() const
{
return (*this);
return *this;
}
\ No newline at end of file
......@@ -15,6 +15,6 @@ public:
class ReconstructionOperator
{
public:
virtual void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const = 0;
virtual void reconstructSolution(Solution &solution, double blinkRate) const = 0;
virtual ~ReconstructionOperator() = default;
};
......@@ -9,53 +9,60 @@
void RandomDestroy::destroySolution(Solution &solution) const
{
std::cout << "RD ";
int nbRequests = solution.requestsFulFilledCount();
int actualNumberOfPairsToDestroy = std::min(nbRequests, numberOfPairsToDestroy);
int remainingPairToDelete = actualNumberOfPairsToDestroy;
while (remainingPairToDelete < 0)
while (remainingPairToDelete > 0)
{
// too complicated
// Other (simpler) option -> choose random route then choose random pair ?
// choose a random pair
int pairNumber = util::getRandomInt(0, remainingPairToDelete * 2 - 1);
// choose a random location
int locationNumber = util::getRandomInt(0, remainingPairToDelete * 2 - 1);
int pairID = 0;
int routeID = 0;
int count = 0;
int position = 0;
Index index = std::make_tuple(0,0,0);
// retrieve index (route and position)
for (const Route &route : solution.getRoutes())
{
count += route.getSize();
if (pairNumber < count)
position += route.getSize();
if (locationNumber < position)
{
count = count - pairNumber;
// calculate the location position
position = route.getSize() - (position - locationNumber);
std::get<0>(index) = routeID;
std::get<1>(index) = count;
std::get<2>(index) = route.getPairLocationPosition(count, solution.getData());
// get location associated to the position
Location loc = solution.getData().getLocation(route.getRoute().at(position));
// retrieve pickupID (= PairID)
if (solution.getData().getLocation(route.getRoute().at(count)).getLocType() == LocType::PICKUP )
if (loc.getLocType() == LocType::PICKUP )
{
pairID = route.getRoute().at(count);
pairID = route.getRoute().at(position);
std::get<1>(index) = position;
std::get<2>(index) = route.getPairLocationPosition(position, solution.getData());
}
else
{
pairID = route.getRoute().at(std::get<2>(index));
pairID = loc.getPair();
std::get<1>(index) = route.getPairLocationPosition(position, solution.getData());
std::get<2>(index) = position;
}
std::get<0>(index) = routeID;
break;
}
++routeID;
}
RemovePair remPair = RemovePair(index, solution.getData().getPair(pairID));
// appliquer la modif (via solution method -> update correctement la solution)
solution.applyDestructSolution(remPair);
// update les compteurs
......
#include "list_heuristic_cost_oriented.h"
void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
EnumerationType enumeration) const
ListHeuristicCostOriented::ListHeuristicCostOriented(SortingStrategyType strategy, EnumerationType enumeration)
: strategy(strategy), enumeration(enumeration)
{}
void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double blinkRate) const
{
std::vector<int> sortedPairs;
// selection strategy
switch (strategy)
{
case SortingStrategyType::SHUFFLE: {
std::cout << " \n(Shuffle)\n";
// copy
std::cout << "S";
sortedPairs = sorting_strategy::Shuffle(solution).sortPairs();
break;
}
......@@ -19,6 +22,19 @@ void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double b
break;
}
// just for print (no use)
switch (enumeration)
{
case EnumerationType::ALL_INSERT_PAIR: {
// copy
std::cout << "_AIP ";
}
default:
break;
}
for (int pairID: sortedPairs)
{
Pair const &pair = solution.getData().getPair(pairID);
......@@ -30,7 +46,6 @@ void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double b
switch (enumeration)
{
case EnumerationType::ALL_INSERT_PAIR: {
std::cout << " \n(All insert pair) \n";
enumeration::enumerateAllInsertPair(
solution,
pair,
......@@ -46,7 +61,6 @@ void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double b
if (bestRecreation)
{
std::cout << "\n --- Apply recreation --- \n";
solution.applyRecreateSolution(*bestRecreation);
}
}
......
......@@ -11,10 +11,15 @@
*/
class ListHeuristicCostOriented : public ReconstructionOperator
{
private:
SortingStrategyType strategy;
EnumerationType enumeration;
public:
using AtomicRecreationPtr = std::unique_ptr<AtomicRecreation>;
void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
EnumerationType enumeration) const override;
ListHeuristicCostOriented(SortingStrategyType strategy, EnumerationType enumeration);
void reconstructSolution(Solution &solution, double blinkRate) const override;
};
/**
......@@ -37,8 +42,6 @@ std::function<void(ModificationType &&)> keepBestSolution(Solution const &soluti
// then store the best cost and the modification to the pointer
if (cost < bestCost && util::getRandom() >= blinkRate && solution.checkModification(modification))
{
std::cout << " => Better Modification, update pointer"
<< "\n";
bestModificationPtr = std::make_unique<ModificationType>(modification);
bestCost = cost;
}
......
......@@ -7,16 +7,17 @@
#include <concepts>
ListHeuristicInsertion::ListHeuristicInsertion() = default;
ListHeuristicInsertion::ListHeuristicInsertion(SortingStrategyType strategy, EnumerationType enumeration)
: strategy(strategy), enumeration(enumeration)
{}
void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const
void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blinkRate) const
{
std::vector<int> sortedPairs;
// selection strategy
switch (strategy) {
case SortingStrategyType::SHUFFLE:
{
std::cout << " \n(Shuffle)\n";
// copy
sortedPairs = sorting_strategy::Shuffle(solution).sortPairs();
break;
......@@ -52,7 +53,6 @@ std::unique_ptr<AtomicRecreation> ListHeuristicInsertion::selectRecreation(Solut
switch (enumeration) {
case EnumerationType::ALL_INSERT_PAIR:
{
std::cout << " \n(All insert pair) \n";
enumeration::enumerateAllInsertPair(solution, pair, addToListIfValidTemplate<InsertPair>(solution, modifications));
break;
......