33 #include "absl/random/random.h"
34 #include "absl/strings/str_cat.h"
35 #include "google/protobuf/text_format.h"
41 #include "ortools/constraint_solver/routing_enums.pb.h"
44 #include "ortools/constraint_solver/routing_parameters.pb.h"
49 using operations_research::FirstSolutionStrategy;
57 using operations_research::RoutingNodeIndex;
58 using operations_research::RoutingSearchParameters;
62 ABSL_FLAG(
int, vrp_orders, 100,
"Nodes in the problem.");
64 "Size of Traveling Salesman Problem instance.");
65 ABSL_FLAG(
bool, vrp_use_deterministic_random_seed,
false,
66 "Use deterministic random seeds.");
67 ABSL_FLAG(std::string, routing_search_parameters,
"",
68 "Text proto RoutingSearchParameters (possibly partial) that will "
69 "override the DefaultRoutingSearchParameters()");
74 int main(
int argc,
char** argv) {
76 CHECK_LT(0, absl::GetFlag(FLAGS_vrp_orders))
77 <<
"Specify an instance size greater than 0.";
78 CHECK_LT(0, absl::GetFlag(FLAGS_vrp_vehicles))
79 <<
"Specify a non-null vehicle fleet size.";
85 absl::GetFlag(FLAGS_vrp_vehicles), kDepot);
88 CHECK(google::protobuf::TextFormat::MergeFromString(
89 absl::GetFlag(FLAGS_routing_search_parameters), &
parameters));
91 FirstSolutionStrategy::PARALLEL_CHEAPEST_INSERTION);
94 const int64_t kXMax = 100000;
95 const int64_t kYMax = 100000;
96 const int64_t kSpeed = 10;
98 kSpeed, absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed));
99 for (
int location = 0; location <= absl::GetFlag(FLAGS_vrp_orders);
106 [&locations, &manager](int64_t i, int64_t j) {
113 const int64_t kVehicleCapacity = 40;
114 const int64_t kNullCapacitySlack = 0;
116 absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed));
119 [&
demand, &manager](int64_t i, int64_t j) {
120 return demand.Demand(manager.IndexToNode(i),
121 manager.IndexToNode(j));
123 kNullCapacitySlack, kVehicleCapacity,
127 const int64_t kTimePerDemandUnit = 300;
128 const int64_t kHorizon = 24 * 3600;
131 [&
demand](RoutingNodeIndex i, RoutingNodeIndex j) {
132 return demand.Demand(i, j);
134 [&locations](RoutingNodeIndex i, RoutingNodeIndex j) {
139 return time.Compute(manager.IndexToNode(i), manager.IndexToNode(j));
141 kHorizon, kHorizon,
false,
kTime);
145 std::mt19937 randomizer(
146 GetSeed(absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed)));
147 const int64_t kTWDuration = 5 * 3600;
148 for (
int order = 1; order < manager.
num_nodes(); ++order) {
149 const int64_t
start =
150 absl::Uniform<int32_t>(randomizer, 0, kHorizon - kTWDuration);
156 for (
int i = 0; i < routing.
Size(); ++i) {
159 for (
int j = 0; j < absl::GetFlag(FLAGS_vrp_vehicles); ++j) {
171 std::vector<int64_t> service_times(routing.
Size());
172 for (
int node = 0; node < routing.
Size(); node++) {
173 if (node >= routing.
nodes()) {
174 service_times[node] = 0;
180 const std::vector<std::vector<int>> break_data = {
185 for (
int vehicle = 0; vehicle < absl::GetFlag(FLAGS_vrp_vehicles);
187 std::vector<IntervalVar*> breaks;
188 for (
int i = 0; i < break_data.size(); ++i) {
190 break_data[i][0] * 3600, break_data[i][1] * 3600, break_data[i][2],
191 true, absl::StrCat(
"Break ", i,
" on vehicle ", vehicle));
192 breaks.push_back(break_interval);
196 breaks[2]->PerformedExpr()));
199 breaks[2], Solver::STARTS_AFTER_END, breaks[1], 3600));
202 breaks[2]->PerformedExpr()));
209 const int64_t kPenalty = 10000000;
212 order < routing.
nodes(); ++order) {
213 std::vector<int64_t> orders(1, manager.
NodeToIndex(order));
219 if (solution !=
nullptr) {
220 LOG(INFO) <<
"Breaks: ";
221 for (
const auto& break_interval :
223 if (break_interval.PerformedValue() == 1) {
224 LOG(INFO) << break_interval.Var()->
name() <<
" "
225 << break_interval.DebugString();
227 LOG(INFO) << break_interval.Var()->name() <<
" unperformed";
230 DisplayPlan(manager, routing, *solution,
false, 0, 0,
234 LOG(INFO) <<
"No solution found.";
const std::vector< E > & elements() const
An Assignment is a variable -> domains mapping, used to report solutions to the user.
const IntervalContainer & IntervalVarContainer() const
virtual void SetRange(int64_t l, int64_t u)
This method sets both the min and the max of the expression.
Interval variables are often used in scheduling.
int64_t ManhattanTime(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
void AddRandomLocation(int64_t x_max, int64_t y_max)
int64_t ManhattanDistance(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
virtual std::string name() const
Object naming.
Dimensions represent quantities accumulated at nodes along the routes.
IntVar * SlackVar(int64_t index) const
IntVar * CumulVar(int64_t index) const
Get the cumul, transit and slack variables for the given node (given as int64_t var index).
void SetBreakIntervalsOfVehicle(std::vector< IntervalVar * > breaks, int vehicle, int pre_travel_evaluator, int post_travel_evaluator)
Sets the breaks for a given vehicle.
Manager for any NodeIndex <-> variable index conversion.
NodeIndex IndexToNode(int64_t index) const
int64_t NodeToIndex(NodeIndex node) const
int nodes() const
Sizes and indices Returns the number of nodes in the model.
void AddToAssignment(IntVar *const var)
Adds an extra variable to the vehicle routing assignment.
void AddVariableMinimizedByFinalizer(IntVar *var)
Adds a variable to minimize in the solution finalizer.
int64_t Size() const
Returns the number of next variables in the model.
RoutingDimension * GetMutableDimension(const std::string &dimension_name) const
Returns a dimension from its name.
Solver * solver() const
Returns the underlying constraint solver.
DisjunctionIndex AddDisjunction(const std::vector< int64_t > &indices, int64_t penalty=kNoPenalty, int64_t max_cardinality=1)
Adds a disjunction constraint on the indices: exactly 'max_cardinality' of the indices are active.
const Assignment * SolveWithParameters(const RoutingSearchParameters &search_parameters, std::vector< const Assignment * > *solutions=nullptr)
Solves the current routing model with the given parameters.
int RegisterTransitCallback(TransitCallback2 callback)
int64_t Start(int vehicle) const
Model inspection.
void SetArcCostEvaluatorOfAllVehicles(int evaluator_index)
Sets the cost function of the model such that the cost of a segment of a route between node 'from' an...
int64_t End(int vehicle) const
Returns the variable index of the ending node of a vehicle route.
bool AddDimension(int evaluator_index, int64_t slack_max, int64_t capacity, bool fix_start_cumul_to_zero, const std::string &name)
Model creation.
const RoutingDimension & GetDimensionOrDie(const std::string &dimension_name) const
Returns a dimension from its name. Dies if the dimension does not exist.
IntervalVar * MakeFixedDurationIntervalVar(int64_t start_min, int64_t start_max, int64_t duration, bool optional, const std::string &name)
Creates an interval var with a fixed duration.
Constraint * MakeEquality(IntExpr *const left, IntExpr *const right)
left == right
Constraint * MakeIntervalVarRelationWithDelay(IntervalVar *const t1, BinaryIntervalRelation r, IntervalVar *const t2, int64_t delay)
This method creates a relation between two interval vars.
void AddConstraint(Constraint *const c)
Adds the constraint 'c' to the model.
Constraint * MakeNonEquality(IntExpr *const left, IntExpr *const right)
left != right
int main(int argc, char **argv)
ABSL_FLAG(int, vrp_orders, 100, "Nodes in the problem.")
void InitGoogle(const char *usage, int *argc, char ***argv, bool deprecated)
void DisplayPlan(const RoutingIndexManager &manager, const RoutingModel &routing, const operations_research::Assignment &plan, bool use_same_vehicle_costs, int64_t max_nodes_per_group, int64_t same_vehicle_cost, const operations_research::RoutingDimension &capacity_dimension, const operations_research::RoutingDimension &time_dimension)
int32_t GetSeed(bool deterministic)
RoutingSearchParameters DefaultRoutingSearchParameters()