25#include "absl/container/btree_set.h"
26#include "absl/strings/str_format.h"
39 return absl::Uniform<int64_t>(absl::BitGen(), 0,
40 std::numeric_limits<int64_t>::max());
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 {
90LocationContainer::Location::Location() : x_(0), y_(0) {}
92LocationContainer::Location::Location(int64_t
x, int64_t
y) : x_(
x), y_(
y) {}
94int64_t LocationContainer::Location::DistanceTo(
95 const Location& location)
const {
96 return Abs(x_ - location.x_) + Abs(y_ - location.y_);
99bool LocationContainer::Location::IsAtSameLocation(
100 const Location& location)
const {
101 return x_ == location.x_ && y_ == location.y_;
104int64_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),
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,
164 const operations_research::RoutingDimension& capacity_dimension,
165 const operations_research::RoutingDimension& time_dimension) {
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;
173 if (plan.
Value(routing.NextVar(order)) == order) {
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;
194 visited.insert(plan.
Value(routing.VehicleVar(order)));
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);
214 if (routing.IsEnd(plan.
Value(routing.NextVar(order)))) {
215 plan_output +=
"Empty\n";
219 capacity_dimension.CumulVar(order);
221 time_dimension.CumulVar(order);
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 +=
" -> ";
238 order = plan.
Value(routing.NextVar(order));
243 LOG(INFO) << plan_output;
int64_t Value(const IntVar *var) const
int64_t Max(const IntVar *var) const
int64_t Min(const IntVar *var) const
bool Contains(const IntVar *var) const
int64_t ObjectiveValue() const
int64_t ManhattanDistance(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
void AddRandomLocation(int64_t x_max, int64_t y_max)
int64_t ManhattanTime(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
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 NegManhattanDistance(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
int64_t SameLocationFromIndex(int64_t node1, int64_t node2) const
int64_t Demand(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
RandomDemand(int size, RoutingIndexManager::NodeIndex depot, bool use_deterministic_seed)
RoutingNodeIndex NodeIndex
NodeIndex IndexToNode(int64_t index) 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)
int64_t Compute(RoutingIndexManager::NodeIndex from, RoutingIndexManager::NodeIndex to) const
In SWIG mode, we don't want anything besides these top-level includes.
int32_t GetSeed(bool deterministic)
Random seed generator.
std::function< int64_t(RoutingNodeIndex, RoutingNodeIndex)> RoutingNodeEvaluator2
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)
trees with all degrees equal to