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

Add list_heuristic_cost_oriented

- add  list_heuristic_cost_oriented, same as list_heuristic_insertion but evaluate cost before feasibility
parent 4f74e41e
No related branches found
No related tags found
No related merge requests found
...@@ -38,7 +38,8 @@ add_executable(pdptw src/mains/main.cpp ...@@ -38,7 +38,8 @@ add_executable(pdptw src/mains/main.cpp
src/lns/operators/sorting_strategy.cpp src/lns/operators/sorting_strategy.cpp
src/lns/operators/destruction/random_destroy.cpp src/lns/operators/destruction/random_destroy.cpp
src/lns/operators/reconstruction/enumerate.cpp src/lns/operators/reconstruction/enumerate.cpp
src/lns/operators/reconstruction/list_heuristic_insertion.hpp 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_selection.cpp
src/utils.cpp src/utils.cpp
) )
......
...@@ -2,17 +2,6 @@ ...@@ -2,17 +2,6 @@
namespace enumeration namespace enumeration
{ {
template<std::derived_from<AtomicRecreation> ModificationType>
void addToListIfValidTemplate(Solution const &solution, ModificationType const &modification, ModificationContainer &list)
{
if (solution.checkModification(modification))
{
std::cout << " => Insert Modification" << "\n";
list.push_front(std::make_unique<ModificationType>(modification));
}
}
/** /**
* Enumerate InsertPair modifications. * Enumerate InsertPair modifications.
* Does some checks to cut some loops. (TO DO) * Does some checks to cut some loops. (TO DO)
...@@ -20,19 +9,28 @@ namespace enumeration ...@@ -20,19 +9,28 @@ namespace enumeration
* @param pair * @param pair
* @param ModificationContainer * @param ModificationContainer
*/ */
void enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list) void enumerateAllInsertPair(Solution const &solution, Pair const &pair, std::function<void(InsertPair &&)> const &consumeModification)
{ {
int routeIndex = 0; int routeIndex = 0;
// Insert into existing routes // Insert into existing routes
for (Route const &route: solution.getRoutes()) for (Route const &route: solution.getRoutes())
{ {
for (int p = 0; p <= route.getSize(); p++) int routeSize = route.getSize();
for (int p = 0; p <= routeSize; ++p)
{ {
for (int d = p; d <= route.getSize(); d++) for (int d = p; d <= routeSize; ++d)
{ {
Index index = std::make_tuple(routeIndex, p, d); Index index = std::make_tuple(routeIndex, p, d);
// add to list if valid modification
enumeration::addToListIfValidTemplate(solution, InsertPair(index, pair), list); consumeModification(InsertPair(index,pair));
// std::unique_ptr<InsertPair> modification = std::make_unique<InsertPair>(index, pair);
// // add to list if valid modification
// if (solution.checkModification(*modification))
// {
// std::cout << " => Insert Modification\n";
// list.push_front(std::move(modification));
// }
} }
} }
++routeIndex; ++routeIndex;
......
...@@ -24,7 +24,7 @@ namespace enumeration ...@@ -24,7 +24,7 @@ namespace enumeration
* @param Pair * @param Pair
* @param list * @param list
*/ */
void enumerateAllInsertPair(Solution const &solution, Pair const &Pair, ModificationContainer &list); void enumerateAllInsertPair(Solution const &solution, Pair const &pair, std::function<void(InsertPair &&)> const &consumeModification);
}// namespace enumeration }// namespace enumeration
......
#include "list_heuristic_cost_oriented.h"
void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
EnumerationType enumeration) 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;
}
default:
spdlog::error("Error, invalid strategy selected.");
throw std::invalid_argument("Invalid sorting strategy selected.");
break;
}
for (int pairID: sortedPairs)
{
Pair const &pair = solution.getData().getPair(pairID);
AtomicRecreationPtr bestRecreation;
double bestRecreationCost = std::numeric_limits<double>::max();
// Enumeration strategy
switch (enumeration)
{
case EnumerationType::ALL_INSERT_PAIR: {
std::cout << " \n(All insert pair) \n";
enumeration::enumerateAllInsertPair(
solution,
pair,
keepBestSolution<InsertPair>(solution, bestRecreation, bestRecreationCost, blinkRate));
break;
}
default:
spdlog::error("Error, invalid enumeration selected.");
throw std::invalid_argument("Invalid enumeration strategy selected.");
break;
}
if (bestRecreation)
{
std::cout << "\n --- Apply recreation --- \n";
solution.applyRecreateSolution(*bestRecreation);
}
}
}
\ No newline at end of file
#pragma once
#include "input/data.h"
#include "input/pdptw_data.h"
#include "lns/operators/abstract_operator.h"
#include "lns/operators/sorting_strategy.h"
#include "utils.h"
/**
* List heuristic operator but evaluates costs before trying to know if the modification is feasible
*/
class ListHeuristicCostOriented : public ReconstructionOperator
{
public:
using AtomicRecreationPtr = std::unique_ptr<AtomicRecreation>;
void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
EnumerationType enumeration) const override;
};
/**
* Create a function that will consume all the enumerated modifications
* @tparam ModificationType The type of modification enumerated
* @param bestModificationPtr the pointer to the actual best modification found yet
* @param bestCost the cost of the best modification
* @param blinkRate blinking rate
*/
template<std::derived_from<AtomicRecreation> ModificationType>
std::function<void(ModificationType &&)> keepBestSolution(Solution const &solution,
std::unique_ptr<AtomicRecreation> &bestModificationPtr,
double &bestCost, double blinkRate)
{
return [&](ModificationType &&modification) {
double cost = modification.evaluate(solution);
// first test the cost
// if the modification is better, then blink,
// then check the modification
// 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;
}
};
}
#pragma once
#include "list_heuristic_insertion.h" #include "list_heuristic_insertion.h"
#include "lns/operators/sorting_strategy.h" #include "lns/operators/sorting_strategy.h"
#include "enumerate.h" #include "enumerate.h"
// This is a header, but it does define templates, so we can't put them in .cpp file
// for forward declaration you can use the .h file, but if you need to use the class, you must include this one instead
#include <concepts> #include <concepts>
...@@ -20,11 +17,13 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin ...@@ -20,11 +17,13 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin
case SortingStrategyType::SHUFFLE: case SortingStrategyType::SHUFFLE:
{ {
std::cout << " \n(Shuffle)\n"; std::cout << " \n(Shuffle)\n";
// copy
sortedPairs = sorting_strategy::Shuffle(solution).sortPairs(); sortedPairs = sorting_strategy::Shuffle(solution).sortPairs();
break; break;
} }
default: default:
spdlog::error("Error, strategy selected."); spdlog::error("Error, invalid strategy selected.");
throw std::invalid_argument("Invalid sorting strategy selected.");
break; break;
} }
...@@ -32,7 +31,7 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin ...@@ -32,7 +31,7 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin
for (int pairID: sortedPairs) for (int pairID: sortedPairs)
{ {
Pair const &pair = solution.getData().getPair(pairID); Pair const &pair = solution.getData().getPair(pairID);
recreation = ListHeuristicInsertion::choosingStrategy(solution, pair, blinkRate, enumeration); recreation = ListHeuristicInsertion::selectRecreation(solution, pair, blinkRate, enumeration);
if (recreation) if (recreation)
{ {
std::cout << "\n --- Apply recreation --- \n"; std::cout << "\n --- Apply recreation --- \n";
...@@ -41,27 +40,26 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin ...@@ -41,27 +40,26 @@ void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blin
} }
} }
std::unique_ptr<AtomicRecreation> ListHeuristicInsertion::choosingStrategy(Solution &solution, Pair const &pair, std::unique_ptr<AtomicRecreation> ListHeuristicInsertion::selectRecreation(Solution &solution, Pair const &pair,
double blinkRate, EnumerationType enumeration) double blinkRate, EnumerationType enumeration)
{ {
AtomicRecreationPtr bestInsertion; AtomicRecreationPtr bestInsertion;
double bestKnownInsertionCost = std::numeric_limits<double>::max(); double bestKnownInsertionCost = std::numeric_limits<double>::max();
enumeration::ModificationContainer modifications; enumeration::ModificationContainer modifications;
//Generator().populate(solution, pair, modifications);
//
// Enumeration strategy // Enumeration strategy
switch (enumeration) { switch (enumeration) {
case EnumerationType::ALL_INSERT_PAIR: case EnumerationType::ALL_INSERT_PAIR:
{ {
std::cout << " \n(All insert pair) \n"; std::cout << " \n(All insert pair) \n";
//enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list) enumeration::enumerateAllInsertPair(solution, pair, addToListIfValidTemplate<InsertPair>(solution, modifications));
enumeration::enumerateAllInsertPair(solution, pair, modifications);
break; break;
} }
default: default:
spdlog::error("Error, enumeration selected."); spdlog::error("Error, invalid enumeration selected.");
throw std::invalid_argument("Invalid enumeration strategy selected.");
break; break;
} }
......
...@@ -24,13 +24,36 @@ private: ...@@ -24,13 +24,36 @@ private:
public: public:
explicit ListHeuristicInsertion(); explicit ListHeuristicInsertion();
void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const override; void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy,
EnumerationType enumeration) const override;
private: private:
/** /**
* @param blinkRate probability to ignore the request insertion * @param blinkRate probability to ignore the request insertion
* @return the best insertion found * @return the best insertion found
*/ */
static std::unique_ptr<AtomicRecreation> choosingStrategy(Solution &solution, Pair const &pair, static std::unique_ptr<AtomicRecreation> selectRecreation(Solution &solution, Pair const &pair, double blinkRate,
double blinkRate, EnumerationType enumeration); EnumerationType enumeration);
}; };
/**
* Used in enumerate.cpp functions to evaluate modification
* Do not evaluate cost (see list_heuristic_cost_oriented that evaluate cost before feasability)
* @tparam ModificationType the type of modification to be checked
* @param solution the solution to check the modification validity
* @param list the modification will be added to this list if valid
* @return a function that takes a ModificationType and add it to list iff it is valid
*/
template<std::derived_from<AtomicRecreation> ModificationType>
std::function<void(ModificationType &&)> addToListIfValidTemplate(Solution const &solution,
enumeration::ModificationContainer &list)
{
return [&](ModificationType &&modification) {
if (solution.checkModification(modification))
{
std::cout << " => Insert Modification"
<< "\n";
list.push_front(std::make_unique<ModificationType>(modification));
}
};
}
\ No newline at end of file
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "input/data.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/solution/solution.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/route/insert_route.h"
...@@ -21,7 +22,6 @@ ...@@ -21,7 +22,6 @@
#include "lns/modification/route/remove_route.h" #include "lns/modification/route/remove_route.h"
#include "lns/operators/reconstruction/list_heuristic_insertion.h" #include "lns/operators/reconstruction/list_heuristic_insertion.h"
#include "lns/operators/reconstruction/list_heuristic_insertion.hpp"
#include "lns/operators/sorting_strategy.h" #include "lns/operators/sorting_strategy.h"
#include "lns/operators/reconstruction/enumerate.h" #include "lns/operators/reconstruction/enumerate.h"
...@@ -76,8 +76,11 @@ int main(int argc, char const *argv[]) ...@@ -76,8 +76,11 @@ int main(int argc, char const *argv[])
std::cout << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR -> reconstruction (NO COST UPDATE)\n"; std::cout << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR -> reconstruction (NO COST UPDATE)\n";
ListHeuristicInsertion heuristicInsertion; //ListHeuristicInsertion heuristicInsertion;
heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration); //heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration);
ListHeuristicCostOriented heuristic;
heuristic.reconstructSolution(solution, blinkRate, strategy, enumeration);
solution.print(); solution.print();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment