14#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_LP_SCHEDULING_H_
15#define OR_TOOLS_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"
38#include "ortools/constraint_solver/routing_parameters.pb.h"
40#include "ortools/glop/parameters.pb.h"
44#include "ortools/sat/cp_model.pb.h"
47#include "ortools/sat/sat_parameters.pb.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;
85 const RoutingDimension&
dimension()
const {
return dimension_; }
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_;
179 int64_t upper_bound) = 0;
181 const std::vector<int64_t>& starts,
182 const std::vector<int64_t>& ends) = 0;
208 virtual void AddRoute(absl::Span<const int64_t> nodes,
209 absl::Span<const int> schedule_variables) = 0;
219 CHECK_LE(lower_bound, upper_bound);
228 int64_t lower_bound, int64_t upper_bound,
229 absl::Span<
const std::pair<int, double>> variable_coeffs) {
230 CHECK_LE(lower_bound, upper_bound);
232 for (
const auto& variable_coeff : variable_coeffs) {
241 int64_t lower_bound, int64_t upper_bound,
242 absl::Span<
const std::pair<int, double>> weighted_variables) {
244 if (std::numeric_limits<int64_t>::min() < lower_bound) {
250 const int under_lower_bound_ct =
252 lower_bound - 1, weighted_variables);
255 if (upper_bound < std::numeric_limits<int64_t>::max()) {
262 upper_bound + 1, std::numeric_limits<int64_t>::max(),
271 const int within_bounds_ct =
274 return within_bounds;
281 : is_relaxation_(is_relaxation) {
282 lp_solver_.SetParameters(parameters);
283 linear_program_.SetMaximizationProblem(
false);
286 linear_program_.Clear();
287 linear_program_.SetMaximizationProblem(
false);
288 allowed_intervals_.clear();
291 return linear_program_.CreateNewVariable().value();
294 linear_program_.SetVariableName(glop::ColIndex(index), name);
297 int64_t upper_bound)
override {
298 DCHECK_GE(lower_bound, 0);
302 const int64_t kMaxValue = 1e10;
303 const double lp_min = lower_bound;
304 const double lp_max =
306 if (lp_min <= lp_max) {
307 linear_program_.SetVariableBounds(glop::ColIndex(index), lp_min, lp_max);
315 const std::vector<int64_t>& ends)
override {
320 allowed_intervals_[index] =
321 std::make_unique<SortedDisjointIntervalList>(starts, ends);
324 return linear_program_.variable_lower_bounds()[glop::ColIndex(index)];
327 const double upper_bound =
328 linear_program_.variable_upper_bounds()[glop::ColIndex(index)];
329 DCHECK_GE(upper_bound, 0);
330 return upper_bound ==
glop::kInfinity ? std::numeric_limits<int64_t>::max()
331 :
static_cast<int64_t
>(upper_bound);
334 linear_program_.SetObjectiveCoefficient(glop::ColIndex(index), coefficient);
337 return linear_program_.objective_coefficients()[glop::ColIndex(index)];
340 for (glop::ColIndex i(0); i < linear_program_.num_variables(); ++i) {
341 linear_program_.SetObjectiveCoefficient(i, 0);
345 return linear_program_.num_variables().value();
348 const glop::RowIndex ct = linear_program_.CreateNewConstraint();
349 linear_program_.SetConstraintBounds(
351 (lower_bound == std::numeric_limits<int64_t>::min()) ? -
glop::kInfinity
360 if (coefficient == 0.0)
return;
361 linear_program_.SetCoefficient(glop::RowIndex(ct), glop::ColIndex(index),
366 double max_coefficient = 0;
367 for (
int variable = 0; variable <
NumVariables(); variable++) {
369 max_coefficient = std::max(
MathUtil::Abs(coefficient), max_coefficient);
371 DCHECK_GE(max_coefficient, 0);
372 if (max_coefficient == 0) {
376 const glop::RowIndex ct = linear_program_.CreateNewConstraint();
377 double normalized_objective_value = 0;
378 for (
int variable = 0; variable <
NumVariables(); variable++) {
380 if (coefficient != 0) {
381 const double normalized_coeff = coefficient / max_coefficient;
383 normalized_objective_value += normalized_coeff *
GetValue(variable);
386 normalized_objective_value = std::max(
389 normalized_objective_value);
392 std::vector<int> )
override {}
394 std::vector<int> )
override {}
396 void AddRoute(absl::Span<const int64_t>, absl::Span<const int>)
override{};
398 lp_solver_.GetMutableParameters()->set_max_time_in_seconds(
399 absl::ToDoubleSeconds(duration_limit));
406 linear_program_.NotifyThatColumnsAreClean();
407 VLOG(2) << linear_program_.Dump();
414 if (is_relaxation_) {
417 for (
const auto& allowed_interval : allowed_intervals_) {
418 const double value_double =
GetValue(allowed_interval.first);
419 const int64_t value =
420 (value_double >= std::numeric_limits<int64_t>::max())
421 ? std::numeric_limits<int64_t>::max()
424 allowed_interval.second.get();
426 if (it == interval_list->
end() || value < it->start) {
430 if (feasible_only && !linear_program_.objective_coefficients().empty()) {
439 return lp_solver_.variable_values()[glop::ColIndex(index)];
442 return linear_program_.SolutionIsInteger(lp_solver_.variable_values(),
447 glop::GlopParameters params;
448 const bool status = params.ParseFromString(parameters);
450 lp_solver_.SetParameters(params);
455 std::string
PrintModel()
const override {
return linear_program_.Dump(); }
458 const bool is_relaxation_;
461 absl::flat_hash_map<int, std::unique_ptr<SortedDisjointIntervalList>>
468 parameters_.set_num_search_workers(1);
471 parameters_.set_cp_model_presolve(
true);
472 parameters_.set_max_presolve_iterations(1);
473 parameters_.set_cp_model_probing_level(0);
474 parameters_.set_use_sat_inprocessing(
false);
475 parameters_.set_symmetry_level(0);
476 parameters_.set_catch_sigint_signal(
false);
477 parameters_.set_mip_max_bound(1e8);
478 parameters_.set_search_branching(sat::SatParameters::PORTFOLIO_SEARCH);
479 parameters_.set_linearization_level(2);
480 parameters_.set_cut_level(0);
481 parameters_.set_use_absl_random(
false);
487 objective_coefficients_.clear();
488 schedule_variables_.clear();
491 const int index = model_.variables_size();
492 sat::IntegerVariableProto*
const variable = model_.add_variables();
493 variable->add_domain(0);
494 variable->add_domain(
static_cast<int64_t
>(parameters_.mip_max_bound()));
498 model_.mutable_variables(index)->set_name(name.data());
501 int64_t upper_bound)
override {
502 DCHECK_GE(lower_bound, 0);
503 const int64_t capped_upper_bound =
504 std::min<int64_t>(upper_bound, parameters_.mip_max_bound());
505 if (lower_bound > capped_upper_bound)
return false;
506 sat::IntegerVariableProto*
const variable = model_.mutable_variables(index);
507 variable->set_domain(0, lower_bound);
508 variable->set_domain(1, capped_upper_bound);
512 const std::vector<int64_t>& ends)
override {
513 DCHECK_EQ(starts.size(), ends.size());
515 for (
int i = 0; i < starts.size(); ++i) {
519 absl::StrFormat(
"disjoint(%ld, %ld)", index, i));
525 model_.mutable_constraints(window_ct)->add_enforcement_literal(variable);
529 return model_.variables(index).domain(0);
532 const auto& domain = model_.variables(index).domain();
533 return domain[domain.size() - 1];
536 if (index >= objective_coefficients_.size()) {
537 objective_coefficients_.resize(index + 1, 0);
539 objective_coefficients_[index] = coefficient;
540 sat::FloatObjectiveProto*
const objective =
541 model_.mutable_floating_point_objective();
542 objective->add_vars(index);
543 objective->add_coeffs(coefficient);
546 return (index < objective_coefficients_.size())
547 ? objective_coefficients_[index]
551 model_.mutable_floating_point_objective()->Clear();
555 sat::LinearConstraintProto*
const ct =
556 model_.add_constraints()->mutable_linear();
557 ct->add_domain(lower_bound);
558 ct->add_domain(upper_bound);
559 return model_.constraints_size() - 1;
562 sat::LinearConstraintProto*
const ct =
563 model_.mutable_constraints(ct_index)->mutable_linear();
565 const int64_t integer_coefficient = coefficient;
566 ct->add_coeffs(integer_coefficient);
570 const sat::CpObjectiveProto& objective = response_.integer_objective();
571 int64_t activity = 0;
572 for (
int i = 0; i < objective.vars_size(); ++i) {
573 activity += response_.solution(objective.vars(i)) * objective.coeffs(i);
577 for (
int i = 0; i < objective.vars_size(); ++i) {
580 model_.clear_objective();
583 sat::LinearArgumentProto*
const ct =
584 model_.add_constraints()->mutable_lin_max();
585 ct->mutable_target()->add_vars(max_var);
586 ct->mutable_target()->add_coeffs(1);
587 for (
const int var : vars) {
588 sat::LinearExpressionProto*
const expr = ct->add_exprs();
594 sat::LinearArgumentProto*
const ct =
595 model_.add_constraints()->mutable_int_prod();
596 ct->mutable_target()->add_vars(product_var);
597 ct->mutable_target()->add_coeffs(1);
598 for (
const int var : vars) {
599 sat::LinearExpressionProto* expr = ct->add_exprs();
605 DCHECK_LT(ct, model_.constraints_size());
606 model_.mutable_constraints(ct)->add_enforcement_literal(condition);
609 absl::Span<const int> schedule_variables)
override {
610 DCHECK_EQ(nodes.size(), schedule_variables.size());
611 for (
const int64_t node : nodes) {
612 if (node >= schedule_hint_.size()) schedule_hint_.resize(node + 1, 0);
614 for (
int n = 0; n < nodes.size(); ++n) {
615 schedule_variables_.push_back(
616 {.node = nodes[n], .cumul = schedule_variables[n]});
620 const double max_time = absl::ToDoubleSeconds(duration_limit);
622 parameters_.set_max_time_in_seconds(max_time);
624 auto record_hint = [
this]() {
626 for (
int i = 0; i < response_.solution_size(); ++i) {
628 hint_.add_values(response_.solution(i));
630 for (
const auto& [node, cumul] : schedule_variables_) {
631 schedule_hint_[node] = response_.solution(cumul);
634 model_.clear_solution_hint();
635 auto* hint = model_.mutable_solution_hint();
636 if (hint_.vars_size() == model_.variables_size()) {
639 for (
const auto& [node, cumul] : schedule_variables_) {
640 if (schedule_hint_[node] == 0)
continue;
641 hint->add_vars(cumul);
642 hint->add_values(schedule_hint_[node]);
648 VLOG(2) << response_;
649 DCHECK_NE(response_.status(), sat::CpSolverStatus::MODEL_INVALID);
650 if (response_.status() == sat::CpSolverStatus::OPTIMAL ||
651 (response_.status() == sat::CpSolverStatus::FEASIBLE &&
652 !model_.has_floating_point_objective())) {
655 }
else if (response_.status() == sat::CpSolverStatus::FEASIBLE) {
666 return response_.solution(index);
675 bool ModelIsEmpty()
const override {
return model_.ByteSizeLong() == 0; }
681 sat::CpModelProto model_;
682 sat::CpSolverResponse response_;
683 sat::SatParameters parameters_;
684 std::vector<double> objective_coefficients_;
685 sat::PartialVariableAssignment hint_;
686 struct NodeAndCumul {
691 std::vector<NodeAndCumul> schedule_variables_;
693 std::vector<int64_t> schedule_hint_;
699 using RouteDimensionTravelInfo = RoutingModel::RouteDimensionTravelInfo;
700 using Resource = RoutingModel::ResourceGroup::Resource;
704 bool use_precedence_propagator);
709 int vehicle,
double solve_duration_ratio,
710 const std::function<int64_t(int64_t)>& next_accessor,
711 const RouteDimensionTravelInfo* dimension_travel_info,
712 const Resource* resource,
bool optimize_vehicle_costs,
714 std::vector<int64_t>* break_values, int64_t* cost_without_transit,
715 int64_t* transit_cost,
bool clear_lp =
true);
721 int vehicle,
double solve_duration_ratio,
722 const std::function<int64_t(int64_t)>& next_accessor,
723 const RouteDimensionTravelInfo* dimension_travel_info,
725 absl::Span<const int64_t> solution_cumul_values,
726 absl::Span<const int64_t> solution_break_values,
727 int64_t* cost_without_transits, int64_t* cost_offset =
nullptr,
728 bool reuse_previous_model_if_possible =
true,
bool clear_lp =
false,
729 bool clear_solution_constraints =
true,
730 absl::Duration* solve_duration =
nullptr);
737 int vehicle,
double solve_duration_ratio,
738 const std::function<int64_t(int64_t)>& next_accessor,
739 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
740 const RouteDimensionTravelInfo* dimension_travel_info,
741 absl::Span<const Resource> resources,
742 absl::Span<const int> resource_indices,
bool optimize_vehicle_costs,
744 std::vector<std::vector<int64_t>>* cumul_values,
745 std::vector<std::vector<int64_t>>* break_values,
746 std::vector<int64_t>* costs_without_transits, int64_t* transit_cost,
747 bool clear_lp =
true);
755 const std::function<int64_t(int64_t)>& next_accessor,
756 const std::vector<RouteDimensionTravelInfo>&
757 dimension_travel_info_per_route,
759 std::vector<int64_t>* break_values,
760 std::vector<std::vector<int>>* resource_indices_per_group,
761 int64_t* cost_without_transits, int64_t* transit_cost,
762 bool clear_lp =
true,
bool optimize_resource_assignment =
true);
765 const std::function<int64_t(int64_t)>& next_accessor,
766 const std::vector<RouteDimensionTravelInfo>&
767 dimension_travel_info_per_route,
769 std::vector<int64_t>* break_values);
772 int vehicle,
double solve_duration_ratio,
773 const std::function<int64_t(int64_t)>& next_accessor,
774 const RouteDimensionTravelInfo* dimension_travel_info,
776 std::vector<int64_t>* cumul_values, std::vector<int64_t>* break_values);
778 const RoutingDimension*
dimension()
const {
return dimension_; }
787 bool ExtractRouteCumulBounds(absl::Span<const int64_t> route,
788 int64_t cumul_offset);
793 bool TightenRouteCumulBounds(absl::Span<const int64_t> route,
794 absl::Span<const int64_t> min_transits,
795 int64_t cumul_offset);
801 bool SetRouteCumulConstraints(
802 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
803 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
804 const RouteDimensionTravelInfo* dimension_travel_info,
805 int64_t cumul_offset,
bool optimize_costs,
807 int64_t* route_cost_offset);
812 bool SetRouteTravelConstraints(
813 const RouteDimensionTravelInfo* dimension_travel_info,
814 absl::Span<const int> lp_slacks, absl::Span<const int64_t> fixed_transit,
824 bool SetGlobalConstraints(
825 const std::function<int64_t(int64_t)>& next_accessor,
826 int64_t cumul_offset,
bool optimize_costs,
829 bool SetGlobalConstraintsForResourceAssignment(
830 const std::function<int64_t(int64_t)>& next_accessor,
833 void SetValuesFromLP(absl::Span<const int> lp_variables, int64_t offset,
835 std::vector<int64_t>* lp_values)
const;
837 void SetResourceIndices(
839 std::vector<std::vector<int>>* resource_indices_per_group)
const;
848 std::vector<int> vehicles,
double solve_duration_ratio,
850 const glop::GlopParameters& packing_parameters);
852 std::unique_ptr<CumulBoundsPropagator> propagator_;
853 std::vector<int64_t> current_route_min_cumuls_;
854 std::vector<int64_t> current_route_max_cumuls_;
855 const RoutingDimension*
const dimension_;
857 std::vector<int> current_route_cumul_variables_;
858 std::vector<int> index_to_cumul_variable_;
863 std::vector<int> current_route_break_variables_;
867 std::vector<int> all_break_variables_;
871 std::vector<int> vehicle_to_all_break_variables_offset_;
876 std::vector<std::vector<int>>
877 resource_class_to_vehicle_assignment_variables_per_group_;
880 std::vector<std::vector<absl::flat_hash_set<int>>>
881 resource_class_ignored_resources_per_group_;
884 int min_start_cumul_;
885 std::vector<std::pair<int64_t, int64_t>>
886 visited_pickup_delivery_indices_for_pair_;
898 RoutingSearchParameters::SchedulingSolver solver_type);
905 int vehicle,
double solve_duration_ratio,
906 const std::function<int64_t(int64_t)>& next_accessor,
907 int64_t* optimal_cost);
912 int vehicle,
double solve_duration_ratio,
913 const std::function<int64_t(int64_t)>& next_accessor,
914 const RoutingModel::ResourceGroup::Resource* resource,
915 int64_t* optimal_cost_without_transits);
917 std::vector<DimensionSchedulingStatus>
919 int vehicle,
double solve_duration_ratio,
920 const std::function<int64_t(int64_t)>& next_accessor,
921 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
922 absl::Span<const RoutingModel::ResourceGroup::Resource> resources,
923 absl::Span<const int> resource_indices,
bool optimize_vehicle_costs,
924 std::vector<int64_t>* optimal_costs_without_transits,
925 std::vector<std::vector<int64_t>>* optimal_cumuls,
926 std::vector<std::vector<int64_t>>* optimal_breaks);
934 int vehicle,
double solve_duration_ratio,
935 const std::function<int64_t(int64_t)>& next_accessor,
936 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
937 const RoutingModel::ResourceGroup::Resource* resource,
938 std::vector<int64_t>* optimal_cumuls,
939 std::vector<int64_t>* optimal_breaks);
944 int vehicle,
double solve_duration_ratio,
945 const std::function<int64_t(int64_t)>& next_accessor,
946 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
947 std::vector<int64_t>* optimal_cumuls,
948 std::vector<int64_t>* optimal_breaks,
949 int64_t* optimal_cost_without_transits);
954 int vehicle,
double solve_duration_ratio,
955 const std::function<int64_t(int64_t)>& next_accessor,
956 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
957 absl::Span<const int64_t> solution_cumul_values,
958 absl::Span<const int64_t> solution_break_values, int64_t* solution_cost,
959 int64_t* cost_offset =
nullptr,
960 bool reuse_previous_model_if_possible =
false,
bool clear_lp =
true,
961 absl::Duration* solve_duration =
nullptr);
969 int vehicle,
double solve_duration_ratio,
970 const std::function<int64_t(int64_t)>& next_accessor,
971 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
972 const RoutingModel::ResourceGroup::Resource* resource,
973 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks);
976 return optimizer_core_.dimension();
980 std::vector<std::unique_ptr<RoutingLinearSolverWrapper>> solver_;
988 RoutingSearchParameters::SchedulingSolver solver_type);
995 const std::function<int64_t(int64_t)>& next_accessor,
996 int64_t* optimal_cost_without_transits);
1003 const std::function<int64_t(int64_t)>& next_accessor,
1004 const std::vector<RoutingModel::RouteDimensionTravelInfo>&
1005 dimension_travel_info_per_route,
1006 std::vector<int64_t>* optimal_cumuls,
1007 std::vector<int64_t>* optimal_breaks,
1008 std::vector<std::vector<int>>* optimal_resource_indices_per_group);
1017 const std::function<int64_t(int64_t)>& next_accessor,
1018 const std::vector<RoutingModel::RouteDimensionTravelInfo>&
1019 dimension_travel_info_per_route,
1020 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks);
1023 return optimizer_core_.dimension();
1027 std::unique_ptr<RoutingLinearSolverWrapper> solver_;
1050 absl::Span<const int> vehicles,
1053 resource_indices_per_class,
1055 absl::flat_hash_set<int>>&
1056 ignored_resources_per_class,
1057 std::function<
const std::vector<int64_t>*(
int)>
1058 vehicle_to_resource_class_assignment_costs,
1059 std::vector<int>* resource_indices);
1071 int v,
double solve_duration_ratio,
1072 const RoutingModel::ResourceGroup& resource_group,
1074 absl::flat_hash_set<int>>&
1075 ignored_resources_per_class,
1076 const std::function<int64_t(int64_t)>& next_accessor,
1077 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
1078 bool optimize_vehicle_costs, LocalDimensionCumulOptimizer* lp_optimizer,
1079 LocalDimensionCumulOptimizer* mp_optimizer,
1080 std::vector<int64_t>* assignment_costs,
1081 std::vector<std::vector<int64_t>>* cumul_values,
1082 std::vector<std::vector<int64_t>>* break_values);
1103 const FloatSlopePiecewiseLinearFunction& pwl_function,
int index_start = 0,
1104 int index_end = -1);
1113 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)
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)
GlobalDimensionCumulOptimizer.
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)
LocalDimensionCumulOptimizer.
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)
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 int64_t FastInt64Round(double 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
double GetValue(int index) const 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
Prints an understandable view of the model.
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
int64_t GetVariableLowerBound(int index) const override
bool ModelIsEmpty() const override
Returns if the model is empty or not.
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
double GetValue(int index) const override
double GetObjectiveCoefficient(int index) const override
int CreateNewPositiveVariable() override
RoutingGlopWrapper(bool is_relaxation, const glop::GlopParameters ¶meters)
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
This function is meant to override the parameters of the solver.
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
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
Prints an understandable view of the model.
virtual double GetValue(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
This function is meant to override the parameters of the solver.
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
Returns if the model is empty or not.
virtual int64_t GetVariableLowerBound(int index) const =0
virtual bool IsCPSATSolver()=0
virtual double GetObjectiveCoefficient(int index) const =0
int AddVariable(int64_t lower_bound, int64_t upper_bound)
Adds a variable with bounds [lower_bound, upper_bound].
Iterator FirstIntervalGreaterOrEqual(int64_t value) const
ConstIterator end() const
A full-fledged linear programming solver.
T Add(std::function< T(Model *)> f)
constexpr double kInfinity
Infinity for type Fractional.
ProblemStatus
Different statuses for a given problem.
std::function< SatParameters(Model *)> NewSatParameters(const std::string ¶ms)
CpSolverResponse SolveCpModel(const CpModelProto &model_proto, Model *model)
In SWIG mode, we don't want anything besides these top-level includes.
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
@ INFEASIBLE
A solution could not be found.
@ FEASIBLE
Only a feasible solution was found, optimality was not proven.
@ OPTIMAL
An optimal solution was found respecting all constraints.
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)
friend::std::ostream & operator<<(::std::ostream &os, const SlopeAndYIntercept &it)