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"
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(),
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);
479 parameters_.set_linearization_level(2);
480 parameters_.set_cut_level(0);
481 parameters_.set_add_lp_constraints_lazily(
false);
482 parameters_.set_use_absl_random(
false);
488 objective_coefficients_.clear();
489 schedule_variables_.clear();
492 const int index = model_.variables_size();
495 variable->
add_domain(
static_cast<int64_t
>(parameters_.mip_max_bound()));
499 model_.mutable_variables(index)->set_name(name.data());
502 int64_t upper_bound)
override {
503 DCHECK_GE(lower_bound, 0);
504 const int64_t capped_upper_bound =
505 std::min<int64_t>(upper_bound, parameters_.mip_max_bound());
506 if (lower_bound > capped_upper_bound)
return false;
513 const std::vector<int64_t>& ends)
override {
514 DCHECK_EQ(starts.size(), ends.size());
516 for (
int i = 0; i < starts.size(); ++i) {
520 absl::StrFormat(
"disjoint(%ld, %ld)", index, i));
526 model_.mutable_constraints(window_ct)->add_enforcement_literal(variable);
530 return model_.variables(index).domain(0);
533 const auto& domain = model_.variables(index).domain();
534 return domain[domain.size() - 1];
537 if (index >= objective_coefficients_.size()) {
538 objective_coefficients_.resize(index + 1, 0);
540 objective_coefficients_[index] = coefficient;
542 model_.mutable_floating_point_objective();
547 return (index < objective_coefficients_.size())
548 ? objective_coefficients_[index]
552 model_.mutable_floating_point_objective()->Clear();
557 model_.add_constraints()->mutable_linear();
560 return model_.constraints_size() - 1;
564 model_.mutable_constraints(ct_index)->mutable_linear();
566 const int64_t integer_coefficient = coefficient;
572 int64_t activity = 0;
573 for (
int i = 0; i < objective.
vars_size(); ++i) {
574 activity += response_.solution(objective.
vars(i)) * objective.
coeffs(i);
578 for (
int i = 0; i < objective.
vars_size(); ++i) {
581 model_.clear_objective();
585 model_.add_constraints()->mutable_lin_max();
588 for (
const int var : vars) {
596 model_.add_constraints()->mutable_int_prod();
599 for (
const int var : vars) {
606 DCHECK_LT(ct, model_.constraints_size());
607 model_.mutable_constraints(ct)->add_enforcement_literal(condition);
610 absl::Span<const int> schedule_variables)
override {
611 DCHECK_EQ(nodes.size(), schedule_variables.size());
612 for (
const int64_t node : nodes) {
613 if (node >= schedule_hint_.size()) schedule_hint_.resize(node + 1, 0);
615 for (
int n = 0; n < nodes.size(); ++n) {
616 schedule_variables_.push_back(
617 {.node = nodes[n], .cumul = schedule_variables[n]});
621 const double max_time = absl::ToDoubleSeconds(duration_limit);
623 parameters_.set_max_time_in_seconds(max_time);
625 auto record_hint = [
this]() {
627 for (
int i = 0; i < response_.solution_size(); ++i) {
629 hint_.add_values(response_.solution(i));
631 for (
const auto& [node, cumul] : schedule_variables_) {
632 schedule_hint_[node] = response_.solution(cumul);
635 model_.clear_solution_hint();
636 auto* hint = model_.mutable_solution_hint();
637 if (hint_.vars_size() == model_.variables_size()) {
640 for (
const auto& [node, cumul] : schedule_variables_) {
641 if (schedule_hint_[node] == 0)
continue;
642 hint->add_vars(cumul);
643 hint->add_values(schedule_hint_[node]);
649 VLOG(2) << response_;
653 !model_.has_floating_point_objective())) {
667 return response_.solution(index);
676 bool ModelIsEmpty()
const override {
return model_.ByteSizeLong() == 0; }
685 std::vector<double> objective_coefficients_;
687 struct NodeAndCumul {
692 std::vector<NodeAndCumul> schedule_variables_;
694 std::vector<int64_t> schedule_hint_;
700 using RouteDimensionTravelInfo = RoutingModel::RouteDimensionTravelInfo;
701 using Resource = RoutingModel::ResourceGroup::Resource;
705 bool use_precedence_propagator);
710 int vehicle,
double solve_duration_ratio,
711 const std::function<int64_t(int64_t)>& next_accessor,
712 const RouteDimensionTravelInfo* dimension_travel_info,
713 const Resource* resource,
bool optimize_vehicle_costs,
715 std::vector<int64_t>* break_values, int64_t* cost_without_transit,
716 int64_t* transit_cost,
bool clear_lp =
true);
722 int vehicle,
double solve_duration_ratio,
723 const std::function<int64_t(int64_t)>& next_accessor,
724 const RouteDimensionTravelInfo* dimension_travel_info,
726 absl::Span<const int64_t> solution_cumul_values,
727 absl::Span<const int64_t> solution_break_values,
728 int64_t* cost_without_transits, int64_t* cost_offset =
nullptr,
729 bool reuse_previous_model_if_possible =
true,
bool clear_lp =
false,
730 bool clear_solution_constraints =
true,
731 absl::Duration* solve_duration =
nullptr);
738 int vehicle,
double solve_duration_ratio,
739 const std::function<int64_t(int64_t)>& next_accessor,
740 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
741 const RouteDimensionTravelInfo* dimension_travel_info,
742 absl::Span<const Resource> resources,
743 absl::Span<const int> resource_indices,
bool optimize_vehicle_costs,
745 std::vector<std::vector<int64_t>>* cumul_values,
746 std::vector<std::vector<int64_t>>* break_values,
747 std::vector<int64_t>* costs_without_transits, int64_t* transit_cost,
748 bool clear_lp =
true);
756 const std::function<int64_t(int64_t)>& next_accessor,
757 const std::vector<RouteDimensionTravelInfo>&
758 dimension_travel_info_per_route,
760 std::vector<int64_t>* break_values,
761 std::vector<std::vector<int>>* resource_indices_per_group,
762 int64_t* cost_without_transits, int64_t* transit_cost,
763 bool clear_lp =
true,
bool optimize_resource_assignment =
true);
766 const std::function<int64_t(int64_t)>& next_accessor,
767 const std::vector<RouteDimensionTravelInfo>&
768 dimension_travel_info_per_route,
770 std::vector<int64_t>* break_values);
773 int vehicle,
double solve_duration_ratio,
774 const std::function<int64_t(int64_t)>& next_accessor,
775 const RouteDimensionTravelInfo* dimension_travel_info,
777 std::vector<int64_t>* cumul_values, std::vector<int64_t>* break_values);
779 const RoutingDimension*
dimension()
const {
return dimension_; }
788 bool ExtractRouteCumulBounds(absl::Span<const int64_t> route,
789 int64_t cumul_offset);
794 bool TightenRouteCumulBounds(absl::Span<const int64_t> route,
795 absl::Span<const int64_t> min_transits,
796 int64_t cumul_offset);
802 bool SetRouteCumulConstraints(
803 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
804 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
805 const RouteDimensionTravelInfo* dimension_travel_info,
806 int64_t cumul_offset,
bool optimize_costs,
808 int64_t* route_cost_offset);
813 bool SetRouteTravelConstraints(
814 const RouteDimensionTravelInfo* dimension_travel_info,
815 absl::Span<const int> lp_slacks, absl::Span<const int64_t> fixed_transit,
825 bool SetGlobalConstraints(
826 const std::function<int64_t(int64_t)>& next_accessor,
827 int64_t cumul_offset,
bool optimize_costs,
830 bool SetGlobalConstraintsForResourceAssignment(
831 const std::function<int64_t(int64_t)>& next_accessor,
834 void SetValuesFromLP(absl::Span<const int> lp_variables, int64_t offset,
836 std::vector<int64_t>* lp_values)
const;
838 void SetResourceIndices(
840 std::vector<std::vector<int>>* resource_indices_per_group)
const;
849 std::vector<int> vehicles,
double solve_duration_ratio,
853 std::unique_ptr<CumulBoundsPropagator> propagator_;
854 std::vector<int64_t> current_route_min_cumuls_;
855 std::vector<int64_t> current_route_max_cumuls_;
856 const RoutingDimension*
const dimension_;
858 std::vector<int> current_route_cumul_variables_;
859 std::vector<int> index_to_cumul_variable_;
864 std::vector<int> current_route_break_variables_;
868 std::vector<int> all_break_variables_;
872 std::vector<int> vehicle_to_all_break_variables_offset_;
877 std::vector<std::vector<int>>
878 resource_class_to_vehicle_assignment_variables_per_group_;
881 std::vector<std::vector<absl::flat_hash_set<int>>>
882 resource_class_ignored_resources_per_group_;
885 int min_start_cumul_;
886 std::vector<std::pair<int64_t, int64_t>>
887 visited_pickup_delivery_indices_for_pair_;
906 int vehicle,
double solve_duration_ratio,
907 const std::function<int64_t(int64_t)>& next_accessor,
908 int64_t* optimal_cost);
913 int vehicle,
double solve_duration_ratio,
914 const std::function<int64_t(int64_t)>& next_accessor,
915 const RoutingModel::ResourceGroup::Resource* resource,
916 int64_t* optimal_cost_without_transits);
918 std::vector<DimensionSchedulingStatus>
920 int vehicle,
double solve_duration_ratio,
921 const std::function<int64_t(int64_t)>& next_accessor,
922 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
923 absl::Span<const RoutingModel::ResourceGroup::Resource> resources,
924 absl::Span<const int> resource_indices,
bool optimize_vehicle_costs,
925 std::vector<int64_t>* optimal_costs_without_transits,
926 std::vector<std::vector<int64_t>>* optimal_cumuls,
927 std::vector<std::vector<int64_t>>* optimal_breaks);
935 int vehicle,
double solve_duration_ratio,
936 const std::function<int64_t(int64_t)>& next_accessor,
937 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
938 const RoutingModel::ResourceGroup::Resource* resource,
939 std::vector<int64_t>* optimal_cumuls,
940 std::vector<int64_t>* optimal_breaks);
945 int vehicle,
double solve_duration_ratio,
946 const std::function<int64_t(int64_t)>& next_accessor,
947 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
948 std::vector<int64_t>* optimal_cumuls,
949 std::vector<int64_t>* optimal_breaks,
950 int64_t* optimal_cost_without_transits);
955 int vehicle,
double solve_duration_ratio,
956 const std::function<int64_t(int64_t)>& next_accessor,
957 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
958 absl::Span<const int64_t> solution_cumul_values,
959 absl::Span<const int64_t> solution_break_values, int64_t* solution_cost,
960 int64_t* cost_offset =
nullptr,
961 bool reuse_previous_model_if_possible =
false,
bool clear_lp =
true,
962 absl::Duration* solve_duration =
nullptr);
970 int vehicle,
double solve_duration_ratio,
971 const std::function<int64_t(int64_t)>& next_accessor,
972 const RoutingModel::RouteDimensionTravelInfo* dimension_travel_info,
973 const RoutingModel::ResourceGroup::Resource* resource,
974 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks);
977 return optimizer_core_.dimension();
981 std::vector<std::unique_ptr<RoutingLinearSolverWrapper>> solver_;
996 const std::function<int64_t(int64_t)>& next_accessor,
997 int64_t* optimal_cost_without_transits);
1004 const std::function<int64_t(int64_t)>& next_accessor,
1005 const std::vector<RoutingModel::RouteDimensionTravelInfo>&
1006 dimension_travel_info_per_route,
1007 std::vector<int64_t>* optimal_cumuls,
1008 std::vector<int64_t>* optimal_breaks,
1009 std::vector<std::vector<int>>* optimal_resource_indices_per_group);
1018 const std::function<int64_t(int64_t)>& next_accessor,
1019 const std::vector<RoutingModel::RouteDimensionTravelInfo>&
1020 dimension_travel_info_per_route,
1021 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks);
1024 return optimizer_core_.dimension();
1028 std::unique_ptr<RoutingLinearSolverWrapper> solver_;
1051 absl::Span<const int> vehicles,
1054 resource_indices_per_class,
1056 absl::flat_hash_set<int>>&
1057 ignored_resources_per_class,
1058 std::function<
const std::vector<int64_t>*(
int)>
1059 vehicle_to_resource_class_assignment_costs,
1060 std::vector<int>* resource_indices);
1072 int v,
double solve_duration_ratio,
1073 const RoutingModel::ResourceGroup& resource_group,
1075 absl::flat_hash_set<int>>&
1076 ignored_resources_per_class,
1077 const std::function<int64_t(int64_t)>& next_accessor,
1078 const std::function<int64_t(int64_t, int64_t)>& transit_accessor,
1079 bool optimize_vehicle_costs, LocalDimensionCumulOptimizer* lp_optimizer,
1080 LocalDimensionCumulOptimizer* mp_optimizer,
1081 std::vector<int64_t>* assignment_costs,
1082 std::vector<std::vector<int64_t>>* cumul_values,
1083 std::vector<std::vector<int64_t>>* break_values);
1104 const FloatSlopePiecewiseLinearFunction& pwl_function,
int index_start = 0,
1105 int index_end = -1);
1114 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].
RoutingSearchParameters_SchedulingSolver SchedulingSolver
Iterator FirstIntervalGreaterOrEqual(int64_t value) const
ConstIterator end() const
A full-fledged linear programming solver.
int vars_size() const
repeated int32 vars = 1;
::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
Infinity for type Fractional.
ProblemStatus
Different statuses for a given problem.
std::function< SatParameters(Model *)> NewSatParameters(absl::string_view params)
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)