14#ifndef ORTOOLS_CONSTRAINT_SOLVER_ROUTING_LP_SCHEDULING_H_
15#define ORTOOLS_CONSTRAINT_SOLVER_ROUTING_LP_SCHEDULING_H_
28#include "absl/container/flat_hash_map.h"
29#include "absl/container/flat_hash_set.h"
30#include "absl/log/check.h"
31#include "absl/strings/str_format.h"
32#include "absl/strings/string_view.h"
33#include "absl/time/time.h"
34#include "absl/types/span.h"
69 const std::function<int64_t(int64_t)>& next_accessor,
71 const std::vector<RoutingModel::RouteDimensionTravelInfo>*
72 dimension_travel_info_per_route =
nullptr);
75 return propagated_bounds_[PositiveNode(index)];
79 const int64_t negated_upper_bound = propagated_bounds_[NegativeNode(index)];
80 return negated_upper_bound == std::numeric_limits<int64_t>::min()
81 ? std::numeric_limits<int64_t>::max()
82 : -negated_upper_bound;
95 static const int kNoParent;
96 static const int kParentToBePropagated;
100 int PositiveNode(
int index)
const {
return 2 * index; }
101 int NegativeNode(
int index)
const {
return 2 * index + 1; }
103 void AddNodeToQueue(
int node) {
104 if (!node_in_queue_[node]) {
105 bf_queue_.push_back(node);
106 node_in_queue_[node] =
true;
113 void AddArcs(
int first_index,
int second_index, int64_t offset);
115 bool InitializeArcsAndBounds(
116 const std::function<int64_t(int64_t)>& next_accessor,
117 int64_t cumul_offset,
118 const std::vector<RoutingModel::RouteDimensionTravelInfo>*
119 dimension_travel_info_per_route =
nullptr);
121 bool UpdateCurrentLowerBoundOfNode(
int node, int64_t new_lb, int64_t offset);
123 bool DisassembleSubtree(
int source,
int target);
125 bool CleanupAndReturnFalse() {
127 for (
int node_to_cleanup : bf_queue_) {
128 node_in_queue_[node_to_cleanup] =
false;
134 const RoutingDimension& dimension_;
135 const int64_t num_nodes_;
140 std::vector<std::vector<ArcInfo>> outgoing_arcs_;
142 std::deque<int> bf_queue_;
143 std::vector<bool> node_in_queue_;
144 std::vector<int> tree_parent_node_of_;
148 std::vector<int64_t> propagated_bounds_;
151 std::vector<int> tmp_dfs_stack_;
154 std::vector<std::pair<int64_t, int64_t>>
155 visited_pickup_delivery_indices_for_pair_;
181 int64_t upper_bound) = 0;
183 const std::vector<int64_t>& starts,
184 const std::vector<int64_t>& ends) = 0;
210 virtual void AddRoute(absl::Span<const int64_t> nodes,
211 absl::Span<const int> schedule_variables) = 0;
221 CHECK_LE(lower_bound, upper_bound);
230 int64_t lower_bound, int64_t upper_bound,
231 absl::Span<
const std::pair<int, double>> variable_coeffs) {
232 CHECK_LE(lower_bound, upper_bound);
234 for (
const auto& variable_coeff : variable_coeffs) {
243 int64_t lower_bound, int64_t upper_bound,
244 absl::Span<
const std::pair<int, double>> weighted_variables) {
246 if (std::numeric_limits<int64_t>::min() < lower_bound) {
252 const int under_lower_bound_ct =
254 lower_bound - 1, weighted_variables);
257 if (upper_bound < std::numeric_limits<int64_t>::max()) {
264 upper_bound + 1, std::numeric_limits<int64_t>::max(),
273 const int within_bounds_ct =
276 return within_bounds;
288 is_relaxation_(is_relaxation) {
289 lp_solver_.SetParameters(parameters);
290 linear_program_.SetMaximizationProblem(
false);
293 linear_program_.Clear();
294 linear_program_.SetMaximizationProblem(
false);
295 allowed_intervals_.clear();
298 return linear_program_.CreateNewVariable().value();
301 linear_program_.SetVariableName(glop::ColIndex(index), name);
304 int64_t upper_bound)
override {
305 DCHECK_GE(lower_bound, 0);
309 const int64_t kMaxValue = 1e10;
310 const double lp_min = lower_bound;
311 const double lp_max =
313 if (lp_min <= lp_max) {
314 linear_program_.SetVariableBounds(glop::ColIndex(index), lp_min, lp_max);
322 const std::vector<int64_t>& ends)
override {
327 allowed_intervals_[index] =
328 std::make_unique<SortedDisjointIntervalList>(starts, ends);
331 return linear_program_.variable_lower_bounds()[glop::ColIndex(index)];
334 const double upper_bound =
335 linear_program_.variable_upper_bounds()[glop::ColIndex(index)];
336 DCHECK_GE(upper_bound, 0);
337 return upper_bound ==
glop::kInfinity ? std::numeric_limits<int64_t>::max()
338 :
static_cast<int64_t
>(upper_bound);
341 linear_program_.SetObjectiveCoefficient(glop::ColIndex(index), coefficient);
344 return linear_program_.objective_coefficients()[glop::ColIndex(index)];
347 for (glop::ColIndex i(0); i < linear_program_.num_variables(); ++i) {
348 linear_program_.SetObjectiveCoefficient(i, 0);
352 return linear_program_.num_variables().value();
355 const glop::RowIndex ct = linear_program_.CreateNewConstraint();
356 linear_program_.SetConstraintBounds(
358 (lower_bound == std::numeric_limits<int64_t>::min()) ? -
glop::kInfinity
367 if (coefficient == 0.0)
return;
368 linear_program_.SetCoefficient(glop::RowIndex(ct), glop::ColIndex(index),
373 double max_coefficient = 0;
374 for (
int variable = 0; variable <
NumVariables(); variable++) {
376 max_coefficient = std::max(
MathUtil::Abs(coefficient), max_coefficient);
378 DCHECK_GE(max_coefficient, 0);
379 if (max_coefficient == 0) {
383 const glop::RowIndex ct = linear_program_.CreateNewConstraint();
384 double normalized_objective_value = 0;
385 for (
int variable = 0; variable <
NumVariables(); variable++) {
387 if (coefficient != 0) {
388 const double normalized_coeff = coefficient / max_coefficient;
390 normalized_objective_value +=
391 normalized_coeff * GetValueDouble(glop::ColIndex(variable));
394 normalized_objective_value = std::max(
397 normalized_objective_value);
400 std::vector<int> )
override {}
402 std::vector<int> )
override {}
404 void AddRoute(absl::Span<const int64_t>, absl::Span<const int>)
override{};
406 lp_solver_.GetMutableParameters()->set_max_time_in_seconds(
407 absl::ToDoubleSeconds(duration_limit));
414 linear_program_.NotifyThatColumnsAreClean();
415 VLOG(2) << linear_program_.Dump();
423 if (is_relaxation_) {
426 for (
const auto& allowed_interval : allowed_intervals_) {
429 allowed_interval.second.get();
431 if (it == interval_list->
end() || value < it->start) {
435 if (feasible_only && !linear_program_.objective_coefficients().empty()) {
444 const double value_double = GetValueDouble(glop::ColIndex(index));
445 return (value_double >= std::numeric_limits<int64_t>::max())
446 ? std::numeric_limits<int64_t>::max()
450 return linear_program_.SolutionIsInteger(lp_solver_.variable_values(),
456 const bool status = params.ParseFromString(parameters);
458 lp_solver_.SetParameters(params);
463 std::string
PrintModel()
const override {
return linear_program_.Dump(); }
466 double GetValueDouble(glop::ColIndex index)
const {
470 const bool is_relaxation_;
471 glop::LinearProgram linear_program_;
472 glop::LPSolver lp_solver_;
473 absl::flat_hash_map<int, std::unique_ptr<SortedDisjointIntervalList>>
481 parameters_.set_num_workers(1);
484 parameters_.set_cp_model_presolve(
true);
485 parameters_.set_max_presolve_iterations(1);
486 parameters_.set_cp_model_probing_level(0);
487 parameters_.set_use_sat_inprocessing(
false);
488 parameters_.set_symmetry_level(0);
489 parameters_.set_catch_sigint_signal(
false);
490 parameters_.set_mip_max_bound(1e8);
492 parameters_.set_linearization_level(2);
493 parameters_.set_cut_level(0);
494 parameters_.set_add_lp_constraints_lazily(
false);
495 parameters_.set_use_absl_random(
false);
496 parameters_.set_alternative_pool_size(0);
497 parameters_.set_transitive_precedences_work_limit(0);
503 objective_coefficients_.clear();
504 schedule_variables_.clear();
507 const int index = model_.variables_size();
510 variable->
add_domain(
static_cast<int64_t
>(parameters_.mip_max_bound()));
514 model_.mutable_variables(index)->set_name(name.data());
517 int64_t upper_bound)
override {
518 DCHECK_GE(lower_bound, 0);
519 const int64_t capped_upper_bound =
520 std::min<int64_t>(upper_bound, parameters_.mip_max_bound());
521 if (lower_bound > capped_upper_bound)
return false;
528 const std::vector<int64_t>& ends)
override {
529 DCHECK_EQ(starts.size(), ends.size());
531 for (
int i = 0; i < starts.size(); ++i) {
535 absl::StrFormat(
"disjoint(%ld, %ld)", index, i));
541 model_.mutable_constraints(window_ct)->add_enforcement_literal(variable);
545 return model_.variables(index).domain(0);
548 const auto& domain = model_.variables(index).domain();
549 return domain[domain.size() - 1];
552 if (index >= objective_coefficients_.size()) {
553 objective_coefficients_.resize(index + 1, 0);
555 objective_coefficients_[index] = coefficient;
557 model_.mutable_floating_point_objective();
562 return (index < objective_coefficients_.size())
563 ? objective_coefficients_[index]
567 model_.mutable_floating_point_objective()->Clear();
572 model_.add_constraints()->mutable_linear();
575 return model_.constraints_size() - 1;
579 model_.mutable_constraints(ct_index)->mutable_linear();
581 const int64_t integer_coefficient = coefficient;
587 int64_t activity = 0;
588 for (
int i = 0; i < objective.
vars_size(); ++i) {
589 activity += response_.solution(objective.
vars(i)) * objective.
coeffs(i);
593 for (
int i = 0; i < objective.
vars_size(); ++i) {
596 model_.clear_objective();
600 model_.add_constraints()->mutable_lin_max();
603 for (
const int var : vars) {
611 model_.add_constraints()->mutable_int_prod();
614 for (
const int var : vars) {
621 DCHECK_LT(ct, model_.constraints_size());
622 model_.mutable_constraints(ct)->add_enforcement_literal(condition);
625 absl::Span<const int> schedule_variables)
override {
626 DCHECK_EQ(nodes.size(), schedule_variables.size());
627 for (
const int64_t node : nodes) {
628 if (node >= schedule_hint_.size()) schedule_hint_.resize(node + 1, 0);
630 for (
int n = 0; n < nodes.size(); ++n) {
631 schedule_variables_.push_back(
632 {.node = nodes[n], .cumul = schedule_variables[n]});
636 const double max_time = absl::ToDoubleSeconds(duration_limit);
638 parameters_.set_max_time_in_seconds(max_time);
640 auto record_hint = [
this]() {
642 for (
int i = 0; i < response_.solution_size(); ++i) {
644 hint_.add_values(response_.solution(i));
646 for (
const auto& [node, cumul] : schedule_variables_) {
647 schedule_hint_[node] = response_.solution(cumul);
650 model_.clear_solution_hint();
651 auto* hint = model_.mutable_solution_hint();
652 if (hint_.vars_size() == model_.variables_size()) {
655 for (
const auto& [node, cumul] : schedule_variables_) {
656 if (schedule_hint_[node] == 0)
continue;
657 hint->add_vars(cumul);
658 hint->add_values(schedule_hint_[node]);
665 VLOG(2) << response_;
669 !model_.has_floating_point_objective())) {
683 return response_.solution(index);
692 bool ModelIsEmpty()
const override {
return model_.ByteSizeLong() == 0; }
701 std::vector<double> objective_coefficients_;
703 struct NodeAndCumul {
708 std::vector<NodeAndCumul> schedule_variables_;
710 std::vector<int64_t> schedule_hint_;
721 bool use_precedence_propagator);
726 int vehicle,
double solve_duration_ratio,
727 const std::function<int64_t(int64_t)>& next_accessor,
728 const RouteDimensionTravelInfo* dimension_travel_info,
729 const Resource* resource,
bool optimize_vehicle_costs,
731 std::vector<int64_t>* break_values, int64_t* cost_without_transit,
732 int64_t* transit_cost,
bool clear_lp =
true);
738 int vehicle,
double solve_duration_ratio,
739 const std::function<int64_t(int64_t)>& next_accessor,
740 const RouteDimensionTravelInfo* dimension_travel_info,
742 absl::Span<const int64_t> solution_cumul_values,
743 absl::Span<const int64_t> solution_break_values,
744 int64_t* cost_without_transits, int64_t* cost_offset =
nullptr,
745 bool reuse_previous_model_if_possible =
true,
bool clear_lp =
false,
746 bool clear_solution_constraints =
true,
747 absl::Duration* solve_duration =
nullptr);
754 int vehicle,
double solve_duration_ratio,
755 const std::function<int64_t(int64_t)>& next_accessor,
756 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
757 const RouteDimensionTravelInfo* dimension_travel_info,
758 absl::Span<const Resource> resources,
759 absl::Span<const int> resource_indices,
bool optimize_vehicle_costs,
761 std::vector<std::vector<int64_t>>* cumul_values,
762 std::vector<std::vector<int64_t>>* break_values,
763 std::vector<int64_t>* costs_without_transits, int64_t* transit_cost,
764 bool clear_lp =
true);
772 const std::function<int64_t(int64_t)>& next_accessor,
773 const std::vector<RouteDimensionTravelInfo>&
774 dimension_travel_info_per_route,
776 std::vector<int64_t>* break_values,
777 std::vector<std::vector<int>>* resource_indices_per_group,
778 int64_t* cost_without_transits, int64_t* transit_cost,
779 bool clear_lp =
true,
bool optimize_resource_assignment =
true);
782 const std::function<int64_t(int64_t)>& next_accessor,
783 const std::vector<RouteDimensionTravelInfo>&
784 dimension_travel_info_per_route,
786 std::vector<int64_t>* break_values);
789 int vehicle,
double solve_duration_ratio,
790 const std::function<int64_t(int64_t)>& next_accessor,
791 const RouteDimensionTravelInfo* dimension_travel_info,
793 std::vector<int64_t>* cumul_values, std::vector<int64_t>* break_values);
801 int vehicle,
double solve_duration_ratio,
802 const std::function<int64_t(int64_t)>& next_accessor,
803 absl::Span<const int64_t> transit_targets,
805 std::vector<int64_t>* optimal_transits,
806 std::vector<int64_t>* optimal_cumuls,
807 std::vector<int64_t>* optimal_breaks);
818 bool ExtractRouteCumulBounds(absl::Span<const int64_t> route,
819 int64_t cumul_offset);
824 bool TightenRouteCumulBounds(absl::Span<const int64_t> route,
825 absl::Span<const int64_t> min_transits,
826 int64_t cumul_offset);
832 bool SetRouteCumulConstraints(
833 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
834 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
835 absl::Span<const int64_t> transit_targets,
836 const RouteDimensionTravelInfo* dimension_travel_info,
837 int64_t cumul_offset,
bool optimize_costs,
839 int64_t* route_cost_offset);
845 void SetRouteCumulCosts(
int vehicle, int64_t cumul_offset,
846 int64_t total_fixed_transit,
848 int64_t* route_transit_cost,
849 int64_t* route_cost_offset);
854 bool SetRouteTravelConstraints(
855 const RouteDimensionTravelInfo* dimension_travel_info,
856 absl::Span<const int> lp_slacks, absl::Span<const int64_t> fixed_transits,
857 absl::Span<const int64_t> transit_targets,
867 bool SetGlobalConstraints(
868 const std::function<int64_t(int64_t)>& next_accessor,
869 int64_t cumul_offset,
bool optimize_costs,
872 bool SetGlobalConstraintsForResourceAssignment(
873 const std::function<int64_t(int64_t)>& next_accessor,
876 void SetValuesFromLP(absl::Span<const int> lp_variables, int64_t offset,
877 int64_t default_value,
879 std::vector<int64_t>* lp_values)
const;
881 void SetResourceIndices(
883 std::vector<std::vector<int>>* resource_indices_per_group)
const;
892 std::vector<int> vehicles,
double solve_duration_ratio,
896 std::unique_ptr<CumulBoundsPropagator> propagator_;
897 std::vector<int64_t> current_route_min_cumuls_;
898 std::vector<int64_t> current_route_max_cumuls_;
900 std::vector<int64_t> current_route_nodes_;
903 std::vector<int> current_route_cumul_variables_;
904 std::vector<int> index_to_cumul_variable_;
906 std::vector<int> current_route_variable_transit_variables_;
911 std::vector<int> current_route_break_variables_;
915 std::vector<int> all_break_variables_;
919 std::vector<int> vehicle_to_all_break_variables_offset_;
924 std::vector<std::vector<int>>
925 resource_class_to_vehicle_assignment_variables_per_group_;
928 std::vector<std::vector<absl::flat_hash_set<int>>>
929 resource_class_ignored_resources_per_group_;
932 int min_start_cumul_;
933 std::vector<std::pair<int64_t, int64_t>>
934 visited_pickup_delivery_indices_for_pair_;
954 int vehicle,
double solve_duration_ratio,
955 const std::function<int64_t(int64_t)>& next_accessor,
956 int64_t* optimal_cost);
961 int vehicle,
double solve_duration_ratio,
962 const std::function<int64_t(int64_t)>& next_accessor,
964 int64_t* optimal_cost_without_transits);
966 std::vector<DimensionSchedulingStatus>
968 int vehicle,
double solve_duration_ratio,
969 const std::function<int64_t(int64_t)>& next_accessor,
970 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
971 absl::Span<const RoutingModel::ResourceGroup::Resource> resources,
972 absl::Span<const int> resource_indices,
bool optimize_vehicle_costs,
973 std::vector<int64_t>* optimal_costs_without_transits,
974 std::vector<std::vector<int64_t>>* optimal_cumuls,
975 std::vector<std::vector<int64_t>>* optimal_breaks);
983 int vehicle,
double solve_duration_ratio,
984 const std::function<int64_t(int64_t)>& next_accessor,
987 std::vector<int64_t>* optimal_cumuls,
988 std::vector<int64_t>* optimal_breaks);
993 int vehicle,
double solve_duration_ratio,
994 const std::function<int64_t(int64_t)>& next_accessor,
996 std::vector<int64_t>* optimal_cumuls,
997 std::vector<int64_t>* optimal_breaks,
998 int64_t* optimal_cost_without_transits);
1003 int vehicle,
double solve_duration_ratio,
1004 const std::function<int64_t(int64_t)>& next_accessor,
1006 absl::Span<const int64_t> solution_cumul_values,
1007 absl::Span<const int64_t> solution_break_values, int64_t* solution_cost,
1008 int64_t* cost_offset =
nullptr,
1009 bool reuse_previous_model_if_possible =
false,
bool clear_lp =
true,
1010 absl::Duration* solve_duration =
nullptr);
1018 int vehicle,
double solve_duration_ratio,
1019 const std::function<int64_t(int64_t)>& next_accessor,
1022 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks);
1028 int vehicle,
double solve_duration_ratio,
1029 const std::function<int64_t(int64_t)>& next_accessor,
1030 absl::Span<const int64_t> transit_targets,
1032 std::vector<int64_t>* optimal_transits,
1033 std::vector<int64_t>* optimal_cumuls,
1034 std::vector<int64_t>* optimal_breaks);
1037 return optimizer_core_.dimension();
1041 std::vector<std::unique_ptr<RoutingLinearSolverWrapper>> solver_;
1057 const std::function<int64_t(int64_t)>& next_accessor,
1058 int64_t* optimal_cost_without_transits);
1065 const std::function<int64_t(int64_t)>& next_accessor,
1066 const std::vector<RoutingModel::RouteDimensionTravelInfo>&
1067 dimension_travel_info_per_route,
1068 std::vector<int64_t>* optimal_cumuls,
1069 std::vector<int64_t>* optimal_breaks,
1070 std::vector<std::vector<int>>* optimal_resource_indices_per_group);
1079 const std::function<int64_t(int64_t)>& next_accessor,
1080 const std::vector<RoutingModel::RouteDimensionTravelInfo>&
1081 dimension_travel_info_per_route,
1082 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks);
1085 return optimizer_core_.dimension();
1089 std::unique_ptr<RoutingLinearSolverWrapper> solver_;
1112 absl::Span<const int> vehicles,
1115 resource_indices_per_class,
1117 absl::flat_hash_set<int>>&
1118 ignored_resources_per_class,
1119 std::function<
const std::vector<int64_t>*(
int)>
1120 vehicle_to_resource_class_assignment_costs,
1121 std::vector<int>* resource_indices);
1133 int v,
double solve_duration_ratio,
1134 const RoutingModel::ResourceGroup& resource_group,
1136 absl::flat_hash_set<int>>&
1137 ignored_resources_per_class,
1138 const std::function<int64_t(int64_t)>& next_accessor,
1139 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
1140 bool optimize_vehicle_costs, LocalDimensionCumulOptimizer* lp_optimizer,
1141 LocalDimensionCumulOptimizer* mp_optimizer,
1142 std::vector<int64_t>* assignment_costs,
1143 std::vector<std::vector<int64_t>>* cumul_values,
1144 std::vector<std::vector<int64_t>>* break_values);
1165 const FloatSlopePiecewiseLinearFunction& pwl_function,
int index_start = 0,
1166 int index_end = -1);
1175 absl::Span<const SlopeAndYIntercept> slope_and_y_intercept);
CumulBoundsPropagator(const RoutingDimension *dimension)
bool PropagateCumulBounds(const std::function< int64_t(int64_t)> &next_accessor, int64_t cumul_offset, const std::vector< RoutingModel::RouteDimensionTravelInfo > *dimension_travel_info_per_route=nullptr)
int64_t CumulMax(int index) const
int64_t CumulMin(int index) const
const RoutingDimension & dimension() const
DimensionSchedulingStatus Optimize(const std::function< int64_t(int64_t)> &next_accessor, const std::vector< RouteDimensionTravelInfo > &dimension_travel_info_per_route, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *cumul_values, std::vector< int64_t > *break_values, std::vector< std::vector< int > > *resource_indices_per_group, int64_t *cost_without_transits, int64_t *transit_cost, bool clear_lp=true, bool optimize_resource_assignment=true)
DimensionSchedulingStatus ComputeSingleRouteSolutionCostWithoutFixedTransits(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RouteDimensionTravelInfo *dimension_travel_info, RoutingLinearSolverWrapper *solver, absl::Span< const int64_t > solution_cumul_values, absl::Span< const int64_t > solution_break_values, int64_t *cost_without_transits, int64_t *cost_offset=nullptr, bool reuse_previous_model_if_possible=true, bool clear_lp=false, bool clear_solution_constraints=true, absl::Duration *solve_duration=nullptr)
const RoutingDimension * dimension() const
DimensionSchedulingStatus OptimizeAndPack(const std::function< int64_t(int64_t)> &next_accessor, const std::vector< RouteDimensionTravelInfo > &dimension_travel_info_per_route, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *cumul_values, std::vector< int64_t > *break_values)
DimensionSchedulingStatus OptimizeSingleRouteWithTransitTargets(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, absl::Span< const int64_t > transit_targets, TransitTargetCost transit_target_cost, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *optimal_transits, std::vector< int64_t > *optimal_cumuls, std::vector< int64_t > *optimal_breaks)
DimensionCumulOptimizerCore(const RoutingDimension *dimension, bool use_precedence_propagator)
DimensionSchedulingStatus OptimizeSingleRouteWithResource(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RouteDimensionTravelInfo *dimension_travel_info, const Resource *resource, bool optimize_vehicle_costs, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *cumul_values, std::vector< int64_t > *break_values, int64_t *cost_without_transit, int64_t *transit_cost, bool clear_lp=true)
DimensionSchedulingStatus OptimizeAndPackSingleRoute(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RouteDimensionTravelInfo *dimension_travel_info, const Resource *resource, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *cumul_values, std::vector< int64_t > *break_values)
std::vector< DimensionSchedulingStatus > OptimizeSingleRouteWithResources(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const std::function< int64_t(int64_t, int64_t)> &transit_accessor, const RouteDimensionTravelInfo *dimension_travel_info, absl::Span< const Resource > resources, absl::Span< const int > resource_indices, bool optimize_vehicle_costs, RoutingLinearSolverWrapper *solver, std::vector< std::vector< int64_t > > *cumul_values, std::vector< std::vector< int64_t > > *break_values, std::vector< int64_t > *costs_without_transits, int64_t *transit_cost, bool clear_lp=true)
DimensionSchedulingStatus ComputeCumulCostWithoutFixedTransits(const std::function< int64_t(int64_t)> &next_accessor, int64_t *optimal_cost_without_transits)
GlobalDimensionCumulOptimizer(const RoutingDimension *dimension, RoutingSearchParameters::SchedulingSolver solver_type, RoutingSearchStats *search_stats)
const RoutingDimension * dimension() const
DimensionSchedulingStatus ComputeCumuls(const std::function< int64_t(int64_t)> &next_accessor, const std::vector< RoutingModel::RouteDimensionTravelInfo > &dimension_travel_info_per_route, std::vector< int64_t > *optimal_cumuls, std::vector< int64_t > *optimal_breaks, std::vector< std::vector< int > > *optimal_resource_indices_per_group)
DimensionSchedulingStatus ComputePackedCumuls(const std::function< int64_t(int64_t)> &next_accessor, const std::vector< RoutingModel::RouteDimensionTravelInfo > &dimension_travel_info_per_route, std::vector< int64_t > *packed_cumuls, std::vector< int64_t > *packed_breaks)
const RoutingDimension * dimension() const
DimensionSchedulingStatus ComputeRouteSolutionCostWithoutFixedTransits(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RoutingModel::RouteDimensionTravelInfo *dimension_travel_info, absl::Span< const int64_t > solution_cumul_values, absl::Span< const int64_t > solution_break_values, int64_t *solution_cost, int64_t *cost_offset=nullptr, bool reuse_previous_model_if_possible=false, bool clear_lp=true, absl::Duration *solve_duration=nullptr)
DimensionSchedulingStatus ComputePackedRouteCumuls(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RoutingModel::RouteDimensionTravelInfo *dimension_travel_info, const RoutingModel::ResourceGroup::Resource *resource, std::vector< int64_t > *packed_cumuls, std::vector< int64_t > *packed_breaks)
LocalDimensionCumulOptimizer(const RoutingDimension *dimension, RoutingSearchParameters::SchedulingSolver solver_type, RoutingSearchStats *search_stats)
DimensionSchedulingStatus ComputeRouteCumuls(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RoutingModel::RouteDimensionTravelInfo *dimension_travel_info, const RoutingModel::ResourceGroup::Resource *resource, std::vector< int64_t > *optimal_cumuls, std::vector< int64_t > *optimal_breaks)
DimensionSchedulingStatus ComputeRouteCumulCostWithoutFixedTransits(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RoutingModel::ResourceGroup::Resource *resource, int64_t *optimal_cost_without_transits)
DimensionSchedulingStatus ComputeRouteCumulsAndCostWithoutFixedTransits(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const RoutingModel::RouteDimensionTravelInfo *dimension_travel_info, std::vector< int64_t > *optimal_cumuls, std::vector< int64_t > *optimal_breaks, int64_t *optimal_cost_without_transits)
Merge with the packing method DimensionSchedulingStatus ComputeRouteCumulsWithTransitTargets(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, absl::Span< const int64_t > transit_targets, DimensionCumulOptimizerCore::TransitTargetCost transit_target_cost, std::vector< int64_t > *optimal_transits, std::vector< int64_t > *optimal_cumuls, std::vector< int64_t > *optimal_breaks)
std::vector< DimensionSchedulingStatus > ComputeRouteCumulCostsForResourcesWithoutFixedTransits(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, const std::function< int64_t(int64_t, int64_t)> &transit_accessor, absl::Span< const RoutingModel::ResourceGroup::Resource > resources, absl::Span< const int > resource_indices, bool optimize_vehicle_costs, std::vector< int64_t > *optimal_costs_without_transits, std::vector< std::vector< int64_t > > *optimal_cumuls, std::vector< std::vector< int64_t > > *optimal_breaks)
DimensionSchedulingStatus ComputeRouteCumulCost(int vehicle, double solve_duration_ratio, const std::function< int64_t(int64_t)> &next_accessor, int64_t *optimal_cost)
static IntOut Round(FloatIn x)
void AddMaximumConstraint(int max_var, std::vector< int > vars) override
void AddObjectiveConstraint() override
void SetParameters(const std::string &) override
void SetVariableDisjointBounds(int index, const std::vector< int64_t > &starts, const std::vector< int64_t > &ends) override
int NumVariables() const override
bool IsCPSATSolver() override
int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound) override
int CreateNewPositiveVariable() override
DimensionSchedulingStatus Solve(absl::Duration duration_limit) override
void SetCoefficient(int ct_index, int index, double coefficient) override
void SetVariableName(int index, absl::string_view name) override
bool SetVariableBounds(int index, int64_t lower_bound, int64_t upper_bound) override
void SetObjectiveCoefficient(int index, double coefficient) override
double GetObjectiveCoefficient(int index) const override
std::string PrintModel() const override
int64_t GetVariableUpperBound(int index) const override
void SetEnforcementLiteral(int ct, int condition) override
void ClearObjective() override
int64_t GetObjectiveValue() const override
void AddRoute(absl::Span< const int64_t > nodes, absl::Span< const int > schedule_variables) override
RoutingCPSatWrapper(RoutingSearchStats *const search_stats)
int64_t GetVariableLowerBound(int index) const override
int64_t GetVariableValue(int index) const override
bool ModelIsEmpty() const override
void AddProductConstraint(int product_var, std::vector< int > vars) override
~RoutingCPSatWrapper() override
bool SolutionIsInteger() const override
int64_t GetVariableLowerBound(int index) const override
int NumVariables() const override
void ClearObjective() override
bool SetVariableBounds(int index, int64_t lower_bound, int64_t upper_bound) override
int64_t GetVariableValue(int index) const override
double GetObjectiveCoefficient(int index) const override
int CreateNewPositiveVariable() override
RoutingGlopWrapper(bool is_relaxation, const glop::GlopParameters ¶meters, RoutingSearchStats *search_stats)
void AddRoute(absl::Span< const int64_t >, absl::Span< const int >) override
std::string PrintModel() const override
void SetObjectiveCoefficient(int index, double coefficient) override
void AddMaximumConstraint(int, std::vector< int >) override
void AddObjectiveConstraint() override
void SetEnforcementLiteral(int, int) override
DimensionSchedulingStatus Solve(absl::Duration duration_limit) override
int64_t GetObjectiveValue() const override
int64_t GetVariableUpperBound(int index) const override
bool IsCPSATSolver() override
bool SolutionIsInteger() const override
void SetVariableDisjointBounds(int index, const std::vector< int64_t > &starts, const std::vector< int64_t > &ends) override
void SetCoefficient(int ct, int index, double coefficient) override
void SetVariableName(int index, absl::string_view name) override
int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound) override
void AddProductConstraint(int, std::vector< int >) override
void SetParameters(const std::string ¶meters) override
virtual int NumVariables() const =0
virtual int64_t GetObjectiveValue() const =0
virtual DimensionSchedulingStatus Solve(absl::Duration duration_limit)=0
virtual void SetCoefficient(int ct, int index, double coefficient)=0
virtual int64_t GetVariableUpperBound(int index) const =0
RoutingSearchStats *const search_stats_
virtual ~RoutingLinearSolverWrapper()=default
int AddLinearConstraint(int64_t lower_bound, int64_t upper_bound, absl::Span< const std::pair< int, double > > variable_coeffs)
virtual bool SolutionIsInteger() const =0
virtual int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound)=0
virtual void SetEnforcementLiteral(int ct, int condition)=0
virtual void AddProductConstraint(int product_var, std::vector< int > vars)=0
virtual std::string PrintModel() const =0
virtual int64_t GetVariableValue(int index) const =0
virtual void SetVariableDisjointBounds(int index, const std::vector< int64_t > &starts, const std::vector< int64_t > &ends)=0
int AddReifiedLinearConstraint(int64_t lower_bound, int64_t upper_bound, absl::Span< const std::pair< int, double > > weighted_variables)
virtual void AddRoute(absl::Span< const int64_t > nodes, absl::Span< const int > schedule_variables)=0
virtual void SetObjectiveCoefficient(int index, double coefficient)=0
static const int kNoConstraint
virtual void ClearObjective()=0
virtual int CreateNewPositiveVariable()=0
virtual bool SetVariableBounds(int index, int64_t lower_bound, int64_t upper_bound)=0
virtual void SetParameters(const std::string ¶meters)=0
virtual void AddMaximumConstraint(int max_var, std::vector< int > vars)=0
virtual void SetVariableName(int index, absl::string_view name)=0
virtual void AddObjectiveConstraint()=0
virtual bool ModelIsEmpty() const
virtual int64_t GetVariableLowerBound(int index) const =0
virtual bool IsCPSATSolver()=0
RoutingLinearSolverWrapper(RoutingSearchStats *search_stats)
virtual double GetObjectiveCoefficient(int index) const =0
int AddVariable(int64_t lower_bound, int64_t upper_bound)
A Resource sets attributes (costs/constraints) for a set of dimensions.
RoutingResourceClassIndex ResourceClassIndex
RoutingSearchParameters_SchedulingSolver SchedulingSolver
Iterator FirstIntervalGreaterOrEqual(int64_t value) const
ConstIterator end() const
const DenseRow & variable_values() const
::int32_t vars(int index) const
::int64_t coeffs(int index) const
void add_coeffs(double value)
void add_vars(::int32_t value)
void add_domain(::int64_t value)
void set_domain(int index, ::int64_t value)
::operations_research::sat::LinearExpressionProto *PROTOBUF_NONNULL mutable_target()
::operations_research::sat::LinearExpressionProto *PROTOBUF_NONNULL add_exprs()
void add_vars(::int32_t value)
void add_domain(::int64_t value)
void add_coeffs(::int64_t value)
void add_coeffs(::int64_t value)
void add_vars(::int32_t value)
T Add(std::function< T(Model *)> f)
static constexpr SearchBranching PORTFOLIO_SEARCH
constexpr Fractional kInfinity
std::function< SatParameters(Model *)> NewSatParameters(absl::string_view params)
CpSolverResponse SolveCpModel(const CpModelProto &model_proto, Model *model)
int64_t ComputeBestVehicleToResourceAssignment(absl::Span< const int > vehicles, const util_intops::StrongVector< RoutingModel::ResourceClassIndex, std::vector< int > > &resource_indices_per_class, const util_intops::StrongVector< RoutingModel::ResourceClassIndex, absl::flat_hash_set< int > > &ignored_resources_per_class, std::function< const std::vector< int64_t > *(int)> vehicle_to_resource_class_assignment_costs, std::vector< int > *resource_indices)
DimensionSchedulingStatus
std::vector< bool > SlopeAndYInterceptToConvexityRegions(absl::Span< const SlopeAndYIntercept > slope_and_y_intercept)
bool ComputeVehicleToResourceClassAssignmentCosts(int v, double solve_duration_ratio, const RoutingModel::ResourceGroup &resource_group, const util_intops::StrongVector< RoutingModel::ResourceClassIndex, absl::flat_hash_set< int > > &ignored_resources_per_class, const std::function< int64_t(int64_t)> &next_accessor, const std::function< int64_t(int64_t, int64_t)> &transit_accessor, bool optimize_vehicle_costs, LocalDimensionCumulOptimizer *lp_optimizer, LocalDimensionCumulOptimizer *mp_optimizer, std::vector< int64_t > *assignment_costs, std::vector< std::vector< int64_t > > *cumul_values, std::vector< std::vector< int64_t > > *break_values)
std::string ProtobufDebugString(const P &message)
std::vector< SlopeAndYIntercept > PiecewiseLinearFunctionToSlopeAndYIntercept(const FloatSlopePiecewiseLinearFunction &pwl_function, int index_start, int index_end)
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
int64_t cost_coefficient_above_threshold
int64_t cost_coefficient_below_threshold
friend::std::ostream & operator<<(::std::ostream &os, const SlopeAndYIntercept &it)