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

Replace template by switch case

- replace template by switch case for the sorting strategy and the enumeration strategy in reconstruction operator
- remove generator / modficiation generator
parent a4e9f18a
No related branches found
No related tags found
No related merge requests found
......@@ -37,8 +37,7 @@ add_executable(pdptw src/mains/main.cpp
src/output/solution_exporter.cpp
src/lns/operators/sorting_strategy.cpp
src/lns/operators/destruction/random_destroy.cpp
src/lns/operators/generators/enumerate.cpp
src/lns/operators/generators/modification_generator.cpp
src/lns/operators/reconstruction/enumerate.cpp
src/lns/operators/reconstruction/list_heuristic_insertion.hpp
src/lns/operators/selector/operator_selection.cpp
src/utils.cpp
......
#pragma once
#include "lns/operators/reconstruction/enumerate.h"
#include "sorting_strategy.h"
class Solution;
class DestructionOperator
......@@ -12,6 +15,6 @@ public:
class ReconstructionOperator
{
public:
virtual void reconstructSolution(Solution &solution, double blinkRate) const = 0;
virtual void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const = 0;
virtual ~ReconstructionOperator() = default;
};
#include "modification_generator.h"
#include "enumerate.h"
namespace generator
{
/**
*
* @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,
ModificationContainer &list)
{
return [&](ModificationType &&modification) {
if (solution.checkModification(modification))
{
std::cout << " => Insert Modification" << "\n";
list.push_front(std::make_unique<ModificationType>(modification));
}
};
std::cout << " => Insert Modification" << "\n";
}
void AllTypedModifications<InsertPair>::populate(Solution const &solution, Pair const &pair,
std::forward_list<std::unique_ptr<AtomicRecreation>> &list)
{
std::cout << "\n MODIFICATION GENERATOR : \n";
enumeration::enumerateAllInsertPair(
solution, pair, addToListIfValidTemplate<InsertPair>(solution, list));
}
}// namespace generator
#pragma once
#include "input/pair.h"
#include "lns/modification/atomic_recreation.h"
#include "lns/modification/pair/insert_pair.h"
#include <forward_list>
#include <memory>
namespace generator
{
using ModificationContainer = std::forward_list<std::unique_ptr<AtomicRecreation>>;
/**
* Abstract class to generate valid modifications
*/
class ModificationGenerator
{
public:
/**
* Adds valid insertions of request to the solution in the list provided as argument
*/
virtual void populate(Solution const &solution, Pair const &, ModificationContainer &modificationList) = 0;
virtual ~ModificationGenerator() = default;
};
/**
* Empty template class to generate ALL valid modification of a specific type
* @tparam T the type of modification to generate
*/
template<std::derived_from<AtomicRecreation> T>
class AllTypedModifications : public ModificationGenerator
{
// this assert will always fail. Needs a template specification
static_assert(sizeof(T) == 0, "The generator for type T has not been defined yet.");
};
template<>
class AllTypedModifications<InsertPair> : public ModificationGenerator
{
public:
void populate(Solution const &solution, Pair const &, ModificationContainer &list) override;
};
}// namespace generator
\ No newline at end of file
......@@ -2,16 +2,25 @@
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.
* consumeModification is called for each modification.
* Does some checks to cut some loops. (TO DO)
* @param solution
* @param pair
* @param consumeModification called when a modification is created
* @param ModificationContainer
*/
void enumerateAllInsertPair(Solution const &solution, Pair const &pair,
std::function<void(InsertPair &&)> const &consumeModification)
void enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list)
{
int routeIndex = 0;
// Insert into existing routes
......@@ -22,8 +31,8 @@ namespace enumeration
for (int d = p; d <= route.getSize(); d++)
{
Index index = std::make_tuple(routeIndex, p, d);
//std::cout << std::get<0>(index) << " " << std::get<1>(index) << " " << std::get<2>(index) << "\n";
consumeModification(InsertPair(index, pair));
// add to list if valid modification
enumeration::addToListIfValidTemplate(solution, InsertPair(index, pair), list);
}
}
++routeIndex;
......
......@@ -2,21 +2,29 @@
#include "lns/modification/pair/insert_pair.h"
#include <forward_list>
#include <functional>
/**
* A type of enumeration for a specific modification
*/
enum class EnumerationType {
ALL_INSERT_PAIR
};
namespace enumeration
{
using ModificationContainer = std::forward_list<std::unique_ptr<AtomicRecreation>>;
/**
* Enumerate InsertDelivery modifications.
* consumeModification is called for each modification.
* Does some checks to cut some loops.
* @param solution
* @param request
* @param consumeModification called when a modification is created (ex : keepBestSolution)
* @param Pair
* @param list
*/
void enumerateAllInsertPair(Solution const &solution, Pair const &Pair,
std::function<void(InsertPair &&)> const &consumeModification);
void enumerateAllInsertPair(Solution const &solution, Pair const &Pair, ModificationContainer &list);
}// namespace enumeration
......
......@@ -3,7 +3,6 @@
#include "input/data.h"
#include "input/pdptw_data.h"
#include "lns/operators/abstract_operator.h"
#include "lns/operators/generators/modification_generator.h"
#include "lns/operators/sorting_strategy.h"
#include "utils.h"
......@@ -17,8 +16,6 @@ class AtomicRecreation;
* @tparam Strategy defines in which order we are treating the requests
* @tparam Generator defines which modifications are going to be used
*/
template<std::derived_from<sorting_strategy::SortingStrategy> Strategy,
std::derived_from<generator::ModificationGenerator> Generator>
class ListHeuristicInsertion : public ReconstructionOperator
{
private:
......@@ -27,7 +24,7 @@ private:
public:
explicit ListHeuristicInsertion();
void reconstructSolution(Solution &solution, double blinkRate) const override;
void reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const override;
private:
/**
......@@ -35,5 +32,5 @@ private:
* @return the best insertion found
*/
static std::unique_ptr<AtomicRecreation> choosingStrategy(Solution &solution, Pair const &pair,
double blinkRate);
double blinkRate, EnumerationType enumeration);
};
#pragma once
#include "list_heuristic_insertion.h"
#include "lns/operators/sorting_strategy.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 "lns/operators/generators/modification_generator.h"
#include <concepts>
template<std::derived_from<sorting_strategy::SortingStrategy> Strategy,
std::derived_from<generator::ModificationGenerator> Generator>
ListHeuristicInsertion<Strategy, Generator>::ListHeuristicInsertion() = default;
ListHeuristicInsertion::ListHeuristicInsertion() = default;
template<std::derived_from<sorting_strategy::SortingStrategy> Strategy,
std::derived_from<generator::ModificationGenerator> Generator>
void ListHeuristicInsertion<Strategy, Generator>::reconstructSolution(Solution &solution, double blinkRate) const
void ListHeuristicInsertion::reconstructSolution(Solution &solution, double blinkRate, SortingStrategyType strategy, EnumerationType enumeration) const
{
std::vector<int> sortedPairs = Strategy(solution).sortPairs();
std::vector<int> sortedPairs;
// selection strategy
switch (strategy) {
case SortingStrategyType::SHUFFLE:
{
std::cout << " \n(Shuffle)\n";
sortedPairs = sorting_strategy::Shuffle(solution).sortPairs();
break;
}
default:
spdlog::error("Error, strategy selected.");
break;
}
AtomicRecreationPtr recreation;
for (int pairID: sortedPairs)
{
Pair const &pair = solution.getData().getPair(pairID);
recreation = ListHeuristicInsertion::choosingStrategy(solution, pair, blinkRate);
recreation = ListHeuristicInsertion::choosingStrategy(solution, pair, blinkRate, enumeration);
if (recreation)
{
std::cout << "\n --- Apply recreation --- \n";
......@@ -31,17 +41,31 @@ void ListHeuristicInsertion<Strategy, Generator>::reconstructSolution(Solution &
}
}
template<std::derived_from<sorting_strategy::SortingStrategy> Strategy,
std::derived_from<generator::ModificationGenerator> Generator>
std::unique_ptr<AtomicRecreation> ListHeuristicInsertion<Strategy, Generator>::choosingStrategy(Solution &solution,
Pair const &pair,
double blinkRate)
std::unique_ptr<AtomicRecreation> ListHeuristicInsertion::choosingStrategy(Solution &solution, Pair const &pair,
double blinkRate, EnumerationType enumeration)
{
AtomicRecreationPtr bestInsertion;
double bestKnownInsertionCost = std::numeric_limits<double>::max();
generator::ModificationContainer modifications;
Generator().populate(solution, pair, modifications);
enumeration::ModificationContainer modifications;
//Generator().populate(solution, pair, modifications);
//
// Enumeration strategy
switch (enumeration) {
case EnumerationType::ALL_INSERT_PAIR:
{
std::cout << " \n(All insert pair) \n";
//enumerateAllInsertPair(Solution const &solution, Pair const &pair, ModificationContainer &list)
enumeration::enumerateAllInsertPair(solution, pair, modifications);
break;
}
default:
spdlog::error("Error, enumeration selected.");
break;
}
// Keep the modification with the best cost
for (AtomicRecreationPtr &possibleRecreation: modifications)
{
if (util::getRandom() <= 1 - blinkRate)
......
......@@ -2,6 +2,13 @@
#include "lns/solution/solution.h"
/**
* A type of sorting strategy for the bank of pairs
*/
enum class SortingStrategyType {
SHUFFLE
};
namespace sorting_strategy
{
/**
......
......@@ -22,9 +22,10 @@
#include "lns/operators/reconstruction/list_heuristic_insertion.h"
#include "lns/operators/reconstruction/list_heuristic_insertion.hpp"
#include "lns/operators/generators/modification_generator.h"
#include "lns/operators/sorting_strategy.h"
#include "lns/operators/reconstruction/enumerate.h"
#include "output/solution_exporter.h"
using json = nlohmann::json;
......@@ -69,18 +70,14 @@ int main(int argc, char const *argv[])
std::cout << "--- Empty Solution --- \n";
solution.print();
generator::AllTypedModifications<InsertPair> generator;
generator::ModificationContainer modificationList;
//ListHeuristicInsertion<std::derived_from<sorting_strategy::SortingStrategy> Strategy, std::derived_from<generator::ModificationGenerator> Generator>
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 << "\n --- Operator - SHUFFLE - ALL_INSERTPAIR -> reconstruction (NO COST UPDATE)\n";
ListHeuristicInsertion<sorting_strategy::Shuffle, generator::AllTypedModifications<InsertPair>> operatorInstance;
operatorInstance.reconstructSolution(solution, blinkRate);
ListHeuristicInsertion heuristicInsertion;
heuristicInsertion.reconstructSolution(solution, blinkRate, strategy, enumeration);
solution.print();
......
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