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
...@@ -16,6 +16,36 @@ void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double b ...@@ -16,6 +16,36 @@ void ListHeuristicCostOriented::reconstructSolution(Solution &solution, double b
sortedPairs = sorting_strategy::Shuffle(solution).sortPairs(); sortedPairs = sorting_strategy::Shuffle(solution).sortPairs();
break; break;
} }
case SortingStrategyType::DEMAND: {
std::cout << "D";
sortedPairs = sorting_strategy::Demand(solution).sortPairs();
break;
}
case SortingStrategyType::CLOSE: {
std::cout << "C";
sortedPairs = sorting_strategy::Close(solution).sortPairs();
break;
}
case SortingStrategyType::FAR: {
std::cout << "F";
sortedPairs = sorting_strategy::Far(solution).sortPairs();
break;
}
case SortingStrategyType::TWWIDTH: {
std::cout << "TWW";
sortedPairs = sorting_strategy::TimeWindowWidth(solution).sortPairs();
break;
}
case SortingStrategyType::TWSTART: {
std::cout << "TWS";
sortedPairs = sorting_strategy::TimeWindowStart(solution).sortPairs();
break;
}
case SortingStrategyType::TWEND: {
std::cout << "TWE";
sortedPairs = sorting_strategy::TimeWindowEnd(solution).sortPairs();
break;
}
default: default:
spdlog::error("Error, invalid strategy selected."); spdlog::error("Error, invalid strategy selected.");
throw std::invalid_argument("Invalid sorting strategy selected."); throw std::invalid_argument("Invalid sorting strategy selected.");
......
#include "sorting_strategy.h" #include "sorting_strategy.h"
#include "input/pdptw_data.h"
#include "input/data.h" #include "input/data.h"
#include "input/pdptw_data.h"
#include "utils.h" #include "utils.h"
#include <algorithm> #include <algorithm>
#include <ranges> #include <ranges>
double getDistanceToDepot(PDPTWData const &data, int pairID) double getDistanceToDepot(PDPTWData const &data, int pairID)
{ {
return data::TravelTime(data, 0, 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();
...@@ -32,15 +30,17 @@ std::vector<int> const &sorting_strategy::Demand::sortPairs() const ...@@ -32,15 +30,17 @@ std::vector<int> const &sorting_strategy::Demand::sortPairs() const
return bank; 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 std::vector<int> const &sorting_strategy::Close::sortPairs() const
{ {
auto &bank = getSolution().getPairBank(); auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID // Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) { std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getDistanceToDepot(getSolution().getData(), a) < getDistanceToDepot(getSolution().getData(), b); return (getDistanceToDepot(getSolution().getData(), a) +
getDistanceToDepot(getSolution().getData(), getSolution().getData().getLocation(a).getPair())) /
2 <
(getDistanceToDepot(getSolution().getData(), b) +
getDistanceToDepot(getSolution().getData(), getSolution().getData().getLocation(b).getPair())) /
2;
}); });
return bank; return bank;
} }
...@@ -50,7 +50,12 @@ std::vector<int> const &sorting_strategy::Far::sortPairs() const ...@@ -50,7 +50,12 @@ std::vector<int> const &sorting_strategy::Far::sortPairs() const
auto &bank = getSolution().getPairBank(); auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID // Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) { std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getDistanceToDepot(getSolution().getData(), a) > getDistanceToDepot(getSolution().getData(), b); return (getDistanceToDepot(getSolution().getData(), a) +
getDistanceToDepot(getSolution().getData(), getSolution().getData().getLocation(a).getPair())) /
2 >
(getDistanceToDepot(getSolution().getData(), b) +
getDistanceToDepot(getSolution().getData(), getSolution().getData().getLocation(b).getPair())) /
2;
}); });
return bank; return bank;
} }
...@@ -60,7 +65,12 @@ std::vector<int> const &sorting_strategy::TimeWindowWidth::sortPairs() const ...@@ -60,7 +65,12 @@ std::vector<int> const &sorting_strategy::TimeWindowWidth::sortPairs() const
auto &bank = getSolution().getPairBank(); auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID // Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) { std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getSolution().getData().getLocation(a).getTimeWindow().getWidth() < getSolution().getData().getLocation(b).getTimeWindow().getWidth(); const Location &locA = getSolution().getData().getLocation(a);
const Location &locB = getSolution().getData().getLocation(b);
return locA.getTimeWindow().getWidth() +
getSolution().getData().getLocation(locA.getPair()).getTimeWindow().getWidth() / 2 <
locB.getTimeWindow().getWidth() +
getSolution().getData().getLocation(locB.getPair()).getTimeWindow().getWidth() / 2;
}); });
return bank; return bank;
} }
...@@ -70,7 +80,8 @@ std::vector<int> const &sorting_strategy::TimeWindowStart::sortPairs() const ...@@ -70,7 +80,8 @@ std::vector<int> const &sorting_strategy::TimeWindowStart::sortPairs() const
auto &bank = getSolution().getPairBank(); auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID // Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) { std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getSolution().getData().getLocation(a).getTimeWindow().getStart() < getSolution().getData().getLocation(b).getTimeWindow().getStart(); return getSolution().getData().getLocation(a).getTimeWindow().getStart() <
getSolution().getData().getLocation(b).getTimeWindow().getStart();
}); });
return bank; return bank;
} }
...@@ -80,7 +91,10 @@ std::vector<int> const &sorting_strategy::TimeWindowEnd::sortPairs() const ...@@ -80,7 +91,10 @@ std::vector<int> const &sorting_strategy::TimeWindowEnd::sortPairs() const
auto &bank = getSolution().getPairBank(); auto &bank = getSolution().getPairBank();
// Pair ID = Pickup ID // Pair ID = Pickup ID
std::sort(bank.begin(), bank.end(), [&](int a, int b) { std::sort(bank.begin(), bank.end(), [&](int a, int b) {
return getSolution().getData().getLocation(a).getTimeWindow().getEnd() > getSolution().getData().getLocation(b).getTimeWindow().getEnd(); const Location &locA = getSolution().getData().getLocation(a);
const Location &locB = getSolution().getData().getLocation(b);
return getSolution().getData().getLocation(locA.getPair()).getTimeWindow().getEnd() >
getSolution().getData().getLocation(locB.getPair()).getTimeWindow().getEnd();
}); });
return bank; return bank;
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#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
{ {
...@@ -20,7 +20,7 @@ enum class SortingStrategyType ...@@ -20,7 +20,7 @@ enum class SortingStrategyType
namespace sorting_strategy namespace sorting_strategy
{ {
/** /**
* Interface for sorting the requests in the request bank. Does modify directly the solution request bank * Interface for sorting the requests in the request bank. Does modify directly the solution request bank.
*/ */
class SortingStrategy class SortingStrategy
{ {
...@@ -33,12 +33,12 @@ namespace sorting_strategy ...@@ -33,12 +33,12 @@ namespace sorting_strategy
virtual ~SortingStrategy() = default; virtual ~SortingStrategy() = default;
private: private:
// non const to sort in place // non const to sort in place.
Solution &solution; Solution &solution;
}; };
/** /**
* Shuffle the requests * Shuffle the requests.
*/ */
class Shuffle : public SortingStrategy class Shuffle : public SortingStrategy
{ {
...@@ -48,7 +48,7 @@ namespace sorting_strategy ...@@ -48,7 +48,7 @@ namespace sorting_strategy
}; };
/** /**
* Sort the bank by decreasing order of demand * Sort the bank by decreasing order of demand.
*/ */
class Demand : public SortingStrategy class Demand : public SortingStrategy
{ {
...@@ -58,7 +58,7 @@ namespace sorting_strategy ...@@ -58,7 +58,7 @@ namespace sorting_strategy
}; };
/** /**
* Sort the bank by increasing distance from the depot * Sort the bank by increasing distance from the depot.
*/ */
class Close : public SortingStrategy class Close : public SortingStrategy
{ {
...@@ -68,7 +68,7 @@ namespace sorting_strategy ...@@ -68,7 +68,7 @@ namespace sorting_strategy
}; };
/** /**
* Sort the bank by decreasing distance from the depot * Sort the bank by decreasing distance from the depot.
*/ */
class Far : public SortingStrategy class Far : public SortingStrategy
{ {
...@@ -78,7 +78,7 @@ namespace sorting_strategy ...@@ -78,7 +78,7 @@ namespace sorting_strategy
}; };
/** /**
* Sort the bank by increasing time window width * Sort the bank by increasing time window width.
*/ */
class TimeWindowWidth : public SortingStrategy class TimeWindowWidth : public SortingStrategy
{ {
...@@ -88,7 +88,7 @@ namespace sorting_strategy ...@@ -88,7 +88,7 @@ namespace sorting_strategy
}; };
/** /**
* Sort the bank by inscreasing time window start * Sort the bank by inscreasing time window start (compare the pickup time window).
*/ */
class TimeWindowStart : public SortingStrategy class TimeWindowStart : public SortingStrategy
{ {
...@@ -98,7 +98,7 @@ namespace sorting_strategy ...@@ -98,7 +98,7 @@ namespace sorting_strategy
}; };
/** /**
* Sort the bank by decreasing time window end * Sort the bank by decreasing time window end (compare the delivery time window).
*/ */
class TimeWindowEnd : public SortingStrategy class TimeWindowEnd : public SortingStrategy
{ {
......
...@@ -61,6 +61,14 @@ int Route::getSize() const ...@@ -61,6 +61,14 @@ int Route::getSize() const
return route.size(); return route.size();
} }
int Route::getIndex(int locationID) const
{
auto it = std::find(route.begin(), route.end(), locationID);
if (it != route.end()) {
return std::distance(route.begin(), it);
}
return -1;
}
int Route::getPairLocationPosition(int position, const PDPTWData &data) const int Route::getPairLocationPosition(int position, const PDPTWData &data) const
{ {
......
...@@ -27,6 +27,11 @@ public: ...@@ -27,6 +27,11 @@ public:
// get Location // get Location
int getLocation(int index) const; int getLocation(int index) const;
/**
* Given a locationID, return the Index in the route.
* return -1 if no such location.
*/
int getIndex(int locationID) const;
/** /**
* Given the position of a location in a route, return the paired location position. * Given the position of a location in a route, return the paired location position.
......
...@@ -4,13 +4,17 @@ ...@@ -4,13 +4,17 @@
#include "input/data.h" #include "input/data.h"
#include "input/time_window.h" #include "input/time_window.h"
#include "lns/constraints/capacity/capacity_constraint.h" #include "lns/constraints/capacity/capacity_constraint.h"
#include "lns/constraints/constraint.h"
#include "lns/constraints/time_window/time_window_constraint.h" #include "lns/constraints/time_window/time_window_constraint.h"
#include "lns/solution/route.h" #include "lns/solution/route.h"
#include "output/solution_checker.h" #include "output/solution_checker.h"
#include <algorithm>
#include <bits/ranges_algo.h> #include <bits/ranges_algo.h>
#include <bits/ranges_util.h> #include <bits/ranges_util.h>
#include <ranges>
#include <utility> #include <utility>
#include <vector>
void Solution::initPairBank() void Solution::initPairBank()
{ {
...@@ -24,7 +28,10 @@ void Solution::initPairBank() ...@@ -24,7 +28,10 @@ void Solution::initPairBank()
void Solution::initRoutes() void Solution::initRoutes()
{ {
routes.clear(); routes.clear();
routes.emplace_back(); for (unsigned int i = 0; i < NUMBER_VEHICLE; ++i)
{
this->routes.emplace_back();
}
} }
void Solution::initConstraints() void Solution::initConstraints()
...@@ -44,7 +51,7 @@ void Solution::computeAndStoreSolutionCost() ...@@ -44,7 +51,7 @@ void Solution::computeAndStoreSolutionCost()
double Solution::computeSolutionCost() const double Solution::computeSolutionCost() const
{ {
double cost = 0; double cost = 0.0;
for (Route const &route: getRoutes()) for (Route const &route: getRoutes())
{ {
cost += data::routeCost(data, route); cost += data::routeCost(data, route);
...@@ -77,8 +84,8 @@ Solution::Solution(PDPTWData const &data) : data(data) ...@@ -77,8 +84,8 @@ Solution::Solution(PDPTWData const &data) : data(data)
Solution Solution::emptySolution(PDPTWData const &data) Solution Solution::emptySolution(PDPTWData const &data)
{ {
Solution s = Solution(data); Solution sol = Solution(data);
return s; return sol;
} }
Solution::~Solution() noexcept = default; Solution::~Solution() noexcept = default;
...@@ -199,6 +206,11 @@ PDPTWData const &Solution::getData() const ...@@ -199,6 +206,11 @@ PDPTWData const &Solution::getData() const
return data.get(); return data.get();
} }
std::vector<std::unique_ptr<Constraint>> const &Solution::getConstraints() const
{
return constraints;
}
int Solution::requestsFulFilledCount() const int Solution::requestsFulFilledCount() const
{ {
int count = 0; int count = 0;
...@@ -209,6 +221,28 @@ int Solution::requestsFulFilledCount() const ...@@ -209,6 +221,28 @@ int Solution::requestsFulFilledCount() const
return count; return count;
} }
int Solution::getRouteIDOf(int locationID) const
{
int routeIndex = 0;
for (Route const &route: getRoutes())
{
std::vector<int> const &routeLocationIDs = route.getRoute();
if (std::ranges::find(routeLocationIDs, locationID) != routeLocationIDs.end())
{
return routeIndex;
}
++routeIndex;
}
// no routes contain the location
return -1;
}
unsigned int Solution::missingPairCount() const
{
return pairBank.size();
}
bool Solution::checkModification(AtomicRecreation const &modification) const bool Solution::checkModification(AtomicRecreation const &modification) const
{ {
//std::cout << "--- Check Modification Validity : "; //std::cout << "--- Check Modification Validity : ";
...@@ -276,13 +310,8 @@ void Solution::check() const ...@@ -276,13 +310,8 @@ void Solution::check() const
void Solution::print() const void Solution::print() const
{ {
std::cout << "Cost : " << totalCost << "\n" std::cout << "\nRawCost : " << rawCost << "\n"
<< "Routes : \n"; << "TotalCost : " << totalCost << "\n";
for (Route const &id: getRoutes())
{
id.print();
}
std::cout << "Pair Bank : \n"; std::cout << "Pair Bank : \n";
...@@ -291,7 +320,16 @@ void Solution::print() const ...@@ -291,7 +320,16 @@ void Solution::print() const
std::cout << id << ", "; std::cout << id << ", ";
} }
std::cout << "\nConstraints : \n"; std::cout << "\nRoutes : \n";
int i = 0;
for (Route const &route: getRoutes())
{
std::cout << "#" << i << ": ";
route.print();
++i;
}
std::cout << "Constraints : \n";
for (std::unique_ptr<Constraint> const &constraint: constraints) for (std::unique_ptr<Constraint> const &constraint: constraints)
{ {
constraint->print(); constraint->print();
......
...@@ -76,6 +76,14 @@ public: ...@@ -76,6 +76,14 @@ public:
PDPTWData const &getData() const; PDPTWData const &getData() const;
double getRawCost() const; double getRawCost() const;
double getCost() const; double getCost() const;
unsigned int missingPairCount() const;
std::vector<std::unique_ptr<Constraint>> const &getConstraints() const;
/**
* Return the route index associated to the given location ID.
* -1 if the location is not in a route.
*/
int getRouteIDOf(int locationID) const;
/** /**
* Return the number of fullfilled requests. * Return the number of fullfilled requests.
...@@ -125,7 +133,8 @@ public: ...@@ -125,7 +133,8 @@ public:
Route &getRoute(int routeIndex); Route &getRoute(int routeIndex);
void print() const; void print() const;
void computeAndStoreSolutionCost();
private: private:
/** /**
...@@ -139,11 +148,10 @@ private: ...@@ -139,11 +148,10 @@ private:
void initConstraints(); void initConstraints();
void initRoutes(); void initRoutes();
void initPairBank(); void initPairBank();
void computeAndStoreSolutionCost();
/** /**
* Compute the cost of the solution (routes cost) * Compute the cost of the solution (routes cost)
*/ */
double computeSolutionCost() const; double computeSolutionCost() const;
}; };
\ No newline at end of file
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "input/time_window.h" #include "input/time_window.h"
#include "lns/acceptance/threshold_acceptance.h" #include "lns/acceptance/threshold_acceptance.h"
#include "lns/constraints/capacity/capacity_constraint.h" #include "lns/constraints/capacity/capacity_constraint.h"
#include "lns/constraints/time_window/forward_time_slack.h"
#include "lns/constraints/time_window/time_window_constraint.h" #include "lns/constraints/time_window/time_window_constraint.h"
#include "lns/lns.h" #include "lns/lns.h"
#include "lns/modification/pair/insert_pair.h" #include "lns/modification/pair/insert_pair.h"
...@@ -13,7 +14,9 @@ ...@@ -13,7 +14,9 @@
#include "lns/modification/route/insert_route.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/abstract_operator.h"
#include "lns/operators/destruction/clean_empty_route.h"
#include "lns/operators/destruction/random_destroy.h" #include "lns/operators/destruction/random_destroy.h"
#include "lns/operators/destruction/string_removal.h"
#include "lns/operators/reconstruction/enumerate.h" #include "lns/operators/reconstruction/enumerate.h"
#include "lns/operators/reconstruction/list_heuristic_cost_oriented.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"
...@@ -22,11 +25,15 @@ ...@@ -22,11 +25,15 @@
#include "lns/operators/sorting_strategy.h" #include "lns/operators/sorting_strategy.h"
#include "lns/solution/solution.h" #include "lns/solution/solution.h"
#include "mains/main_interface.h" #include "mains/main_interface.h"
#include "output/solution_checker.h"
#include "output/solution_exporter.h" #include "output/solution_exporter.h"
#include "types.h"
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <iomanip>
#include <iostream> #include <iostream>
#include <limits>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <string> #include <string>
...@@ -46,69 +53,47 @@ void simpleLNS(PDPTWData const &data, Solution &startingSolution) ...@@ -46,69 +53,47 @@ void simpleLNS(PDPTWData const &data, Solution &startingSolution)
ThresholdAcceptance acceptor(0.05); ThresholdAcceptance acceptor(0.05);
// lns operators // lns operators
SimpleOperatorSelector RandomDestroy_ShuffleBestInsert; SimpleOperatorSelector RandomDestroy_BestInsert;
addAllReconstructor(RandomDestroy_ShuffleBestInsert); addAllReconstructor(RandomDestroy_BestInsert);
RandomDestroy_ShuffleBestInsert.addDestructor(RandomDestroy(pairs)); RandomDestroy_BestInsert.addDestructor(RandomDestroy(pairs));
RandomDestroy_BestInsert.addDestructor(StringRemoval(10, 10));
SimpleOperatorSelector largeSelector; SimpleOperatorSelector largeSelector;
addAllReconstructor(largeSelector); addAllReconstructor(largeSelector);
largeSelector.addDestructor(RandomDestroy(pairs)); largeSelector.addDestructor(RandomDestroy(manyPairs));
largeSelector.addDestructor(StringRemoval(10, 10));
// 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; std::vector<SmallLargeOperatorSelector::StepSelector> selectors;
selectors.emplace_back(10, std::move(RandomDestroy_ShuffleBestInsert)); selectors.emplace_back(10, std::move(RandomDestroy_BestInsert));
// selectors.emplace_back(100, std::move(largeSelector)); selectors.emplace_back(50, 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)); SmallLargeOperatorSelector smallLargeSelector(std::move(selectors));
// run lns // run lns
output::LnsOutput result = lns::runLns(startingSolution, smallLargeSelector, acceptor); output::LnsOutput result = lns::runLns(startingSolution, smallLargeSelector, acceptor);
result.getBestSolution().print();
Solution sol = result.getBestSolution();
CleanEmptyRoute clean = CleanEmptyRoute();
clean.destroySolution(sol);
sol.print();
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
//return mainInterface(argc, argv, &simpleLNS); //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/pdp_100/lc102.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";
PDPTWData data = parsing::parseJson(filepath); PDPTWData data = parsing::parseJson(filepath);
Solution startingSolution = Solution::emptySolution(data); Solution startingSolution = Solution::emptySolution(data);
simpleLNS(data, startingSolution);
//simpleLNS(data, startingSolution);
///
std::cout << "===== TEST ===== \n";
Solution testSolution = Solution::emptySolution(data);
//ListHeuristicCostOriented reconstruction = ListHeuristicCostOriented(SortingStrategyType::SHUFFLE, EnumerationType::ALL_INSERT_PAIR);
//reconstruction.reconstructSolution(testSolution, 0.01);
testSolution.print();
sorting_strategy::Shuffle(testSolution).sortPairs();
testSolution.print();
sorting_strategy::TimeWindowStart(testSolution).sortPairs();
testSolution.print();
return 0; return 0;
} }
...@@ -8,7 +8,12 @@ ...@@ -8,7 +8,12 @@
void addAllReconstructor(SimpleOperatorSelector &selector) void addAllReconstructor(SimpleOperatorSelector &selector)
{ {
selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::SHUFFLE, EnumerationType::ALL_INSERT_PAIR)); selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::SHUFFLE, EnumerationType::ALL_INSERT_PAIR), 1);
selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::FAR, EnumerationType::ALL_INSERT_PAIR), 1);
selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::CLOSE, EnumerationType::ALL_INSERT_PAIR), 1);
selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::TWWIDTH, EnumerationType::ALL_INSERT_PAIR), 1);
selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::TWSTART, EnumerationType::ALL_INSERT_PAIR), 1);
selector.addReconstructor(ListHeuristicCostOriented(SortingStrategyType::TWEND, EnumerationType::ALL_INSERT_PAIR), 1);
} }
int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solution &)> function) int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solution &)> function)
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "input/data.h" #include "input/data.h"
#include "input/location.h" #include "input/location.h"
#include "input/pdptw_data.h" #include "input/pdptw_data.h"
#include "lns/operators/destruction/clean_empty_route.h"
#include "lns/solution/solution.h" #include "lns/solution/solution.h"
#include "types.h" #include "types.h"
...@@ -20,20 +21,20 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data) ...@@ -20,20 +21,20 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
// checking routes coherence // checking routes coherence
int routeID = 0; int routeID = 0;
for (Route const &route: sol.getRoutes()) for (Route const &route: sol.getRoutes())
{ {
// skip if it is an empty route // skip if it is an empty route
if (!route.getRoute().empty()) if (!route.getRoute().empty())
{ {
for (int LocID: route.getRoute()) for (int LocID: route.getRoute())
{ {
if (check.at(LocID -1) != -1) if (check.at(LocID - 1) != -1)
{ {
// 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;
} }
check.at(LocID -1) = routeID; check.at(LocID - 1) = routeID;
// if the location is a delivery, check if the pickup location has already been visited in the same route // if the location is a delivery, check if the pickup location has already been visited in the same route
if ((data.getLocation(LocID).getLocType() == LocType::DELIVERY) && if ((data.getLocation(LocID).getLocType() == LocType::DELIVERY) &&
...@@ -64,7 +65,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data) ...@@ -64,7 +65,6 @@ void checker::checkSolutionCoherence(Solution const &sol, PDPTWData const &data)
if (errorFlag) if (errorFlag)
{ {
sol.print();
throw SolutionConstraintError("Error in the consistency of the solution.", sol); throw SolutionConstraintError("Error in the consistency of the solution.", sol);
} }
} }
...@@ -77,22 +77,25 @@ void checker::checkCapacity(Solution const &sol, PDPTWData const &data) ...@@ -77,22 +77,25 @@ void checker::checkCapacity(Solution const &sol, PDPTWData const &data)
for (Route const &route: sol.getRoutes()) for (Route const &route: sol.getRoutes())
{ {
for (int id: route.getRoute()) if (!route.getRoute().empty())
{ {
capa += data.getLocation(id).getDemand(); for (int id: route.getRoute())
if (capa > data.getCapacity()) {
capa += data.getLocation(id).getDemand();
if (capa > data.getCapacity())
{
// Error, max capacity is exceeded
spdlog::error("Maximum Capacity is exceeded at {} in the route {}.", id, routeID);
errorFlag = true;
}
}
if (capa != 0)
{ {
// Error, max capacity is exceeded // Error, all the capacity is supposed to be free at the end of a route
spdlog::error("Maximum Capacity is exceeded at {} in the route {}.", id, routeID); spdlog::error("Some capacity still used at the end of the route {}.", routeID);
errorFlag = true; errorFlag = true;
} }
} }
if (capa != 0)
{
// Error, all the capacity is supposed to be free at the end of a route
spdlog::error("Some capacity still used at the end of the route {}.", routeID);
errorFlag = true;
}
++routeID; ++routeID;
} }
...@@ -109,38 +112,41 @@ void checker::checkTimeWindows(Solution const &sol, PDPTWData const &data) ...@@ -109,38 +112,41 @@ void checker::checkTimeWindows(Solution const &sol, PDPTWData const &data)
int routeID = 0; int routeID = 0;
int locID = 0; int locID = 0;
for (Route const &route: sol.getRoutes()) for (Route const &route: sol.getRoutes())
{ {
// travel to the first location if (!route.getRoute().empty())
reachTime = data.getDepot().getTimeWindow().getStart() + data::TravelTime(data, 0, route.getRoute().at(0));
for (int i = 0; i < route.getRoute().size() - 1; i++)
{ {
locID = route.getRoute().at(i); // travel to the first location
// check TimeWindow reachTime = data.getDepot().getTimeWindow().getStart() + data::TravelTime(data, 0, route.getRoute().at(0));
for (int i = 0; i < route.getRoute().size() - 1; i++)
{
locID = route.getRoute().at(i);
// check TimeWindow
if (!(data.getLocation(locID).getTimeWindow().isValid(reachTime)))
{
// Error, reach time not valid for the location time window
spdlog::error("Reach time not valid for the location {} time window in route {}.", locID, routeID);
errorFlag = true;
}
TimeInteger travelTime = data::TravelTime(data, locID, route.getRoute().at(i + 1));
TimeInteger serviceTime = data.getLocation(locID).getServiceDuration();
TimeInteger startTW = data.getLocation(locID).getTimeWindow().getStart();
reachTime = std::max(reachTime, startTW) + serviceTime + travelTime;
}
// check last timeWindow
locID = route.getRoute().back();
if (!(data.getLocation(locID).getTimeWindow().isValid(reachTime))) if (!(data.getLocation(locID).getTimeWindow().isValid(reachTime)))
{ {
// Error, reach time not valid for the location time window // Error, reach time not valid for the location time window
spdlog::error("Reach time not valid for the location {} time window in route {}.", locID, routeID); spdlog::error("Reach time not valid for the location {} time window in route {}.", locID, routeID);
errorFlag = true; errorFlag = true;
} }
TimeInteger travelTime = data::TravelTime(data, locID, route.getRoute().at(i + 1));
TimeInteger serviceTime = data.getLocation(locID).getServiceDuration();
TimeInteger startTW = data.getLocation(locID).getTimeWindow().getStart();
reachTime = std::max(reachTime, startTW) + serviceTime + travelTime;
} }
// check last timeWindow
locID = route.getRoute().back();
if (!(data.getLocation(locID).getTimeWindow().isValid(reachTime)))
{
// Error, reach time not valid for the location time window
spdlog::error("Reach time not valid for the location {} time window in route {}.", locID, routeID);
errorFlag = true;
}
++routeID; ++routeID;
} }
......