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
Commits on Source (5)
  • awenjb's avatar
    add Solution Components · 54e16ee5
    awenjb authored
    - add basic solution Checker
    - add random destroy Operator
    - revised some parts of the code
    54e16ee5
  • awenjb's avatar
    Add Sorting Strategy · 3249e1b3
    awenjb authored
    - add shuffle as basic sorting strategy
    - add getter  to Solution
    3249e1b3
  • awenjb's avatar
    Add Basic Operators · 056b4f35
    awenjb authored
    - add enumeration of all Insert position for a pair
    - add shuffle strategy
    056b4f35
  • awenjb's avatar
    Fix some issues · ec1781da
    awenjb authored
    - init the solution with one empty road
    - fix bug while init Data
    - some tests in the main
    ec1781da
  • awenjb's avatar
    Bug fixes · dd723af1
    awenjb authored
    - fix bug in Solution Checker
    - Shuffle and InsertPair operators are working
    dd723af1
Showing
with 230 additions and 103 deletions
BasedOnStyle: LLVM
Language: Cpp
Standard: c++20
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None
AlignOperands: Align
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterStruct: true
AfterControlStatement: Always
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterUnion: true
BeforeCatch: false
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 120
CompactNamespaces: false
ContinuationIndentWidth: 8
EmptyLineBeforeAccessModifier: LogicalBlock
IncludeBlocks: Regroup
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PointerAlignment: Right
ReferenceAlignment: Right
QualifierAlignment: Right
ReflowComments: false
SeparateDefinitionBlocks: Always
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never
......@@ -15,10 +15,6 @@ find_package(CLI11 REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(spdlog REQUIRED)
add_executable(pdptw src/mains/main.cpp
src/mains/main_interface.cpp
src/input/data.cpp
......@@ -37,6 +33,14 @@ add_executable(pdptw src/mains/main.cpp
src/lns/modification/route/insert_route_with_pair.cpp
src/lns/modification/route/insert_route.cpp
src/lns/modification/route/remove_route.cpp
src/output/solution_checker.cpp
src/lns/operators/sorting_strategy.cpp
src/lns/operators/destruction/random_destroy.cpp
src/lns/operators/generators/enumerate.cpp
src/lns/operators/generators/modification_generator.cpp
src/lns/operators/reconstruction/list_heuristic_insertion.hpp
src/lns/operators/selector/operator_selection.cpp
src/utils.cpp
)
target_link_libraries(pdptw PRIVATE CLI11::CLI11 nlohmann_json::nlohmann_json spdlog::spdlog)
......
const int EXCLUSION_PENALTY = 100;
\ No newline at end of file
const int EXCLUSION_PENALTY = 100;
const int RANDOM_SEED = 100;
\ No newline at end of file
......@@ -26,8 +26,12 @@ double data::routeCost(PDPTWData const & data, Route const & route)
const std::vector<int> & routeIDs = route.getRoute();
double cost = 0;
if (routeIDs.empty())
{
return 0;
}
// cost from and to the depot
cost += matrix[0][routeIDs[0]];
cost += matrix[0][routeIDs.at(0)];
//std::cout << "\n route cost : " << matrix[0][routeIDs[0]] << " ";
cost += matrix[routeIDs.back()][0];
......
......@@ -51,6 +51,6 @@ void Location::print() const
{
std::cout << "Location ID: " << id << ", Coordinates: (" << longitude << ", " << latitude << ")\n";
std::cout << "Location Type : " << Location::LocTypeToString(locType) << ", Associated location : " << pairedLocationID << "\n";
std::cout << "Demand : " << demand << "\n";
std::cout << "Demand : " << demand << ", Service Duration :" << serviceDuration << "\n";
timeWindow.print();
}
\ No newline at end of file
......@@ -55,11 +55,23 @@ PDPTWData::PDPTWData(int size, int capacity, Location depot, std::vector<Locatio
if( loc.getLocType() == LocType::PICKUP )
{
// vector indexed from 0 / Location indexed from 1
pairs.emplace_back(loc, locations[loc.getPair()-1], loc.getId());
pairs.emplace_back(loc, this->locations[loc.getPair()-1], loc.getId());
}
}
}
const Pair &PDPTWData::getPair(int id) const
{
for (const Pair &pair : pairs)
{
if (id == pair.getID())
{
return pair;
}
}
spdlog::error("Pair not found for ID {}", id);
throw std::runtime_error("Pair not found");
}
void PDPTWData::print() const
{
......
......@@ -54,6 +54,8 @@ public:
std::vector<Location> const &getLocations() const;
std::vector<Pair> const &getPairs() const;
const Pair &getPair(int id) const;
/**
* 0 return the depot.
* Other numbers return the associated location.
......
......@@ -43,7 +43,6 @@ std::vector<int> const & CapacityConstraint::getRouteCapacities(int routeIndex)
// not ideal
bool CapacityConstraint::checkModif(Pair const &pair, int routeIndex, int PickupPosition, int DeliveryPosition) const
{
std::cout << "\n";
int max_capacity = getSolution().getData().getCapacity();
// guardrail
......@@ -67,9 +66,8 @@ bool CapacityConstraint::checkModif(Pair const &pair, int routeIndex, int Pickup
// not ideal
void CapacityConstraint::applyModif(Pair const &pair, int routeIndex, int PickupPosition, int DeliveryPosition, bool addPair)
{
std::cout << "ok \n";
if (addPair)
{
{
// Insert new values
routeCapacities[routeIndex].insert(routeCapacities[routeIndex].begin()+DeliveryPosition, 0);
if (DeliveryPosition != 0)
......@@ -104,10 +102,12 @@ void CapacityConstraint::applyModif(Pair const &pair, int routeIndex, int Pickup
bool CapacityConstraint::check(InsertPair const &op) const
{
std::cout << " #Capa Check";
return checkModif(op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion());
}
void CapacityConstraint::apply(InsertPair const &op)
{
std::cout << "-> Apply Modification on Capacity \n";
applyModif(op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion(), true);
}
......
......@@ -63,6 +63,7 @@ void TimeWindowConstraint::initReachTimes()
// refait l'ordo sur le nouveau vecteur
bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pair, int routeIndex, int pickupPos, int deliveryPos) const
{
ReachTimeVector const &reachTimes = allRouteReachTimes.at(routeIndex);
// COPY route vector
......@@ -75,22 +76,22 @@ bool TimeWindowConstraint::checkInsertion(const PDPTWData& data, const Pair & pa
route.insert(route.begin() + pickupPos, pair.getPickup().getId());
std::cout << "\n";
for (auto pos : route)
{
std::cout << pos << " ";
}
std::cout << "\n";
// 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";
// std::cout << "\n";
// for (auto pos : newReachTimes)
// {
// std::cout << pos << " ";
// }
// std::cout << "\n";
// Check Time Windows
for (int i = 0; i < newReachTimes.size(); ++i)
......@@ -134,28 +135,15 @@ void TimeWindowConstraint::ApplyModif(const PDPTWData& data, const Pair & pair,
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
{
std::cout << " #TW Check";
return checkInsertion(getSolution().getData(), op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion());
}
void TimeWindowConstraint::apply(InsertPair const &op)
{
std::cout << "-> Apply Modification on Time Windows \n";
ApplyModif(getSolution().getData(), op.getPair(), op.getRouteIndex(), op.getPickupInsertion(), op.getDeliveryInsertion(), true);
}
......
......@@ -15,5 +15,5 @@ public:
/**
* @return the location ID removed from the solution.
*/
virtual std::vector<int> const &getDeletedRequests() const = 0;
virtual std::vector<int> const &getDeletedPairs() const = 0;
};
#pragma once
#include <vector>
#include "lns/constraints/constraint.h"
#include <vector>
class Solution;
/**
......@@ -21,11 +21,15 @@ public:
*/
virtual double evaluate(Solution const &solution) const = 0;
/**
/**
* Apply of the modification to the solution.
* @note does not check the validity of the modification, does not update solution cost nor constraints
*/
virtual void modifySolution(Solution &solution) = 0;
};
/**
* Visitor pattern double dispatch.
* Only need to be implemented with `return *this;`, update ModificationApplyVariant typedef when adding new modification.
*/
virtual ModificationApplyVariant asApplyVariant() const = 0;
};
#pragma once
#include "atomic_modification.h"
#include "input/pair.h"
class Location;
......@@ -13,7 +14,15 @@ public:
~AtomicRecreation() override = default;
/**
* @return the pickup location added to the solution, nullptr if none were added
* Visitor pattern double dispatch.
* Only need to be implemented with `return *this;`
* Update ModificationCheckVariant alias when adding new recreate modification
*/
virtual Location const *getAddedLocation() const = 0;
virtual ModificationCheckVariant asCheckVariant() const = 0;
/**
* @return the pair added to the solution, nullptr if none were added
* (why return pointer and not juste a int ?)
*/
virtual int getAddedPairs() const = 0;
};
\ No newline at end of file
#include "insert_pair.h"
#include "input/data.h"
#include "lns/constraints/constraint.h"
InsertPair::InsertPair(int routeIndex, int pickupInsertion, int deliveryInsertion, Pair const &pair) :
......@@ -57,6 +58,11 @@ double InsertPair::evaluate(Solution const &solution) const {
}
ModificationCheckVariant InsertPair::asCheckVariant() const
{
return *this;
}
int InsertPair::getPickupInsertion() const
{
return pickupInsertion;
......@@ -82,9 +88,9 @@ const Location &InsertPair::getDeliveryLocation() const
return deliveryLocation;
}
const Location *InsertPair::getAddedLocation() const
int InsertPair::getAddedPairs() const
{
return &pickupLocation;
return pair.getID();
}
const Pair &InsertPair::getPair() const
......@@ -95,4 +101,9 @@ const Pair &InsertPair::getPair() const
Index InsertPair::getIndex() const
{
return std::make_tuple(routeIndex, pickupInsertion, deliveryInsertion);
}
ModificationApplyVariant InsertPair::asApplyVariant() const
{
return (*this);
}
\ No newline at end of file
......@@ -51,9 +51,11 @@ public:
~InsertPair() override = default;
ModificationApplyVariant asApplyVariant() const override;
void modifySolution(Solution &solution) override;
double evaluate(Solution const &solution) const override;
Location const *getAddedLocation() const override;
int getAddedPairs() const override;
int getPickupInsertion() const;
int getDeliveryInsertion() const;
......@@ -63,4 +65,5 @@ public:
Pair const &getPair() const;
Index getIndex() const;
ModificationCheckVariant asCheckVariant() const override;
};
\ No newline at end of file
#include "remove_pair.h"
#include "input/data.h"
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) {}
#include "input/data.h"
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) {}
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)
{}
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);
// update removedLocationID
removedLocationID.push_back(route.getRoute()[pickupDeletion]);
removedLocationID.push_back(route.getRoute()[deliveryDeletion]);
// update removedPairID
removedPairID.push_back(route.getRoute()[pickupDeletion]);
// 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();
std::vector<int> const &routeIDs = route.getRoute();
PDPTWData const &data = solution.getData();
int prevPickup = (pickupDeletion == 0) ? 0 : routeIDs[pickupDeletion - 1];
// pickup location should not be at the end of a route anyway
......@@ -47,9 +37,9 @@ double RemovePair::evaluate(Solution const &solution) const
double pickupCost = data::removedCostForSuppression(data, prevPickup, pickupLocation.getId(), nextPickup);
int prevDelivery = (deliveryDeletion == 0) ? 0 : routeIDs[deliveryDeletion - 1];
int prevDelivery = (deliveryDeletion == 0) ? 0 : routeIDs[deliveryDeletion - 1];
int nextDelivery = (deliveryDeletion >= routeIDs.size()) ? 0 : routeIDs[deliveryDeletion + 1];
if (deliveryDeletion == pickupDeletion+1)
if (deliveryDeletion == pickupDeletion + 1)
{
prevDelivery = prevPickup;
}
......@@ -62,7 +52,6 @@ double RemovePair::evaluate(Solution const &solution) const
int RemovePair::getPickupDeletion() const
{
return pickupDeletion;
}
int RemovePair::getDeliveryDeletion() const
......@@ -75,19 +64,19 @@ int RemovePair::getRouteIndex() const
return routeIndex;
}
Location const & RemovePair::getPickupLocation() const
Location const &RemovePair::getPickupLocation() const
{
return pickupLocation;
}
Location const & RemovePair::getDeliveryLocation() const
Location const &RemovePair::getDeliveryLocation() const
{
return deliveryLocation;
}
std::vector<int> const & RemovePair::getDeletedRequests() const
std::vector<int> const &RemovePair::getDeletedPairs() const
{
return removedLocationID;
return removedPairID;
}
Pair const &RemovePair::getPair() const
......@@ -95,7 +84,12 @@ Pair const &RemovePair::getPair() const
return pair;
}
Index RemovePair::getIndex() const
Index RemovePair::getIndex() const
{
return std::make_tuple(routeIndex, pickupDeletion, deliveryDeletion);
}
ModificationApplyVariant RemovePair::asApplyVariant() const
{
return (*this);
}
\ No newline at end of file
......@@ -41,9 +41,9 @@ class RemovePair : public AtomicDestruction
Pair const & pair;
/**
* Removed Location ID (empty before ModifySolution is called)
* Removed PairID (= pickupID) (empty before ModifySolution is called)
*/
std::vector<int> removedLocationID;
std::vector<int> removedPairID;
public:
......@@ -51,12 +51,14 @@ public:
RemovePair(Index position, Pair const &pair);
~RemovePair() override = default;
ModificationApplyVariant asApplyVariant() const override;
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;
std::vector<int> const &getDeletedPairs() const override;
int getPickupDeletion() const;
int getDeliveryDeletion() const;
......
......@@ -14,8 +14,12 @@ double InsertRoute::evaluate(Solution const &solution) const
return 0;
}
Location const *InsertRoute::getAddedLocation() const
int InsertRoute::getAddedPairs() const
{
return nullptr;
return -1;
}
ModificationCheckVariant InsertRoute::asCheckVariant() const
{
return *this;
}
......@@ -16,5 +16,7 @@ public:
void modifySolution(Solution &solution) override;
double evaluate(Solution const &solution) const override;
Location const *getAddedLocation() const override;
int getAddedPairs() const override;
ModificationCheckVariant asCheckVariant() const override;
};
\ No newline at end of file
#include "remove_route.h"
#include "input/location.h"
#include <algorithm>
#include <ranges>
#include <utility>
#include <vector>
RemoveRoute::RemoveRoute() : routeIndex(-1), removedPairID({}) {}
RemoveRoute::RemoveRoute(int routeIndex) : routeIndex(routeIndex), removedPairID({}) {}
RemoveRoute::RemoveRoute() : routeIndex(-1), removedLocationID({}) {}
RemoveRoute::RemoveRoute(int routeIndex) : routeIndex(routeIndex), removedLocationID({}) {}
RemoveRoute::RemoveRoute(int routeIndex, std::vector<int> removedLocationID) :
routeIndex(routeIndex),
removedLocationID(std::move(removedLocationID)) {}
RemoveRoute::RemoveRoute(int routeIndex, std::vector<int> &&removedPairID)
: routeIndex(routeIndex), removedPairID(std::move(removedPairID))
{}
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()));
std::vector<int> const &locationIDs = routes.at(routeIndex).getRoute();
// update removedPairID
removedPairID.reserve(routes.at(routeIndex).getSize());
for (int id : locationIDs)
{
if (solution.getData().getLocation(id).getLocType() == LocType::PICKUP)
{
removedPairID.push_back(id);
}
}
routes.erase(routes.begin() + routeIndex);
}
......@@ -31,7 +43,7 @@ int RemoveRoute::getRouteIndex() const
return routeIndex;
}
std::vector<int> const &RemoveRoute::getDeletedRequests() const
std::vector<int> const &RemoveRoute::getDeletedPairs() const
{
return removedLocationID;
return removedPairID;
}
\ No newline at end of file
......@@ -21,20 +21,20 @@ class RemoveRoute : public AtomicDestruction
/**
* Removed Location ID (empty before ModifySolution is called)
*/
std::vector<int> removedLocationID;
std::vector<int> removedPairID;
public:
RemoveRoute();
explicit RemoveRoute(int routeIndex);
RemoveRoute(int routeIndex, std::vector<int> removedLocationID);
RemoveRoute(int routeIndex, std::vector<int> &&removedPairID);
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;
std::vector<int> const &getDeletedPairs() const override;
int getRouteIndex() const;
};
\ No newline at end of file