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
Select Git revision

Target

Select target project
  • a24jacqb/pdptw-main
1 result
Select Git revision
Show changes
Showing
with 573 additions and 11 deletions
#include "insert_pair.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) {}
void InsertPair::modifySolution(Solution &solution)
{
Route &route = solution.getRoute(routeIndex);
route.insertAt(pickupLocation.getId(), pickupInsertion);
// + 1 because the pickup location was inserted earlier in the route
route.insertAt(deliveryLocation.getId(), deliveryInsertion+1);
}
double InsertPair::evaluate(Solution const &solution) const {
Route const &route = solution.getRoute(routeIndex);
const std::vector<int> & routeIDs = route.getRoute();
const PDPTWData &data = solution.getData();
int prevPickup = (pickupInsertion == 0) ? 0 : routeIDs[pickupInsertion - 1];
int nextPickup = (pickupInsertion >= routeIDs.size()) ? 0 : routeIDs[pickupInsertion];
double pickupCost = data::addedCostForInsertion(data, prevPickup, pickupLocation.getId(), nextPickup);
// if pickupInsertion == deliveryInsertion+1, then prevDelivery = pickupLocation.getId()
// the insertion of the delivery is done just after the pickup without intermediate location
// otherwise, the pickup and the delivery insertion are independant and the pickup insertion does not affect the delivery insertion cost
int prevDelivery = (deliveryInsertion == 0) ? 0 : routeIDs[deliveryInsertion - 1];
if (pickupInsertion == deliveryInsertion)
{
prevDelivery = pickupLocation.getId();
}
int nextDelivery = (deliveryInsertion >= routeIDs.size()) ? 0 : routeIDs[deliveryInsertion];
//std::cout << "insert " << prevDelivery << " + " << deliveryLocation.getId() << " + " << nextDelivery << "\n";
double deliveryCost = data::addedCostForInsertion(data, prevDelivery, deliveryLocation.getId(), nextDelivery);
//std::cout << "insert " << pickupCost << " + " << deliveryCost << "\n";
return pickupCost + deliveryCost;
}
int InsertPair::getPickupInsertion() const
{
return pickupInsertion;
}
int InsertPair::getDeliveryInsertion() const
{
return deliveryInsertion;
}
int InsertPair::getRouteIndex() const
{
return routeIndex;
}
Location const &InsertPair::getPickupLocation() const
{
return pickupLocation;
}
const Location &InsertPair::getDeliveryLocation() const
{
return deliveryLocation;
}
const Location *InsertPair::getAddedLocation() const
{
return &pickupLocation;
}
const Pair &InsertPair::getPair() const
{
return pair;
}
#pragma once
#include "./../atomic_recreation.h"
#include "./../../solution/solution.h"
#include "./../../../input/location.h"
#include "./../../../input/pair.h"
#include <functional>
class Route;
/**
* A modification that will insert a pair (pickup/delivery) of location in a route at the given index.
* First index for the pickup location and second index for the delivery location.
* Insertion index are the index before modification !
*/
class InsertPair : public AtomicRecreation
{
/**
* The route index on which the insertion will be made
*/
int routeIndex;
/**
* Index at which the insertion must be made
*/
int pickupInsertion;
/**
* Index at which the insertion must be made
*/
int deliveryInsertion;
/**
* The pickup location to insert
*/
Location const & pickupLocation;
/**
* The delivery location to insert
*/
Location const & deliveryLocation;
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);
void modifySolution(Solution &solution) override;
double evaluate(Solution const &solution) const override;
int getPickupInsertion() const;
int getDeliveryInsertion() const;
int getRouteIndex() const;
Location const &getPickupLocation() const;
Location const &getDeliveryLocation() const;
Pair const &getPair() const;
Location const *getAddedLocation() const override;
};
\ No newline at end of file
#include "remove_pair.h"
#include "../../../input/data.h"
RemovePair::RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion,
Location const &pickupLocation, Location const &deliveryLocation) :
routeIndex(routeIndex),
pickupDeletion(pickupDeletion),
deliveryDeletion(deliveryDeletion),
pickupLocation(pickupLocation),
deliveryLocation(deliveryLocation),
pair(Pair(pickupLocation, deliveryLocation)) {}
RemovePair::RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion,
Pair const &pair) :
routeIndex(routeIndex),
pickupDeletion(pickupDeletion),
deliveryDeletion(deliveryDeletion),
pickupLocation(pair.getPickup()),
deliveryLocation(pair.getDelivery()),
pair(pair) {}
void RemovePair::modifySolution(Solution &solution)
{
Route &route = solution.getRoute(routeIndex);
// update removedLocationID
removedLocationID.push_back(route.getRoute()[pickupDeletion]);
removedLocationID.push_back(route.getRoute()[deliveryDeletion]);
// remove the delivery before (to not have to update the index)
route.deleteAt(deliveryDeletion);
route.deleteAt(pickupDeletion);
}
double RemovePair::evaluate(Solution const &solution) const
{
Route const &route = solution.getRoute(routeIndex);
const std::vector<int> & routeIDs = route.getRoute();
const PDPTWData &data = solution.getData();
int prevPickup = (pickupDeletion == 0) ? 0 : routeIDs[pickupDeletion - 1];
// pickup location should not be at the end of a route anyway
int nextPickup = (pickupDeletion >= routeIDs.size()) ? 0 : routeIDs[pickupDeletion + 1];
double pickupCost = data::removedCostForSuppression(data, prevPickup, pickupLocation.getId(), nextPickup);
int prevDelivery = (deliveryDeletion == 0) ? 0 : routeIDs[deliveryDeletion - 1];
int nextDelivery = (deliveryDeletion >= routeIDs.size()) ? 0 : routeIDs[deliveryDeletion + 1];
if (deliveryDeletion == pickupDeletion+1)
{
prevDelivery = prevPickup;
}
double deliveryCost = data::removedCostForSuppression(data, prevDelivery, deliveryLocation.getId(), nextDelivery);
return pickupCost + deliveryCost;
}
int RemovePair::getPickupDeletion() const
{
return pickupDeletion;
}
int RemovePair::getDeliveryDeletion() const
{
return deliveryDeletion;
}
int RemovePair::getRouteIndex() const
{
return routeIndex;
}
Location const & RemovePair::getPickupLocation() const
{
return pickupLocation;
}
Location const & RemovePair::getDeliveryLocation() const
{
return deliveryLocation;
}
std::vector<int> const & RemovePair::getDeletedRequests() const
{
return removedLocationID;
}
Pair const &RemovePair::getPair() const
{
return pair;
}
\ No newline at end of file
#pragma once
#include "./../atomic_destruction.h"
#include "./../../solution/solution.h"
#include "./../../../input/location.h"
#include "./../../../input/pair.h"
#include <functional>
class Route;
/**
* A modification that will remove a pair (pickup/delivery) of location from the solution.
*/
class RemovePair : public AtomicDestruction
{
/**
* The route index on which the deletion will be made
*/
int routeIndex;
/**
* Index at which the deletion must be made
*/
int pickupDeletion;
/**
* Index at which the deletion must be made
*/
int deliveryDeletion;
/**
* The pickup location to remove
*/
Location const & pickupLocation;
/**
* The delivery location to remove
*/
Location const & deliveryLocation;
Pair const & pair;
/**
* Removed Location ID (empty before ModifySolution is called)
*/
std::vector<int> removedLocationID;
public:
RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion, Location const &pickupLocation, Location const &deliveryLocation);
RemovePair(int routeIndex, int pickupDeletion, int deliveryDeletion, Pair const &pair);
void modifySolution(Solution &solution) override;
double evaluate(Solution const &solution) const override;
int getPickupDeletion() const;
int getDeliveryDeletion() const;
int getRouteIndex() const;
Location const &getPickupLocation() const;
Location const &getDeliveryLocation() const;
Pair const &getPair() const;
/**
* Return the location ID of location that has been deleted
*/
std::vector<int> const &getDeletedRequests() const override;
};
#include "insert_route.h"
InsertRoute::InsertRoute() {}
void InsertRoute::modifySolution(Solution &solution)
{
std::vector<Route> &routes = solution.getRoutes();
routes.push_back(Route());
}
double InsertRoute::evaluate(Solution const &solution) const
{
return 0;
}
Location const *InsertRoute::getAddedLocation() const
{
return nullptr;
}
#pragma once
#include "./../atomic_recreation.h"
#include "./../../solution/solution.h"
#include "./../../../input/location.h"
#include <functional>
class Route;
/**
* Insert a new empty route in the solution
* Do not cost anything
*/
class InsertRoute : public AtomicRecreation
{
public:
InsertRoute();
void modifySolution(Solution &solution) override;
double evaluate(Solution const &solution) const override;
Location const *getAddedLocation() const override;
};
\ No newline at end of file
// TO DO
\ No newline at end of file
// Insertion d'une route avec une ou plusieurs paires pickup / delivery
// TO DO
\ No newline at end of file
#include "remove_route.h"
#include "../../../input/data.h"
RemoveRoute::RemoveRoute() : routeIndex(-1), removedLocationID({}) {}
RemoveRoute::RemoveRoute(int routeIndex) : routeIndex(routeIndex), removedLocationID({}) {}
RemoveRoute::RemoveRoute(int routeIndex, std::vector<int> removedLocationID) : routeIndex(routeIndex), removedLocationID(removedLocationID) {}
void RemoveRoute::modifySolution(Solution &solution)
{
std::vector<Route> &routes = solution.getRoutes();
// update removedLocationID
removedLocationID.insert(removedLocationID.end(),
std::make_move_iterator(routes[routeIndex].getRoute().begin()),
std::make_move_iterator(routes[routeIndex].getRoute().end()));
routes.erase(routes.begin() + routeIndex);
}
double RemoveRoute::evaluate(Solution const &solution) const
{
return data::routeCost(solution.getData(), solution.getRoute(routeIndex));
}
int RemoveRoute::getRouteIndex() const
{
return routeIndex;
}
std::vector<int> const &RemoveRoute::getDeletedRequests() const
{
return removedLocationID;
}
\ No newline at end of file
#pragma once
#include "./../atomic_destruction.h"
#include "./../../solution/solution.h"
#include "./../../../input/location.h"
#include <functional>
/**
* A modification that will remove a route from the solution.
*/
class RemoveRoute : public AtomicDestruction
{
/**
* Index of the route to remove
*/
int routeIndex;
/**
* Removed Location ID (empty before ModifySolution is called)
*/
std::vector<int> removedLocationID;
public:
RemoveRoute();
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
*/
std::vector<int> const &getDeletedRequests() const override;
};
\ No newline at end of file
#include "route.h"
#include <iostream>
#include <spdlog/spdlog.h>
Route::Route() = default;
Route::Route(std::vector<int> route, int cost) : route(route), cost(cost) {}
......@@ -21,4 +23,40 @@ void Route::print() const
std::cout << id << ", ";
}
std::cout << "\n";
}
void Route::insertAt(int locationIndex, int position)
{
if (position < 0 || position > route.size()) {
spdlog::error("Invalid position for the insertion : {}", position);
throw std::out_of_range("Invalid position for the insertion.");
}
route.insert(route.begin() + position, locationIndex);
}
void Route::deleteAt(int position) {
// Vérification si la position est valide
if (position < 0 || position >= route.size()) {
spdlog::error("Invalid position for the suppression : {}", position);
throw std::out_of_range("Invalid position for the suppression");
}
route.erase(route.begin() + position);
}
int Route::getLocation(int index) const
{
// Vérification si la position est valide
if (index < 0 || index >= route.size()) {
spdlog::error("Invalid index when reading route: {}", index);
throw std::out_of_range("Invalid index when reading route");
}
return route[index];
}
int Route::getSize() const
{
return route.size();
}
\ No newline at end of file
......@@ -5,13 +5,15 @@
/**
* Represent a route for the PDPTW
* A route does not include the depot at the begining and the end !
*/
class Route
{
private:
int cost;
std::vector<int> route;
int cost;
/* Stocké dans les contraintes
......@@ -22,9 +24,25 @@ private:
public:
Route();
Route(std::vector<int> route, int cost);
int getCost() const;
const std::vector<int>& getRoute() const;
const std::vector<int> & getRoute() const;
// get Location
int getLocation(int index) const;
void print() const;
/*
* Add a location index in the route (does not update the route cost)
*/
void insertAt(int locationIndex, int position);
/*
* Remove the element at "position"
*/
void deleteAt(int position);
int getSize() const;
};
\ No newline at end of file
#include "solution.h"
#include <iostream>
#include <spdlog/spdlog.h>
Solution::Solution(RequestBank bank, std::vector<Route> routes, int totalCost)
: bank(bank), routes(routes), totalCost(totalCost) {}
Solution::Solution(const PDPTWData &data)
: data(data), totalCost(0) {
bank = RequestBank();
routes = std::vector<Route>();
}
Solution::Solution(const PDPTWData &data, RequestBank bank, std::vector<Route> routes, int totalCost)
: data(data), bank(bank), routes(routes), totalCost(totalCost) {}
const std::vector<int> & Solution::getBank() const
{
return bank;
}
const std::vector<Route> & Solution::getRoute() const
const std::vector<Route> & Solution::getRoutes() const
{
return routes;
}
std::vector<Route> & Solution::getRoutes()
{
return routes;
}
Route & Solution::getRoute(int routeIndex)
{
if (routeIndex < 0 || routeIndex >= routes.size())
{
spdlog::error("Invalid route index: {}", routeIndex);
throw std::out_of_range("Invalid route index.");
}
return routes[routeIndex];
}
const Route & Solution::getRoute(int routeIndex) const
{
if (routeIndex < 0 || routeIndex >= routes.size())
{
spdlog::error("Invalid route index: {}", routeIndex);
throw std::out_of_range("Invalid route index.");
}
return routes[routeIndex];
}
int Solution::getCost()
{
return totalCost;
}
const PDPTWData & Solution::getData() const
{
return data;
}
void Solution::print() const
{
std::cout << "Cost :" << totalCost << "\n";
for (const Route& id : getRoute())
std::cout << "Cost :" << totalCost << "\n" << "Routes : \n";
for (const Route& id : getRoutes())
{
id.print();
}
std::cout << "Banques : \n";
for (const int id : getBank())
{
std::cout << id << ", ";
}
std::cout << "\n";
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
#include <vector>
#include "route.h"
#include "./../../input/pdptw_data.h"
/**
* Represent a solution of PDPTW
......@@ -12,14 +13,29 @@ public:
using RequestBank = std::vector<int>;
private:
PDPTWData const & data;
RequestBank bank;
std::vector<Route> routes;
int totalCost;
static PDPTWData dummy;
public:
Solution(RequestBank bank, std::vector<Route> routes, int totalCost);
const RequestBank & getBank() const;
const std::vector<Route> & getRoute() const;
Solution(const PDPTWData &data);
Solution(const PDPTWData &data, RequestBank bank, std::vector<Route> routes, int totalCost);
RequestBank const & getBank() const;
std::vector<Route> const & getRoutes() const;
Route const & getRoute(int routeIndex) const;
const PDPTWData & getData() const;
// For route modification
std::vector<Route> & getRoutes();
Route & getRoute(int routeIndex);
int getCost();
void print() const;
......