25 #include "absl/container/btree_set.h"
26 #include "absl/strings/str_format.h"
39 return absl::Uniform<int64_t>(absl::BitGen(), 0,
45 : randomizer_(
GetSeed(use_deterministic_seed)), speed_(speed) {
55 const int64_t x = absl::Uniform(randomizer_, 0, x_max + 1);
56 const int64_t y = absl::Uniform(randomizer_, 0, y_max + 1);
57 for (
int i = 0; i < duplicates; ++i) {
64 return locations_[from].DistanceTo(locations_[to]);
77 if (node1 < locations_.
size() && node2 < locations_.
size()) {
78 return locations_[node1].IsAtSameLocation(locations_[node2]);
83 int64_t node2)
const {
90 LocationContainer::Location::Location() : x_(0), y_(0) {}
92 LocationContainer::Location::Location(int64_t x, int64_t y) : x_(x), y_(y) {}
94 int64_t LocationContainer::Location::DistanceTo(
95 const Location& location)
const {
96 return Abs(x_ - location.x_) + Abs(y_ - location.y_);
99 bool LocationContainer::Location::IsAtSameLocation(
100 const Location& location)
const {
101 return x_ == location.x_ && y_ == location.y_;
104 int64_t LocationContainer::Location::Abs(int64_t
value) {
109 bool use_deterministic_seed)
112 use_deterministic_seed_(use_deterministic_seed) {
117 const int64_t kDemandMax = 5;
118 const int64_t kDemandMin = 1;
119 demand_ = std::make_unique<int64_t[]>(size_);
120 std::mt19937 randomizer(
GetSeed(use_deterministic_seed_));
121 for (
int order = 0; order < size_; ++order) {
122 if (order == depot_) {
125 demand_[order] = kDemandMin + absl::Uniform(randomizer, 0,
126 kDemandMax - kDemandMin + 1);
132 return demand_[from.value()];
138 : time_per_demand_unit_(time_per_demand_unit),
139 demand_(std::move(
demand)),
140 transition_time_(std::move(transition_time)) {}
143 return time_per_demand_unit_ * demand_(from, to) + transition_time_(from, to);
149 : stop_time_(stop_time),
150 location_container_(location_container),
151 transition_time_(std::move(transition_time)) {}
157 : stop_time_ + transition_time_(from, to);
163 int64_t max_nodes_per_group, int64_t same_vehicle_cost,
167 std::string plan_output = absl::StrFormat(
"Cost %d\n", plan.
ObjectiveValue());
171 for (int64_t order = 0; order < routing.
Size(); ++order) {
172 if (routing.
IsStart(order) || routing.
IsEnd(order))
continue;
174 if (dropped.empty()) {
175 absl::StrAppendFormat(&dropped,
" %d",
178 absl::StrAppendFormat(&dropped,
", %d",
183 if (!dropped.empty()) {
184 plan_output +=
"Dropped orders:" + dropped +
"\n";
187 if (use_same_vehicle_costs) {
189 int64_t group_same_vehicle_cost = 0;
190 absl::btree_set<int> visited;
191 for (int64_t order = 0; order < routing.
Size(); ++order) {
192 if (routing.
IsStart(order) || routing.
IsEnd(order))
continue;
195 if (group_size == max_nodes_per_group) {
196 if (visited.size() > 1) {
197 group_same_vehicle_cost += (visited.size() - 1) * same_vehicle_cost;
203 if (visited.size() > 1) {
204 group_same_vehicle_cost += (visited.size() - 1) * same_vehicle_cost;
206 LOG(INFO) <<
"Same vehicle costs: " << group_same_vehicle_cost;
210 for (
int route_number = 0; route_number < routing.
vehicles();
212 int64_t order = routing.
Start(route_number);
213 absl::StrAppendFormat(&plan_output,
"Route %d: ", route_number);
215 plan_output +=
"Empty\n";
223 routing.
IsEnd(order) ? nullptr : time_dimension.
SlackVar(order);
224 if (slack_var !=
nullptr && plan.
Contains(slack_var)) {
225 absl::StrAppendFormat(
226 &plan_output,
"%d Load(%d) Time(%d, %d) Slack(%d, %d)",
228 plan.
Min(time_var), plan.
Max(time_var), plan.
Min(slack_var),
229 plan.
Max(slack_var));
231 absl::StrAppendFormat(&plan_output,
"%d Load(%d) Time(%d, %d)",
233 plan.
Value(load_var), plan.
Min(time_var),
236 if (routing.
IsEnd(order))
break;
237 plan_output +=
" -> ";
243 LOG(INFO) << plan_output;
An Assignment is a variable -> domains mapping, used to report solutions to the user.
bool Contains(const IntVar *const var) const
int64_t ObjectiveValue() const
int64_t Max(const IntVar *const var) const
int64_t Value(const IntVar *const var) const
int64_t Min(const IntVar *const var) const
The class IntVar is a subset of IntExpr.
bool SameLocation(RoutingIndexManager::NodeIndex node1, RoutingIndexManager::NodeIndex node2) const
void AddLocation(int64_t x, int64_t y)
LocationContainer(int64_t speed, bool use_deterministic_seed)
int64_t ManhattanTime(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
int64_t SameLocationFromIndex(int64_t node1, int64_t node2) const
void AddRandomLocation(int64_t x_max, int64_t y_max)
int64_t NegManhattanDistance(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
int64_t ManhattanDistance(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
int64_t Demand(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
RandomDemand(int size, RoutingIndexManager::NodeIndex depot, bool use_deterministic_seed)
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).
Manager for any NodeIndex <-> variable index conversion.
NodeIndex IndexToNode(int64_t index) const
RoutingNodeIndex NodeIndex
bool IsStart(int64_t index) const
Returns true if 'index' represents the first node of a route.
IntVar * NextVar(int64_t index) const
!defined(SWIGPYTHON)
IntVar * VehicleVar(int64_t index) const
Returns the vehicle variable of the node corresponding to index.
int64_t Size() const
Returns the number of next variables in the model.
int64_t Start(int vehicle) const
Model inspection.
int vehicles() const
Returns the number of vehicle routes in the model.
bool IsEnd(int64_t index) const
Returns true if 'index' represents the last node of a route.
int64_t Compute(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
ServiceTimePlusTransition(int64_t time_per_demand_unit, operations_research::RoutingNodeEvaluator2 demand, operations_research::RoutingNodeEvaluator2 transition_time)
int64_t Compute(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
StopServiceTimePlusTransition(int64_t stop_time, const LocationContainer &location_container, operations_research::RoutingNodeEvaluator2 transition_time)
Collection of objects used to extend the Constraint Solver library.
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)
std::function< int64_t(RoutingNodeIndex, RoutingNodeIndex)> RoutingNodeEvaluator2