From 2fc0df0b66309314534d1f92e2146ea34b59f8e2 Mon Sep 17 00:00:00 2001 From: awenjb <126257927+awenjb@users.noreply.github.com> Date: Fri, 28 Feb 2025 15:57:32 +0100 Subject: [PATCH] Update Code - revised some parts of the code - add some comments - add config.h and types.h - data init with the list of Pair - Solution init and link with constraints --- CMakeLists.txt | 3 +- src/config.h | 3 + src/input/data.cpp | 4 +- src/input/data.h | 5 +- src/input/json_parser.cpp | 5 +- src/input/location.cpp | 17 ++- src/input/location.h | 27 +++- src/input/pair.cpp | 26 +++- src/input/pair.h | 19 ++- src/input/pdptw_data.cpp | 39 +++++- src/input/pdptw_data.h | 27 ++-- src/input/time_window.cpp | 7 - src/input/time_window.h | 15 +-- .../capacity/capacity_constraint.h | 10 +- src/lns/constraints/constraint.cpp | 2 +- src/lns/constraints/constraint.h | 16 ++- .../time_window/time_window_constraint.cpp | 119 +++++++++++++---- .../time_window/time_window_constraint.h | 14 +- src/lns/modification/atomic_destruction.h | 3 +- src/lns/modification/atomic_modification.h | 5 + src/lns/modification/atomic_recreation.h | 1 + src/lns/modification/pair/insert_pair.cpp | 37 +++--- src/lns/modification/pair/insert_pair.h | 23 ++-- src/lns/modification/pair/remove_pair.cpp | 27 ++-- src/lns/modification/pair/remove_pair.h | 25 ++-- src/lns/modification/route/insert_route.cpp | 4 +- src/lns/modification/route/insert_route.h | 10 +- src/lns/modification/route/remove_route.cpp | 9 +- src/lns/modification/route/remove_route.h | 18 +-- src/lns/solution/route.h | 3 +- src/lns/solution/solution.cpp | 91 +++++++++++-- src/lns/solution/solution.h | 73 +++++++++-- src/main.cpp | 96 -------------- src/mains/main.cpp | 123 ++++++++++++++++++ src/mains/main_interface.cpp | 41 ++++++ src/mains/main_interface.h | 8 ++ src/types.h | 23 ++++ 37 files changed, 691 insertions(+), 287 deletions(-) create mode 100644 src/config.h delete mode 100644 src/main.cpp create mode 100644 src/mains/main.cpp create mode 100644 src/mains/main_interface.cpp create mode 100644 src/mains/main_interface.h create mode 100644 src/types.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b53e89f..9f66893 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,8 @@ find_package(spdlog REQUIRED) -add_executable(pdptw src/main.cpp +add_executable(pdptw src/mains/main.cpp + src/mains/main_interface.cpp src/input/data.cpp src/input/location.cpp src/input/pair.cpp diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..bf368d8 --- /dev/null +++ b/src/config.h @@ -0,0 +1,3 @@ + + +const int EXCLUSION_PENALTY = 100; \ No newline at end of file diff --git a/src/input/data.cpp b/src/input/data.cpp index ded7518..59448dc 100644 --- a/src/input/data.cpp +++ b/src/input/data.cpp @@ -41,9 +41,9 @@ double data::routeCost(PDPTWData const & data, Route const & route) return cost; } -double data::TravelCost(PDPTWData const &data, int index1, int index2) +double data::TravelCost(PDPTWData const &data, int from, int to) { - return data.getMatrix()[index1][index2]; + return data.getMatrix()[from][to]; } double data::TravelTime(PDPTWData const &data, int from, int to) diff --git a/src/input/data.h b/src/input/data.h index 7277150..a0b2e2e 100644 --- a/src/input/data.h +++ b/src/input/data.h @@ -3,7 +3,8 @@ #include "time_window.h" #include "pdptw_data.h" #include "location.h" -#include "../lns/solution/route.h" +#include "lns/solution/solution.h" + /** * Functions for PDPTWData @@ -38,7 +39,7 @@ namespace data * Return the travel cost between two location * (take location id in parameters) */ - double TravelCost(PDPTWData const &data, int index1, int index2); + double TravelCost(PDPTWData const &data, int from, int to); /** * Return the travel time between two location diff --git a/src/input/json_parser.cpp b/src/input/json_parser.cpp index 52c7ecf..31d221c 100644 --- a/src/input/json_parser.cpp +++ b/src/input/json_parser.cpp @@ -51,7 +51,7 @@ PDPTWData parsing::parseJson(std::string filepath) PDPTWData json_to_data(const json& j) { - unsigned int size = j.at("size").get<unsigned int>(); + int size = j.at("size").get<int>(); int capacity = j.at("capacity").get<int>(); auto depot_json = j.at("depot"); @@ -68,7 +68,6 @@ PDPTWData json_to_data(const json& j) LocType::DEPOT ); - std::vector<Location> locations; for (const auto& loc : j.at("locations")) @@ -90,5 +89,5 @@ PDPTWData json_to_data(const json& j) Matrix distance_matrix = j.at("distance_matrix").get<Matrix>(); - return PDPTWData(size, capacity, depot, locations, distance_matrix); + return {size, capacity, depot, locations, distance_matrix}; } diff --git a/src/input/location.cpp b/src/input/location.cpp index 8ccec5f..c012701 100644 --- a/src/input/location.cpp +++ b/src/input/location.cpp @@ -1,9 +1,9 @@ #include "location.h" -Location::Location(unsigned int id, double lon, double lat, int dem, TimeWindow tw, double service, unsigned int pairId, LocType type) - : id(id), longitude(lon), latitude(lat), demand(dem), timeWindow(tw), serviceDuration(service), pairedLocation(pairId), locType(type) {} - +Location::Location(int id, double lon, double lat, int dem, TimeWindow tw, double service, int pairId, LocType type) + : id(id), longitude(lon), latitude(lat), demand(dem), timeWindow(tw), serviceDuration(service), pairedLocationID(pairId), locType(type) +{} double Location::getLongitude() const { return longitude; @@ -17,12 +17,12 @@ double Location::getServiceDuration() const { return serviceDuration; } -unsigned int Location::getId() const { +int Location::getId() const { return id; } -unsigned int Location::getPair() const { - return pairedLocation; +int Location::getPair() const { + return pairedLocationID; } int Location::getDemand() const { @@ -37,7 +37,7 @@ TimeWindow Location::getTimeWindow() const { return timeWindow; } -std::string Location::LocTypeToString(LocType type) const +std::string Location::LocTypeToString(LocType type) { switch (type) { case LocType::DEPOT: return "Depot"; @@ -47,11 +47,10 @@ std::string Location::LocTypeToString(LocType type) const } } - void Location::print() const { std::cout << "Location ID: " << id << ", Coordinates: (" << longitude << ", " << latitude << ")\n"; - std::cout << "Location Type : " << Location::LocTypeToString(locType) << ", Associated location : " << pairedLocation << "\n"; + std::cout << "Location Type : " << Location::LocTypeToString(locType) << ", Associated location : " << pairedLocationID << "\n"; std::cout << "Demand : " << demand << "\n"; timeWindow.print(); } \ No newline at end of file diff --git a/src/input/location.h b/src/input/location.h index 8aac218..e7a1646 100644 --- a/src/input/location.h +++ b/src/input/location.h @@ -23,31 +23,46 @@ enum class LocType */ class Location { - unsigned int id; + /* + * The location ID + */ + int id; double longitude; double latitude; + /* + * Represent the capacity used by that location. + * The location demand must be positive if it is a PICKUP, negative if it is a DELIVERY and 0 for a DEPOT. + */ int demand; double serviceDuration; - unsigned int pairedLocation; + /* + * The location ID associated to form a pickup and delivery pair. + * (the same ID if the location is a depot) + */ + int pairedLocationID; + /* + * The type of the location (PICKUP, DELIVERY, DEPOT). + */ LocType locType; TimeWindow timeWindow; public: - Location(unsigned int id, double lon, double lat, int dem, TimeWindow tw, double service, unsigned int pairId, LocType type); + Location(int id, double lon, double lat, int dem, TimeWindow tw, double service, int pairId, LocType type); double getLongitude() const; double getLatitude() const; double getServiceDuration() const; - unsigned getId() const; - unsigned int getPair() const; + int getId() const; + int getPair() const; int getDemand() const; LocType getLocType() const; TimeWindow getTimeWindow() const; void print() const; - std::string LocTypeToString(LocType type) const; + static std::string LocTypeToString(LocType type); + // Json parsing friend void from_json(nlohmann::json const &json, Location &location); }; \ No newline at end of file diff --git a/src/input/pair.cpp b/src/input/pair.cpp index ccdccb0..fa7223d 100644 --- a/src/input/pair.cpp +++ b/src/input/pair.cpp @@ -1,7 +1,7 @@ #include "pair.h" -Pair::Pair(const Location& pickupLoc, const Location& deliveryLoc) -: pickup(pickupLoc), delivery(deliveryLoc) {} +Pair::Pair(const Location& pickup, const Location& delivery, int pairID) +: pickup(pickup), delivery(delivery), pairID(pairID) {} const Location& Pair::getPickup() const { @@ -11,4 +11,26 @@ const Location& Pair::getPickup() const const Location& Pair::getDelivery() const { return delivery.get(); +} + +const Location& Pair::getP() const +{ + return pickup.get(); +} + +const Location& Pair::getD() const +{ + return delivery.get(); +} + +int Pair::getID() const +{ + return pairID; +} + +void Pair::print() const +{ + pickup.get().print(); + std::cout << "\n"; + delivery.get().print(); } \ No newline at end of file diff --git a/src/input/pair.h b/src/input/pair.h index 4183a20..b7dfc6b 100644 --- a/src/input/pair.h +++ b/src/input/pair.h @@ -2,16 +2,31 @@ #include "location.h" -// Represent a pair pickup/delivery of location +/** + * Represent a pair pickup/delivery of location + * The pair ID is the pickup ID + */ class Pair { private: std::reference_wrapper<Location const> pickup; std::reference_wrapper<Location const> delivery; + int pairID; public: - Pair(const Location& pickupLoc, const Location& deliveryLoc); + Pair(const Location& pickup, const Location& delivery, int pairID); const Location& getPickup() const; const Location& getDelivery() const; + /** + * getPickup() but shorter + */ + const Location& getP() const; + /** + * getDelivery() but shorter + */ + const Location& getD() const; + int getID() const; + + void print() const; }; \ No newline at end of file diff --git a/src/input/pdptw_data.cpp b/src/input/pdptw_data.cpp index 6b819c6..142fbde 100644 --- a/src/input/pdptw_data.cpp +++ b/src/input/pdptw_data.cpp @@ -2,12 +2,10 @@ #include <iostream> #include <fstream> -#include <vector> -#include <nlohmann/json.hpp> #include <spdlog/spdlog.h> -unsigned int PDPTWData::getSize() +int PDPTWData::getSize() const { return size; } @@ -22,6 +20,11 @@ std::vector<Location> const &PDPTWData::getLocations() const return locations; } +std::vector<Pair> const &PDPTWData::getPairs() const +{ + return pairs; +} + Location const &PDPTWData::getDepot() const { return depot; @@ -29,7 +32,12 @@ Location const &PDPTWData::getDepot() const Location const &PDPTWData::getLocation(int id) const { - return locations[id]; + if (id==0) + { + return getDepot(); + } + // location index from 0 to n-1 + return locations.at(id -1); } Matrix const &PDPTWData::getMatrix() const @@ -37,8 +45,20 @@ Matrix const &PDPTWData::getMatrix() const return distanceMatrix; } -PDPTWData::PDPTWData(unsigned int size, int capacity, Location depot, std::vector<Location> location, Matrix distanceMatrix) - : size(size), capacity(capacity), depot(depot), locations(std::move(location)), distanceMatrix(std::move(distanceMatrix)) {} +PDPTWData::PDPTWData(int size, int capacity, Location depot, std::vector<Location> locations, Matrix distanceMatrix) + : size(size), capacity(capacity), depot(depot), locations(std::move(locations)), distanceMatrix(std::move(distanceMatrix)) +{ + // Associate pair of locations + pairs.clear(); + for (const Location & loc : this->locations) + { + if( loc.getLocType() == LocType::PICKUP ) + { + // vector indexed from 0 / Location indexed from 1 + pairs.emplace_back(loc, locations[loc.getPair()-1], loc.getId()); + } + } +} void PDPTWData::print() const @@ -60,6 +80,13 @@ void PDPTWData::print() const } std::cout << "\n"; } + + std::cout << "Pair IDs:\n"; + for (const auto& pair : pairs) + {; + std::cout << pair.getID() << " "; + } + std::cout << " \n"; } void PDPTWData::checkData() const diff --git a/src/input/pdptw_data.h b/src/input/pdptw_data.h index b7a504e..ac0ea57 100644 --- a/src/input/pdptw_data.h +++ b/src/input/pdptw_data.h @@ -1,12 +1,13 @@ #pragma once -#include "location.h" -#include <functional> #include <nlohmann/json_fwd.hpp> #include <vector> +#include "pair.h" +#include "location.h" +#include "types.h" + using json = nlohmann::json; -using Matrix = std::vector<std::vector<double>>; /** * Throw this exception after errors in the input has been found. @@ -20,29 +21,28 @@ public: char const *what() const noexcept override; }; - - class PDPTWData { - unsigned int size; + int size; int capacity; Location depot; std::vector<Location> locations; + std::vector<Pair> pairs; // std::unordered_map<int, Pair> pair; if getPair(index) is needed ? Matrix distanceMatrix; - public: PDPTWData(); PDPTWData(PDPTWData const &rhs) = delete; PDPTWData(PDPTWData &&rhs) noexcept; PDPTWData &operator=(PDPTWData &&rhs) noexcept; PDPTWData &operator=(PDPTWData const &rhs) = delete; + ~PDPTWData() = default; /** * Constructs an empty PDPTWData. * @see parsing::parseJson */ - PDPTWData(unsigned int size, int capacity, Location depot, std::vector<Location> requests, Matrix distanceMatrix); + PDPTWData(int size, int capacity, Location depot, std::vector<Location> locations, Matrix distanceMatrix); /** * Checks some data coherence */ @@ -50,13 +50,20 @@ public: bool checkMatrix() const; bool checkLocation() const; - + std::vector<Location> const &getLocations() const; + std::vector<Pair> const &getPairs() const; + + /** + * 0 return the depot. + * Other numbers return the associated location. + */ Location const &getLocation(int id) const; Location const &getDepot() const; + Matrix const &getMatrix() const; - unsigned int getSize(); + int getSize() const; int getCapacity() const; void print() const; diff --git a/src/input/time_window.cpp b/src/input/time_window.cpp index 086268c..7f6eb3a 100644 --- a/src/input/time_window.cpp +++ b/src/input/time_window.cpp @@ -31,10 +31,3 @@ void TimeWindow::print() const { std::cout << "Time Window : [" << start << ", " << end << "] \n"; } -/* -TimeInteger TimeWindow::waitingTimeBefore(TimeInteger t) const -{ - return std::max<TimeInteger>(0, t - start); -} -*/ - diff --git a/src/input/time_window.h b/src/input/time_window.h index 594bc1f..ce9d56c 100644 --- a/src/input/time_window.h +++ b/src/input/time_window.h @@ -1,14 +1,8 @@ #pragma once -#include <iostream> -#include <limits> #include <nlohmann/json_fwd.hpp> -/** - * A point in time or a duration. - */ -using TimeInteger = double; -TimeInteger constexpr UNDEF_TIMESTAMP = std::numeric_limits<TimeInteger>::max(); +#include "types.h" /** * Represents a time window [start, end] with some basic utilities. @@ -29,12 +23,7 @@ public: //Checks whether the time t is inside the time window OR before bool isValid(TimeInteger t) const; - /** - * return the time to wait from t to the start of this time window. - * @return 0 if t is after start, or start - t - */ - //TimeInteger waitingTimeBefore(TimeInteger t) const; - void print() const; + friend void from_json(nlohmann::json const &json, TimeWindow &tw); }; \ No newline at end of file diff --git a/src/lns/constraints/capacity/capacity_constraint.h b/src/lns/constraints/capacity/capacity_constraint.h index 3114953..c1a668c 100644 --- a/src/lns/constraints/capacity/capacity_constraint.h +++ b/src/lns/constraints/capacity/capacity_constraint.h @@ -1,7 +1,13 @@ #pragma once +#include <vector> -#include "./../constraint.h" -#include "./../../../input/pair.h" +#include "lns/constraints/constraint.h" + +#include "lns/solution/solution.h" +#include "lns/modification/pair/insert_pair.h" +#include "lns/modification/pair/remove_pair.h" +#include "lns/modification/route/insert_route.h" +#include "lns/modification/route/remove_route.h" /** * Capacity constraint. diff --git a/src/lns/constraints/constraint.cpp b/src/lns/constraints/constraint.cpp index 51f375e..23d9315 100644 --- a/src/lns/constraints/constraint.cpp +++ b/src/lns/constraints/constraint.cpp @@ -1,5 +1,5 @@ #include "constraint.h" - +#include "lns/solution/solution.h" Constraint::Constraint(Solution const &solution) : solution(solution) {} diff --git a/src/lns/constraints/constraint.h b/src/lns/constraints/constraint.h index f41e778..6e27f9f 100644 --- a/src/lns/constraints/constraint.h +++ b/src/lns/constraints/constraint.h @@ -1,12 +1,16 @@ #pragma once + +#include <memory> +#include <stdexcept> #include <variant> -#include "./../solution/solution.h" -// all modifications -#include "./../modification/pair/insert_pair.h" -#include "./../modification/pair/remove_pair.h" -#include "./../modification/route/insert_route.h" -#include "./../modification/route/remove_route.h" +// forward declaration of all modifications +class InsertPair; +class RemovePair; +class InsertRoute; +class RemoveRoute; +class Solution; +class PDPTWData; using ModificationApplyVariant = diff --git a/src/lns/constraints/time_window/time_window_constraint.cpp b/src/lns/constraints/time_window/time_window_constraint.cpp index fe4134e..b350692 100644 --- a/src/lns/constraints/time_window/time_window_constraint.cpp +++ b/src/lns/constraints/time_window/time_window_constraint.cpp @@ -1,13 +1,23 @@ #include "time_window_constraint.h" + #include "input/data.h" #include "input/pdptw_data.h" #include "input/time_window.h" +#include "lns/modification/pair/insert_pair.h" +#include "lns/modification/pair/remove_pair.h" +#include "lns/modification/route/remove_route.h" #include "lns/solution/solution.h" -TimeWindowConstraint::TimeWindowConstraint(Solution const &solution) : Constraint(solution) +TimeWindowConstraint::TimeWindowConstraint(const Solution& solution) : Constraint(solution) +{ + allRouteReachTimes.resize(getSolution().getRoutes().size()); +} + + +TimeWindowConstraint::~TimeWindowConstraint() { - // Empty + allRouteReachTimes.clear(); } std::unique_ptr<Constraint> TimeWindowConstraint::clone(Solution const &newOwningSolution) const { @@ -16,6 +26,37 @@ std::unique_ptr<Constraint> TimeWindowConstraint::clone(Solution const &newOwnin return clonePtr; } +void TimeWindowConstraint::computeReachTimes(const PDPTWData& data, const std::vector<int> & routeIDs, ReachTimeVector & reachTimes) const +{ + // Adjust the size of reachTimes vector + reachTimes.resize(routeIDs.size(), 0); + // Time to the first location + reachTimes[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) { + TimeInteger travelTime = data::TravelTime(data, routeIDs[i - 1], routeIDs[i]); + // locations are indexed from 0 to n-1, + TimeInteger serviceTime = data.getLocation(routeIDs[i - 1]).getServiceDuration(); + TimeInteger startTW = data.getLocation(routeIDs[i - 1]).getTimeWindow().getStart(); + + reachTimes[i] = std::max(reachTimes[i - 1], startTW) + serviceTime + travelTime; + } +} + +void TimeWindowConstraint::initReachTimes() +{ + allRouteReachTimes = std::vector<ReachTimeVector>(); + int i = 0; + for (const Route& route : getSolution().getRoutes()) + { + // init and calculate reach time value + allRouteReachTimes.emplace_back(); + computeReachTimes(getSolution().getData(), route.getRoute(), allRouteReachTimes.at(i)); + ++i; + } +} + + // Copie le vecteur de reach time de la route concernée // Insère les positions pickup/delivery @@ -30,14 +71,29 @@ bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pa ReachTimeVector newReachTimes(reachTimes.begin(), reachTimes.end()); // Insert pickup and delivery - route.insert(route.begin() + pickupPos, pair.getPickup().getId()); route.insert(route.begin() + deliveryPos, pair.getDelivery().getId()); + route.insert(route.begin() + pickupPos, pair.getPickup().getId()); + + + std::cout << "\n"; + for (auto pos : route) + { + std::cout << pos << " "; + } + std::cout << "\n"; // Compute new reach time computeReachTimes(data, route, newReachTimes); + std::cout << "\n"; + for (auto pos : newReachTimes) + { + std::cout << pos << " "; + } + std::cout << "\n"; + // Check Time Windows - for (int i = 0; i < reachTimes.size(); ++i) + for (int i = 0; i < newReachTimes.size(); ++i) { if (! data.getLocation(route[i]).getTimeWindow().isValid(newReachTimes.at(i)) ) { @@ -47,20 +103,6 @@ bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pa return true; } -void TimeWindowConstraint::computeReachTimes(const PDPTWData& data, const std::vector<int> & routeIDs, ReachTimeVector & reachTimes) const -{ - // Adjust the size of reachTimes vector - reachTimes.resize(routeIDs.size(), 0); - // Time to the first location - reachTimes[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[i - 1], routeIDs[i]); - TimeInteger serviceTime = data.getLocation(routeIDs[i - 1]).getServiceDuration(); - TimeInteger startTW = data.getLocation(routeIDs[i]).getTimeWindow().getStart(); - reachTimes[i] = std::max(reachTimes[i - 1] + serviceTime + travelTime, startTW); - } -} void TimeWindowConstraint::ApplyModif(const PDPTWData& data, const Pair & pair, int routeIndex, int pickupPos, int deliveryPos, bool addPair) @@ -71,8 +113,8 @@ void TimeWindowConstraint::ApplyModif(const PDPTWData& data, const Pair & pair, // Adjust pickup and delivery if (addPair) { - routeIDs.insert(routeIDs.begin() + pickupPos, pair.getPickup().getId()); routeIDs.insert(routeIDs.begin() + deliveryPos, pair.getDelivery().getId()); + routeIDs.insert(routeIDs.begin() + pickupPos, pair.getPickup().getId()); } else { @@ -88,11 +130,25 @@ void TimeWindowConstraint::ApplyModif(const PDPTWData& data, const Pair & pair, for (int i = 1; i < routeIDs.size(); ++i) { TimeInteger travelTime = data::TravelTime(data, routeIDs[i - 1], routeIDs[i]); TimeInteger serviceTime = data.getLocation(routeIDs[i - 1]).getServiceDuration(); - TimeInteger startTW = data.getLocation(routeIDs[i]).getTimeWindow().getStart(); - allRouteReachTimes[routeIndex][i] = std::max(allRouteReachTimes[routeIndex][i - 1] + serviceTime + travelTime, startTW); + TimeInteger startTW = data.getLocation(routeIDs[i - 1]).getTimeWindow().getStart(); + allRouteReachTimes[routeIndex][i] = std::max(allRouteReachTimes[routeIndex][i - 1], startTW) + serviceTime + travelTime; } } +/* + // Adjust the size of reachTimes vector + reachTimes.resize(routeIDs.size(), 0); + // Time to the first location + reachTimes[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) { + TimeInteger travelTime = data::TravelTime(data, routeIDs[i - 1], routeIDs[i]); + // locations are indexed from 0 to n-1, + TimeInteger serviceTime = data.getLocation(routeIDs[i - 1]).getServiceDuration(); + TimeInteger startTW = data.getLocation(routeIDs[i - 1]).getTimeWindow().getStart(); + reachTimes[i] = std::max(reachTimes[i - 1], startTW) + serviceTime + travelTime; + } +*/ bool TimeWindowConstraint::check(InsertPair const &op) const { @@ -132,6 +188,25 @@ void TimeWindowConstraint::apply(RemoveRoute const &op) allRouteReachTimes.erase(allRouteReachTimes.begin() + op.getRouteIndex()); } +const std::vector<TimeWindowConstraint::ReachTimeVector>& TimeWindowConstraint::getallRouteReachTimes() const { + return allRouteReachTimes; +} - +void TimeWindowConstraint::print() const +{ + std::cout << "Reach Times : \n"; + int i = 0; + for (const auto& reachTimes : getallRouteReachTimes()) + { + //std::cout << reachTimes.size() << ", "; + std::cout << "#" << i << " : "; + for (const TimeInteger reachTime : reachTimes) + { + std::cout << reachTime << ", "; + } + std::cout << "\n "; + i++; + } + std::cout << "\n"; +} diff --git a/src/lns/constraints/time_window/time_window_constraint.h b/src/lns/constraints/time_window/time_window_constraint.h index 89bc055..6b0582b 100644 --- a/src/lns/constraints/time_window/time_window_constraint.h +++ b/src/lns/constraints/time_window/time_window_constraint.h @@ -3,6 +3,7 @@ #include "lns/constraints/constraint.h" #include "input/pair.h" #include "input/time_window.h" +#include "lns/solution/route.h" #include <vector> /** @@ -14,15 +15,22 @@ class TimeWindowConstraint : public Constraint { public: + using ReachTimeVector = std::vector<TimeInteger>; + explicit TimeWindowConstraint(Solution const &); TimeWindowConstraint(TimeWindowConstraint const &) = default; + ~TimeWindowConstraint() override; + + // Given the solution, calculate the reachTimes of each location. + // Modify the routeCapacities vector ! + void initReachTimes(); std::unique_ptr<Constraint> clone(Solution const &newOwningSolution) const override; -private: - using ReachTimeVector = std::vector<TimeInteger>; - + const std::vector<ReachTimeVector> & getallRouteReachTimes() const; + void print() const; +private: /** * For each route, store the reach time of each location diff --git a/src/lns/modification/atomic_destruction.h b/src/lns/modification/atomic_destruction.h index c396ca6..f2ad02f 100644 --- a/src/lns/modification/atomic_destruction.h +++ b/src/lns/modification/atomic_destruction.h @@ -1,7 +1,7 @@ #pragma once #include "atomic_modification.h" -#include <vector> + class Location; @@ -11,6 +11,7 @@ class Location; class AtomicDestruction : public AtomicModification { public: + ~AtomicDestruction() override = default; /** * @return the location ID removed from the solution. */ diff --git a/src/lns/modification/atomic_modification.h b/src/lns/modification/atomic_modification.h index 835ef39..c189594 100644 --- a/src/lns/modification/atomic_modification.h +++ b/src/lns/modification/atomic_modification.h @@ -1,5 +1,8 @@ #pragma once +#include <vector> + +#include "lns/constraints/constraint.h" class Solution; /** @@ -10,6 +13,8 @@ class Solution; class AtomicModification { public: + virtual ~AtomicModification() = default; + /** * Return the cost of the operation. * @return a positive number if the solution cost is bigger after the modification. diff --git a/src/lns/modification/atomic_recreation.h b/src/lns/modification/atomic_recreation.h index f554a25..1d726a4 100644 --- a/src/lns/modification/atomic_recreation.h +++ b/src/lns/modification/atomic_recreation.h @@ -10,6 +10,7 @@ class Location; class AtomicRecreation : public AtomicModification { public: + ~AtomicRecreation() override = default; /** * @return the pickup location added to the solution, nullptr if none were added diff --git a/src/lns/modification/pair/insert_pair.cpp b/src/lns/modification/pair/insert_pair.cpp index 206d66f..b3f9d4b 100644 --- a/src/lns/modification/pair/insert_pair.cpp +++ b/src/lns/modification/pair/insert_pair.cpp @@ -1,24 +1,22 @@ #include "insert_pair.h" -#include "./../../../input/data.h" +#include "input/data.h" -InsertPair::InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, - Location const &pickupLocation, Location const &deliveryLocation) - : routeIndex(routeIndex), - pickupInsertion(pickupInsertion), - deliveryInsertion(deliveryInsertion), - pickupLocation(pickupLocation), - deliveryLocation(deliveryLocation), - pair(Pair(pickupLocation, deliveryLocation)) {} +InsertPair::InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, Pair const &pair) : + routeIndex(routeIndex), + pickupInsertion(pickupInsertion), + deliveryInsertion(deliveryInsertion), + pickupLocation(pair.getPickup()), + deliveryLocation(pair.getDelivery()), + pair(pair) {} -InsertPair::InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, - Pair const &pair) - : routeIndex(routeIndex), - pickupInsertion(pickupInsertion), - deliveryInsertion(deliveryInsertion), - pickupLocation(pair.getPickup()), - deliveryLocation(pair.getDelivery()), - pair(pair) {} +InsertPair::InsertPair(Index position, Pair const &pair) : + routeIndex(std::get<0>(position)), + pickupInsertion(std::get<1>(position)), + deliveryInsertion(std::get<2>(position)), + pickupLocation(pair.getPickup()), + deliveryLocation(pair.getDelivery()), + pair(pair) {} void InsertPair::modifySolution(Solution &solution) @@ -94,4 +92,7 @@ const Pair &InsertPair::getPair() const return pair; } - +Index InsertPair::getIndex() const +{ + return std::make_tuple(routeIndex, pickupInsertion, deliveryInsertion); +} \ No newline at end of file diff --git a/src/lns/modification/pair/insert_pair.h b/src/lns/modification/pair/insert_pair.h index ddeea7f..d806765 100644 --- a/src/lns/modification/pair/insert_pair.h +++ b/src/lns/modification/pair/insert_pair.h @@ -1,12 +1,14 @@ #pragma once -#include "./../atomic_recreation.h" -#include "./../../solution/solution.h" -#include "./../../../input/location.h" -#include "./../../../input/pair.h" #include <functional> +#include <tuple> + +#include "lns/modification/atomic_recreation.h" +#include "lns/solution/solution.h" +#include "input/location.h" +#include "input/pair.h" +#include "types.h" -class Route; /** * A modification that will insert a pair (pickup/delivery) of location in a route at the given index. @@ -24,6 +26,7 @@ class InsertPair : public AtomicRecreation * Index at which the insertion must be made */ int pickupInsertion; + /** * Index at which the insertion must be made */ @@ -33,6 +36,7 @@ class InsertPair : public AtomicRecreation * The pickup location to insert */ Location const & pickupLocation; + /** * The delivery location to insert */ @@ -41,11 +45,15 @@ class InsertPair : public AtomicRecreation Pair const & pair; public: - InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, Location const &pickupLocation, Location const &deliveryLocation); + InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, Pair const &pair); + InsertPair(Index position, Pair const &pair); + + ~InsertPair() override = default; void modifySolution(Solution &solution) override; double evaluate(Solution const &solution) const override; + Location const *getAddedLocation() const override; int getPickupInsertion() const; int getDeliveryInsertion() const; @@ -53,7 +61,6 @@ public: Location const &getPickupLocation() const; Location const &getDeliveryLocation() const; Pair const &getPair() const; + Index getIndex() const; - Location const *getAddedLocation() const override; - }; \ No newline at end of file diff --git a/src/lns/modification/pair/remove_pair.cpp b/src/lns/modification/pair/remove_pair.cpp index fcb2fb4..1a1c808 100644 --- a/src/lns/modification/pair/remove_pair.cpp +++ b/src/lns/modification/pair/remove_pair.cpp @@ -1,25 +1,25 @@ #include "remove_pair.h" -#include "../../../input/data.h" +#include "input/data.h" -RemovePair::RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion, - Location const &pickupLocation, Location const &deliveryLocation) : +RemovePair::RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion, Pair const &pair) : routeIndex(routeIndex), pickupDeletion(pickupDeletion), deliveryDeletion(deliveryDeletion), - pickupLocation(pickupLocation), - deliveryLocation(deliveryLocation), - pair(Pair(pickupLocation, deliveryLocation)) {} + pickupLocation(pair.getPickup()), + deliveryLocation(pair.getDelivery()), + pair(pair) {} -RemovePair::RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion, - Pair const &pair) : - routeIndex(routeIndex), - pickupDeletion(pickupDeletion), - deliveryDeletion(deliveryDeletion), + +RemovePair::RemovePair(Index position, Pair const &pair) : + routeIndex(std::get<0>(position)), + pickupDeletion(std::get<1>(position)), + deliveryDeletion(std::get<2>(position)), pickupLocation(pair.getPickup()), deliveryLocation(pair.getDelivery()), pair(pair) {} + void RemovePair::modifySolution(Solution &solution) { Route &route = solution.getRoute(routeIndex); @@ -93,4 +93,9 @@ std::vector<int> const & RemovePair::getDeletedRequests() const Pair const &RemovePair::getPair() const { return pair; +} + +Index RemovePair::getIndex() const +{ + return std::make_tuple(routeIndex, pickupDeletion, deliveryDeletion); } \ No newline at end of file diff --git a/src/lns/modification/pair/remove_pair.h b/src/lns/modification/pair/remove_pair.h index cb543e7..ef9dbdb 100644 --- a/src/lns/modification/pair/remove_pair.h +++ b/src/lns/modification/pair/remove_pair.h @@ -1,12 +1,12 @@ #pragma once -#include "./../atomic_destruction.h" -#include "./../../solution/solution.h" -#include "./../../../input/location.h" -#include "./../../../input/pair.h" #include <functional> -class Route; +#include "lns/modification/atomic_destruction.h" +#include "lns/solution/solution.h" +#include "input/location.h" +#include "input/pair.h" +#include "types.h" /** * A modification that will remove a pair (pickup/delivery) of location from the solution. @@ -22,6 +22,7 @@ class RemovePair : public AtomicDestruction * Index at which the deletion must be made */ int pickupDeletion; + /** * Index at which the deletion must be made */ @@ -31,6 +32,7 @@ class RemovePair : public AtomicDestruction * The pickup location to remove */ Location const & pickupLocation; + /** * The delivery location to remove */ @@ -45,23 +47,24 @@ class RemovePair : public AtomicDestruction public: - RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion, Location const &pickupLocation, Location const &deliveryLocation); RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion, Pair const &pair); + RemovePair(Index position, Pair const &pair); + ~RemovePair() override = default; void modifySolution(Solution &solution) override; double evaluate(Solution const &solution) const override; + /** + * Return the location ID of location that has been deleted + */ + std::vector<int> const &getDeletedRequests() const override; int getPickupDeletion() const; int getDeliveryDeletion() const; int getRouteIndex() const; Location const &getPickupLocation() const; Location const &getDeliveryLocation() const; - Pair const &getPair() const; + Index getIndex() const; - /** - * Return the location ID of location that has been deleted - */ - std::vector<int> const &getDeletedRequests() const override; }; diff --git a/src/lns/modification/route/insert_route.cpp b/src/lns/modification/route/insert_route.cpp index 5b0b04e..96cf368 100644 --- a/src/lns/modification/route/insert_route.cpp +++ b/src/lns/modification/route/insert_route.cpp @@ -1,12 +1,12 @@ #include "insert_route.h" -InsertRoute::InsertRoute() {} +InsertRoute::InsertRoute() = default; void InsertRoute::modifySolution(Solution &solution) { std::vector<Route> &routes = solution.getRoutes(); - routes.push_back(Route()); + routes.emplace_back(); } double InsertRoute::evaluate(Solution const &solution) const diff --git a/src/lns/modification/route/insert_route.h b/src/lns/modification/route/insert_route.h index 1196526..e5d6413 100644 --- a/src/lns/modification/route/insert_route.h +++ b/src/lns/modification/route/insert_route.h @@ -1,11 +1,8 @@ #pragma once -#include "./../atomic_recreation.h" -#include "./../../solution/solution.h" -#include "./../../../input/location.h" -#include <functional> - -class Route; +#include "lns/modification/atomic_recreation.h" +#include "lns/solution/solution.h" +#include "input/location.h" /** * Insert a new empty route in the solution @@ -20,5 +17,4 @@ public: void modifySolution(Solution &solution) override; double evaluate(Solution const &solution) const override; Location const *getAddedLocation() const override; - }; \ No newline at end of file diff --git a/src/lns/modification/route/remove_route.cpp b/src/lns/modification/route/remove_route.cpp index 8dd22bd..006d5df 100644 --- a/src/lns/modification/route/remove_route.cpp +++ b/src/lns/modification/route/remove_route.cpp @@ -1,9 +1,13 @@ #include "remove_route.h" -#include "../../../input/data.h" + +#include <utility> + RemoveRoute::RemoveRoute() : routeIndex(-1), removedLocationID({}) {} RemoveRoute::RemoveRoute(int routeIndex) : routeIndex(routeIndex), removedLocationID({}) {} -RemoveRoute::RemoveRoute(int routeIndex, std::vector<int> removedLocationID) : routeIndex(routeIndex), removedLocationID(removedLocationID) {} +RemoveRoute::RemoveRoute(int routeIndex, std::vector<int> removedLocationID) : + routeIndex(routeIndex), + removedLocationID(std::move(removedLocationID)) {} void RemoveRoute::modifySolution(Solution &solution) { @@ -27,7 +31,6 @@ int RemoveRoute::getRouteIndex() const return routeIndex; } - std::vector<int> const &RemoveRoute::getDeletedRequests() const { return removedLocationID; diff --git a/src/lns/modification/route/remove_route.h b/src/lns/modification/route/remove_route.h index 83f67c6..be981e8 100644 --- a/src/lns/modification/route/remove_route.h +++ b/src/lns/modification/route/remove_route.h @@ -1,10 +1,11 @@ #pragma once -#include "./../atomic_destruction.h" -#include "./../../solution/solution.h" -#include "./../../../input/location.h" #include <functional> +#include "input/data.h" +#include "input/location.h" +#include "lns/modification/atomic_destruction.h" +#include "lns/solution/solution.h" /** * A modification that will remove a route from the solution. @@ -25,16 +26,15 @@ class RemoveRoute : public AtomicDestruction public: RemoveRoute(); - RemoveRoute(int routeIndex); + explicit RemoveRoute(int routeIndex); RemoveRoute(int routeIndex, std::vector<int> removedLocationID); void modifySolution(Solution &solution) override; double evaluate(Solution const &solution) const override; - - int getRouteIndex() const; - /** - * Return the location ID of location that has been deleted - */ + * Return the location ID of location that has been deleted + */ std::vector<int> const &getDeletedRequests() const override; + + int getRouteIndex() const; }; \ No newline at end of file diff --git a/src/lns/solution/route.h b/src/lns/solution/route.h index 67686cf..aac7992 100644 --- a/src/lns/solution/route.h +++ b/src/lns/solution/route.h @@ -1,7 +1,8 @@ #pragma once #include <vector> -#include "./../../input/time_window.h" + +#include "input/time_window.h" /** * Represent a route for the PDPTW diff --git a/src/lns/solution/solution.cpp b/src/lns/solution/solution.cpp index 03864d8..8c3bf53 100644 --- a/src/lns/solution/solution.cpp +++ b/src/lns/solution/solution.cpp @@ -1,22 +1,91 @@ #include "solution.h" -#include <iostream> -#include <spdlog/spdlog.h> +#include <utility> -Solution::Solution(const PDPTWData &data) - : data(data), totalCost(0) { +#include "input/data.h" +#include "input/time_window.h" +#include "lns/constraints/capacity/capacity_constraint.h" +#include "lns/constraints/time_window/time_window_constraint.h" - bank = RequestBank(); - routes = std::vector<Route>(); +#include "config.h" +#include "lns/solution/route.h" + +void Solution::initPairBank() +{ + pairBank.clear(); + for (const Pair & pair : getData().getPairs()) + { + pairBank.push_back(pair.getID()); + } +} + +void Solution::initRoutes() +{ + routes.clear(); +} + +void Solution::initConstraints() +{ + constraints.clear(); + constraints.push_back(std::make_unique<CapacityConstraint>(*this)); + constraints.push_back(std::make_unique<TimeWindowConstraint>(*this)); } +void Solution::computeAndStoreSolutionCost() +{ + routeCost = computeSolutionCost(); + + // add penalty for solution in the pairBank ? + totalCost = routeCost + computePenalization(); +} -Solution::Solution(const PDPTWData &data, RequestBank bank, std::vector<Route> routes, int totalCost) - : data(data), bank(bank), routes(routes), totalCost(totalCost) {} +double Solution::computeSolutionCost() const +{ + double cost = 0; + for (const Route & route : getRoutes()) + { + cost += data::routeCost(data, route); + } + std::cout << "le cout " << cost << " \n"; + return cost; +} + +double Solution::computePenalization() const +{ + return getBank().size() * EXCLUSION_PENALTY; +} + + +void Solution::init() +{ + initPairBank(); + initRoutes(); + initConstraints(); + computeAndStoreSolutionCost(); +} + + +Solution::Solution(const PDPTWData &data, Solution::PairBank pairbank, std::vector<Route> routes, double routeCost, double totalCost) : + data(data), + pairBank(std::move(pairbank)), + routes(std::move(routes)), + routeCost(routeCost), + totalCost(totalCost) {} + +Solution::Solution(const PDPTWData &data) : data(data) +{ + init(); +} + +Solution Solution::emptySolution(const PDPTWData &data) +{ + Solution s = Solution(data); + return s; +} -const std::vector<int> & Solution::getBank() const +const Solution::PairBank & Solution::getBank() const { - return bank; + return pairBank; } const std::vector<Route> & Solution::getRoutes() const @@ -49,7 +118,7 @@ const Route & Solution::getRoute(int routeIndex) const return routes[routeIndex]; } -int Solution::getCost() +double Solution::getCost() const { return totalCost; } diff --git a/src/lns/solution/solution.h b/src/lns/solution/solution.h index 453a4f8..48bffda 100644 --- a/src/lns/solution/solution.h +++ b/src/lns/solution/solution.h @@ -1,8 +1,19 @@ #pragma once #include <vector> +#include <iostream> +#include <spdlog/spdlog.h> + + +#include "lns/constraints/constraint.h" #include "route.h" -#include "./../../input/pdptw_data.h" +#include "input/pair.h" + +class AtomicModification; +class AtomicRecreation; +class AtomicDestruction; +class TimeWindowConstraint; +class CapacityConstraint; /** * Represent a solution of PDPTW @@ -10,33 +21,71 @@ class Solution { public: - using RequestBank = std::vector<int>; + using PairBank = std::vector<int>; private: PDPTWData const & data; - RequestBank bank; + /* + * Store IDs of a pairs (Pickup & Delivery) that are not assigned yet to a route. + */ + PairBank pairBank; + /* + * Vector of routes representing the solution + */ std::vector<Route> routes; - int totalCost; - - static PDPTWData dummy; + double routeCost; + double totalCost; + std::vector<std::unique_ptr<Constraint>> constraints; public: - Solution(const PDPTWData &data); - Solution(const PDPTWData &data, RequestBank bank, std::vector<Route> routes, int totalCost); - RequestBank const & getBank() const; + /** + * Expected way to construct a solution. + */ + static Solution emptySolution(const PDPTWData &data); + + explicit Solution(const PDPTWData &data); + + /** + * For testing/debugging. + * Use emptySolution(const PDPTWData &data) to create an initial empty solution. + */ + Solution(const PDPTWData &data, Solution::PairBank pairbank, std::vector<Route> routes, double routeCost, double totalCost); + + PairBank const & getBank() const; std::vector<Route> const & getRoutes() const; Route const & getRoute(int routeIndex) const; - const PDPTWData & getData() const; + double getCost() const; // For route modification std::vector<Route> & getRoutes(); Route & getRoute(int routeIndex); + void print() const; - int getCost(); - void print() const; +private : + + /** + * Does the initialisation of the object, called by the constructor + */ + void init(); + + /** + * Init/reset the constraints of the problem + */ + void initConstraints(); + void initRoutes(); + void initPairBank(); + + void computeAndStoreSolutionCost(); + + /** + * Compute the cost of the solution (routes cost) + */ + double computeSolutionCost() const; + + double computePenalization() const; }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 7c736af..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,96 +0,0 @@ - -#include <nlohmann/json.hpp> -#include <vector> -#include <iostream> -#include <string> - -#include <filesystem> -#include <fstream> - -#include <spdlog/spdlog.h> - -#include "input/location.h" -#include "input/time_window.h" -#include "input/json_parser.h" -#include "input/data.h" -#include "lns/constraints/capacity/capacity_constraint.h" -#include "lns/constraints/time_window/time_window_constraint.h" -#include "lns/solution/solution.h" -#include "lns/modification/pair/insert_pair.h" -#include "lns/modification/route/insert_route.h" -#include "lns/modification/pair/remove_pair.h" -#include "lns/modification/route/remove_route.h" - -namespace fs = std::filesystem; -using json = nlohmann::json; - -int main(int argc, char const *argv[]) -{ - //std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/test_inst.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/n5000/bar-n5000-1.json"; - - std::cout << filepath << "\n"; - - PDPTWData data = parsing::parseJson(filepath); - data.checkData(); - - /* - * test - */ - Solution emptySol = Solution(data); - - // SOLUTION 1-6-2-7 (time ; 104) - - Solution::RequestBank bank {3,4,5,8,9,10}; - - std::vector<int> path {1,2,6,7}; - Route route = Route(path, 0); - std::vector<Route> routes; - routes.push_back(route); - - int totalCost = 0; - - Solution sol = Solution(data, bank, routes, totalCost); - - sol.print(); - - - // Couple pickup/delivery - Location r2P = data.getLocations()[1]; - Location r2D = data.getLocations()[6]; - Location r3P = data.getLocations()[2]; - Location r3D = data.getLocations()[7]; - - Pair pair2 = Pair(r2P, r2D); - Pair pair3 = Pair(r3P, r3D); - - // Modification - InsertPair opInsert = InsertPair(0, 2, 2, pair3); - - /* - - CapacityConstraint cap_const = CapacityConstraint(sol); - - - cap_const.initCapacities(); - cap_const.print(); - - std::cout << "Is Valid ? : " << cap_const.checkVariant(opInsert) << "\n"; - - cap_const.applyVariant(opInsert); - - cap_const.print(); - - RemovePair opRemove = RemovePair(0, 2, 3, pair3); - - cap_const.applyVariant(opRemove); - - cap_const.print(); - */ - - - TimeWindowConstraint twconst = TimeWindowConstraint(sol); - return 0; -} diff --git a/src/mains/main.cpp b/src/mains/main.cpp new file mode 100644 index 0000000..67c7b74 --- /dev/null +++ b/src/mains/main.cpp @@ -0,0 +1,123 @@ + +#include <nlohmann/json.hpp> +#include <vector> +#include <iostream> +#include <string> +#include <filesystem> +#include <fstream> +#include <spdlog/spdlog.h> + +#include "input/location.h" +#include "input/time_window.h" +#include "input/json_parser.h" +#include "input/data.h" +#include "lns/constraints/capacity/capacity_constraint.h" +#include "lns/constraints/time_window/time_window_constraint.h" +#include "lns/solution/solution.h" +#include "lns/modification/pair/insert_pair.h" +#include "lns/modification/route/insert_route.h" +#include "lns/modification/pair/remove_pair.h" +#include "lns/modification/route/remove_route.h" + +using json = nlohmann::json; + +int main(int argc, char const *argv[]) +{ + //std::string filepath = "/home/a24jacqb/Documents/Code/pdptw-main/data_in/test_inst.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/n5000/bar-n5000-1.json"; + + std::cout << filepath << "\n"; + + PDPTWData data = parsing::parseJson(filepath); + data.checkData(); + + data.print(); + + std::cout << " \n"; + /* + * test + */ + Solution emptySol = Solution::emptySolution(data); + emptySol.print(); + + + + // // SOLUTION 1-6-2-7 (time ; 104) + + // Solution::PairBank bank {3,4,5,8,9,10}; + + // std::vector<int> path {1,6,2,7}; + // Route route = Route(path, 0); + // std::vector<Route> routes; + // routes.push_back(route); + + // int totalCost = 0; + + // Solution sol = Solution(data, bank, routes, totalCost); + + // sol.print(); + + + // // Couple pickup/delivery + // Location r2P = data.getLocations()[1]; + // Location r2D = data.getLocations()[6]; + // Location r3P = data.getLocations()[2]; + // Location r3D = data.getLocations()[7]; + + // Pair pair2 = Pair(r2P, r2D); + // Pair pair3 = Pair(r3P, r3D); + + + + // /* + + // CapacityConstraint cap_const = CapacityConstraint(sol); + + + // cap_const.initCapacities(); + // cap_const.print(); + + // std::cout << "Is Valid ? : " << cap_const.checkVariant(opInsert) << "\n"; + + // cap_const.applyVariant(opInsert); + + // cap_const.print(); + + // RemovePair opRemove = RemovePair(0, 2, 3, pair3); + + // cap_const.applyVariant(opRemove); + + // cap_const.print(); + // */ + + + // TimeWindowConstraint twconst = TimeWindowConstraint(sol); + + // std::cout << "\n --- : \n"; + + // twconst.print(); + + // twconst.initReachTimes(); + + // twconst.print(); + + // // Modification + // InsertPair opInsert = InsertPair(0, 0, 0, pair3); + + // std::cout << "is valid ? : " << twconst.checkVariant(opInsert) << "\n"; + + // twconst.applyVariant(opInsert); + + // twconst.print(); + // opInsert.modifySolution(sol); + + // RemovePair opRemove = RemovePair(0, 0, 1, pair3); + + // twconst.applyVariant(opRemove); + + // twconst.print(); + + return 0; +} diff --git a/src/mains/main_interface.cpp b/src/mains/main_interface.cpp new file mode 100644 index 0000000..58ad8a7 --- /dev/null +++ b/src/mains/main_interface.cpp @@ -0,0 +1,41 @@ +#include "input/json_parser.h" +#include "input/pdptw_data.h" +#include "main_interface.h" + +#include <fstream> +#include <nlohmann/json.hpp> +#include <spdlog/spdlog.h> + +int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solution &)> function) +{ + + try + { + if (argc <= 1) + { + spdlog::error("No arguments provided. Expected: one command line argument."); + throw std::runtime_error("Error : No arguments provided."); + } + + if (argc > 2) + { + spdlog::error("Too many arguments provided. Expected: one command line argument."); + throw std::runtime_error("Error : Too many arguments arguments provided."); + } + + std::string filepath = argv[1]; + PDPTWData data = parsing::parseJson(filepath); + Solution startingSolution = Solution::emptySolution(data); + + function(data, startingSolution); + + } + catch (const std::exception& e) + { + spdlog::critical("Exception caught : {}", e.what()); + return 1; + } + + spdlog::info("Fin"); + return 0; +} diff --git a/src/mains/main_interface.h b/src/mains/main_interface.h new file mode 100644 index 0000000..5efebfe --- /dev/null +++ b/src/mains/main_interface.h @@ -0,0 +1,8 @@ +#pragma once + +#include "input/pdptw_data.h" +#include "lns/solution/solution.h" + +#include <functional> + +int mainInterface(int argc, char **argv, std::function<void(PDPTWData &, Solution &)> function); diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..00139bf --- /dev/null +++ b/src/types.h @@ -0,0 +1,23 @@ +#pragma once + +#include <iostream> +#include <limits> +#include <tuple> +#include <vector> + +/** + * Represent a pair (pickup/delivery) position in a solution. + * (Route Index, Pickup Position, Delivery Position). + * Used in insertion/deletion modifications. + */ +using Index = std::tuple<int, int, int>; + +/** + * A point in time or a duration. + */ +using TimeInteger = double; +TimeInteger constexpr UNDEF_TIMESTAMP = std::numeric_limits<TimeInteger>::max(); + + +using Matrix = std::vector<std::vector<double>>; + -- GitLab