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/memory/memory.h" 30 #include "absl/time/time.h" 31 #include "ortools/base/logging.h" 32 #include "ortools/base/mathutil.h" 35 #include "ortools/glop/lp_solver.h" 36 #include "ortools/glop/parameters.pb.h" 37 #include "ortools/lp_data/lp_data.h" 38 #include "ortools/lp_data/lp_types.h" 39 #include "ortools/sat/cp_model.pb.h" 40 #include "ortools/sat/cp_model_solver.h" 41 #include "ortools/sat/lp_utils.h" 42 #include "ortools/sat/model.h" 43 #include "ortools/sat/sat_parameters.pb.h" 44 #include "ortools/util/saturated_arithmetic.h" 45 #include "ortools/util/sorted_interval_list.h" 65 const std::function<int64_t(int64_t)>& next_accessor,
66 int64_t cumul_offset);
69 return propagated_bounds_[PositiveNode(index)];
73 const int64_t negated_upper_bound = propagated_bounds_[NegativeNode(index)];
74 return negated_upper_bound == std::numeric_limits<int64_t>::min()
75 ? std::numeric_limits<int64_t>::max()
76 : -negated_upper_bound;
89 static const int kNoParent;
90 static const int kParentToBePropagated;
94 int PositiveNode(
int index)
const {
return 2 * index; }
95 int NegativeNode(
int index)
const {
return 2 * index + 1; }
97 void AddNodeToQueue(
int node) {
98 if (!node_in_queue_[node]) {
99 bf_queue_.push_back(node);
100 node_in_queue_[node] =
true;
107 void AddArcs(
int first_index,
int second_index, int64_t offset);
109 bool InitializeArcsAndBounds(
110 const std::function<int64_t(int64_t)>& next_accessor,
111 int64_t cumul_offset);
113 bool UpdateCurrentLowerBoundOfNode(
int node, int64_t new_lb, int64_t offset);
115 bool DisassembleSubtree(
int source,
int target);
117 bool CleanupAndReturnFalse() {
119 for (
int node_to_cleanup : bf_queue_) {
120 node_in_queue_[node_to_cleanup] =
false;
126 const RoutingDimension& dimension_;
127 const int64_t num_nodes_;
132 std::vector<std::vector<ArcInfo>> outgoing_arcs_;
134 std::deque<int> bf_queue_;
135 std::vector<bool> node_in_queue_;
136 std::vector<int> tree_parent_node_of_;
140 std::vector<int64_t> propagated_bounds_;
143 std::vector<int> tmp_dfs_stack_;
146 std::vector<std::pair<int64_t, int64_t>>
147 visited_pickup_delivery_indices_for_pair_;
163 virtual void Clear() = 0;
166 int64_t upper_bound) = 0;
168 const std::vector<int64_t>& starts,
169 const std::vector<int64_t>& ends) = 0;
177 virtual void SetCoefficient(
int ct,
int index,
double coefficient) = 0;
185 virtual double GetValue(
int index)
const = 0;
190 CHECK_LE(lower_bound, upper_bound);
199 int64_t lower_bound, int64_t upper_bound,
200 const std::vector<std::pair<int, double>>& variable_coeffs) {
201 CHECK_LE(lower_bound, upper_bound);
203 for (
const auto& variable_coeff : variable_coeffs) {
212 int64_t lower_bound, int64_t upper_bound,
213 const std::vector<std::pair<int, double>>& weighted_variables) {
215 if (std::numeric_limits<int64_t>::min() < lower_bound) {
218 const int under_lower_bound_ct =
220 lower_bound - 1, weighted_variables);
223 if (upper_bound < std::numeric_limits<int64_t>::max()) {
227 upper_bound + 1, std::numeric_limits<int64_t>::max(),
233 const int within_bounds_ct =
236 return within_bounds;
243 : is_relaxation_(is_relaxation) {
244 lp_solver_.SetParameters(parameters);
245 linear_program_.SetMaximizationProblem(
false);
248 linear_program_.Clear();
249 linear_program_.SetMaximizationProblem(
false);
250 allowed_intervals_.clear();
253 return linear_program_.CreateNewVariable().value();
256 int64_t upper_bound)
override {
257 DCHECK_GE(lower_bound, 0);
261 const int64_t kMaxValue = 1e10;
262 const double lp_min = lower_bound;
263 const double lp_max =
264 (upper_bound > kMaxValue) ? glop::kInfinity : upper_bound;
265 if (lp_min <= lp_max) {
266 linear_program_.SetVariableBounds(glop::ColIndex(index), lp_min, lp_max);
274 const std::vector<int64_t>& ends)
override {
279 allowed_intervals_[index] =
280 absl::make_unique<SortedDisjointIntervalList>(starts, ends);
283 return linear_program_.variable_lower_bounds()[glop::ColIndex(index)];
286 const double upper_bound =
287 linear_program_.variable_upper_bounds()[glop::ColIndex(index)];
288 DCHECK_GE(upper_bound, 0);
289 return upper_bound == glop::kInfinity ? std::numeric_limits<int64_t>::max()
290 : static_cast<int64_t>(upper_bound);
293 linear_program_.SetObjectiveCoefficient(glop::ColIndex(index), coefficient);
296 return linear_program_.objective_coefficients()[glop::ColIndex(index)];
299 for (glop::ColIndex i(0); i < linear_program_.num_variables(); ++i) {
300 linear_program_.SetObjectiveCoefficient(i, 0);
304 return linear_program_.num_variables().value();
307 const glop::RowIndex ct = linear_program_.CreateNewConstraint();
308 linear_program_.SetConstraintBounds(
310 (lower_bound == std::numeric_limits<int64_t>::min()) ? -glop::kInfinity
312 (upper_bound == std::numeric_limits<int64_t>::max()) ? glop::kInfinity
317 linear_program_.SetCoefficient(glop::RowIndex(ct), glop::ColIndex(index),
323 for (
int variable = 0; variable <
NumVariables(); variable++) {
325 if (coefficient != 0) {
334 lp_solver_.GetMutableParameters()->set_max_time_in_seconds(
335 absl::ToDoubleSeconds(duration_limit));
342 linear_program_.NotifyThatColumnsAreClean();
343 VLOG(2) << linear_program_.Dump();
344 const glop::ProblemStatus status = lp_solver_.Solve(linear_program_);
345 if (status != glop::ProblemStatus::OPTIMAL &&
346 status != glop::ProblemStatus::IMPRECISE) {
349 if (is_relaxation_) {
352 for (
const auto& allowed_interval : allowed_intervals_) {
353 const double value_double =
GetValue(allowed_interval.first);
354 const int64_t value =
355 (value_double >= std::numeric_limits<int64_t>::max())
356 ? std::numeric_limits<int64_t>::max()
357 : MathUtil::FastInt64Round(value_double);
358 const SortedDisjointIntervalList*
const interval_list =
359 allowed_interval.second.get();
360 const auto it = interval_list->FirstIntervalGreaterOrEqual(value);
361 if (it == interval_list->end() || value < it->start) {
368 return MathUtil::FastInt64Round(lp_solver_.GetObjectiveValue());
371 return lp_solver_.variable_values()[glop::ColIndex(index)];
374 return linear_program_.SolutionIsInteger(lp_solver_.variable_values(),
379 const bool is_relaxation_;
380 glop::LinearProgram linear_program_;
381 glop::LPSolver lp_solver_;
382 absl::flat_hash_map<int, std::unique_ptr<SortedDisjointIntervalList>>
389 parameters_.set_num_search_workers(1);
392 parameters_.set_cp_model_presolve(
true);
393 parameters_.set_max_presolve_iterations(0);
394 parameters_.set_catch_sigint_signal(
false);
395 parameters_.set_mip_max_bound(1e8);
396 parameters_.set_search_branching(sat::SatParameters::LP_SEARCH);
402 objective_coefficients_.clear();
405 const int index = model_.variables_size();
406 sat::IntegerVariableProto*
const variable = model_.add_variables();
407 variable->add_domain(0);
408 variable->add_domain(static_cast<int64_t>(parameters_.mip_max_bound()));
412 int64_t upper_bound)
override {
413 DCHECK_GE(lower_bound, 0);
414 const int64_t capped_upper_bound =
415 std::min<int64_t>(upper_bound, parameters_.mip_max_bound());
416 if (lower_bound > capped_upper_bound)
return false;
417 sat::IntegerVariableProto*
const variable = model_.mutable_variables(index);
418 variable->set_domain(0, lower_bound);
419 variable->set_domain(1, capped_upper_bound);
423 const std::vector<int64_t>& ends)
override {
424 DCHECK_EQ(starts.size(), ends.size());
426 for (
int i = 0; i < starts.size(); ++i) {
432 model_.mutable_constraints(window_ct)->add_enforcement_literal(variable);
436 return model_.variables(index).domain(0);
439 const auto& domain = model_.variables(index).domain();
440 return domain[domain.size() - 1];
443 if (index >= objective_coefficients_.size()) {
444 objective_coefficients_.resize(index + 1, 0);
446 objective_coefficients_[index] = coefficient;
447 sat::FloatObjectiveProto*
const objective =
448 model_.mutable_floating_point_objective();
449 objective->add_vars(index);
450 objective->add_coeffs(coefficient);
453 return (index < objective_coefficients_.size())
454 ? objective_coefficients_[index]
458 model_.mutable_floating_point_objective()->Clear();
462 sat::LinearConstraintProto*
const ct =
463 model_.add_constraints()->mutable_linear();
464 ct->add_domain(lower_bound);
465 ct->add_domain(upper_bound);
466 return model_.constraints_size() - 1;
469 sat::LinearConstraintProto*
const ct =
470 model_.mutable_constraints(ct_index)->mutable_linear();
472 const int64_t integer_coefficient = coefficient;
473 ct->add_coeffs(integer_coefficient);
478 const sat::FloatObjectiveProto& fp_objective =
479 model_.floating_point_objective();
480 std::vector<std::pair<int, double>> terms;
481 for (
int i = 0; i < fp_objective.vars_size(); ++i) {
482 terms.push_back({fp_objective.vars(i), fp_objective.coeffs(i)});
486 sat::ScaleAndSetObjective(parameters_, terms, fp_objective.offset(),
487 fp_objective.maximize(), &model_, &logger);
489 const sat::CpObjectiveProto& objective = model_.objective();
490 int64_t activity = 0;
491 for (
int i = 0; i < objective.vars_size(); ++i) {
492 activity += response_.solution(objective.vars(i)) * objective.coeffs(i);
495 for (
int i = 0; i < objective.vars_size(); ++i) {
498 model_.clear_objective();
501 sat::LinearArgumentProto*
const ct =
502 model_.add_constraints()->mutable_lin_max();
503 ct->mutable_target()->add_vars(max_var);
504 ct->mutable_target()->add_coeffs(1);
505 for (
const int var : vars) {
506 sat::LinearExpressionProto*
const expr = ct->add_exprs();
512 sat::LinearArgumentProto*
const ct =
513 model_.add_constraints()->mutable_int_prod();
514 ct->mutable_target()->add_vars(product_var);
515 ct->mutable_target()->add_coeffs(1);
516 for (
const int var : vars) {
517 sat::LinearExpressionProto* expr = ct->add_exprs();
523 DCHECK_LT(ct, model_.constraints_size());
524 model_.mutable_constraints(ct)->add_enforcement_literal(condition);
527 parameters_.set_max_time_in_seconds(absl::ToDoubleSeconds(duration_limit));
528 VLOG(2) << model_.DebugString();
529 if (hint_.vars_size() == model_.variables_size()) {
530 *model_.mutable_solution_hint() = hint_;
533 model.Add(sat::NewSatParameters(parameters_));
534 response_ = sat::SolveCpModel(model_, &model);
535 VLOG(2) << response_.DebugString();
536 if (response_.status() == sat::CpSolverStatus::OPTIMAL ||
537 (response_.status() == sat::CpSolverStatus::FEASIBLE &&
538 !model_.has_floating_point_objective())) {
540 for (
int i = 0; i < response_.solution_size(); ++i) {
542 hint_.add_values(response_.solution(i));
549 return MathUtil::FastInt64Round(response_.objective_value());
552 return response_.solution(index);
557 sat::CpModelProto model_;
558 sat::CpSolverResponse response_;
559 sat::SatParameters parameters_;
560 std::vector<double> objective_coefficients_;
561 sat::PartialVariableAssignment hint_;
569 bool use_precedence_propagator);
576 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
578 std::vector<int64_t>* break_values, int64_t* cost, int64_t* transit_cost,
579 bool clear_lp =
true);
582 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
583 const std::vector<RoutingModel::ResourceGroup::Resource>& resources,
584 const std::vector<int>& resource_indices,
bool optimize_vehicle_costs,
586 std::vector<int64_t>* costs_without_transits,
587 std::vector<std::vector<int64_t>>* cumul_values,
588 std::vector<std::vector<int64_t>>* break_values,
bool clear_lp =
true);
591 const std::function<int64_t(int64_t)>& next_accessor,
593 std::vector<int64_t>* break_values,
594 std::vector<std::vector<int>>* resource_indices_per_group, int64_t* cost,
595 int64_t* transit_cost,
bool clear_lp =
true);
598 const std::function<int64_t(int64_t)>& next_accessor,
600 std::vector<int64_t>* break_values,
601 std::vector<std::vector<int>>* resource_indices_per_group);
604 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
607 std::vector<int64_t>* break_values);
622 bool ComputeRouteCumulBounds(
const std::vector<int64_t>& route,
623 const std::vector<int64_t>& fixed_transits,
624 int64_t cumul_offset);
630 bool SetRouteCumulConstraints(
631 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
632 int64_t cumul_offset,
bool optimize_costs,
634 int64_t* route_cost_offset);
643 bool SetGlobalConstraints(
644 const std::function<int64_t(int64_t)>& next_accessor,
645 int64_t cumul_offset,
bool optimize_costs,
648 void SetValuesFromLP(
const std::vector<int>& lp_variables, int64_t offset,
650 std::vector<int64_t>* lp_values)
const;
652 void SetResourceIndices(
654 std::vector<std::vector<int>>* resource_indices_per_group)
const;
665 std::unique_ptr<CumulBoundsPropagator> propagator_;
666 std::vector<int64_t> current_route_min_cumuls_;
667 std::vector<int64_t> current_route_max_cumuls_;
670 std::vector<int> current_route_cumul_variables_;
671 std::vector<int> index_to_cumul_variable_;
676 std::vector<int> current_route_break_variables_;
680 std::vector<int> all_break_variables_;
684 std::vector<int> vehicle_to_all_break_variables_offset_;
689 std::vector<std::vector<int>>
690 resource_group_to_resource_to_vehicle_assignment_variables_;
693 int min_start_cumul_;
694 std::vector<std::pair<int64_t, int64_t>>
695 visited_pickup_delivery_indices_for_pair_;
714 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
715 int64_t* optimal_cost);
720 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
721 int64_t* optimal_cost_without_transits);
723 std::vector<DimensionSchedulingStatus>
725 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
726 const std::vector<RoutingModel::ResourceGroup::Resource>& resources,
727 const std::vector<int>& resource_indices,
bool optimize_vehicle_costs,
728 std::vector<int64_t>* optimal_costs_without_transits,
729 std::vector<std::vector<int64_t>>* optimal_cumuls,
730 std::vector<std::vector<int64_t>>* optimal_breaks);
738 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
739 std::vector<int64_t>* optimal_cumuls,
740 std::vector<int64_t>* optimal_breaks);
748 int vehicle,
const std::function<int64_t(int64_t)>& next_accessor,
750 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks);
757 std::vector<std::unique_ptr<RoutingLinearSolverWrapper>> solver_;
772 const std::function<int64_t(int64_t)>& next_accessor,
773 int64_t* optimal_cost_without_transits);
780 const std::function<int64_t(int64_t)>& next_accessor,
781 std::vector<int64_t>* optimal_cumuls,
782 std::vector<int64_t>* optimal_breaks,
783 std::vector<std::vector<int>>* optimal_resource_indices_per_group);
789 const std::function<int64_t(int64_t)>& next_accessor,
790 std::vector<int64_t>* packed_cumuls, std::vector<int64_t>* packed_breaks,
791 std::vector<std::vector<int>>* resource_indices_per_group);
798 std::unique_ptr<RoutingLinearSolverWrapper> solver_;
818 const std::vector<std::vector<int64_t>>&
819 primary_vehicle_to_resource_assignment_costs,
820 const std::vector<std::vector<int64_t>>&
821 secondary_vehicle_to_resource_assignment_costs,
822 const std::function<
bool(
int)>& use_primary_for_vehicle,
823 std::vector<int>* resource_indices)
const;
834 int v,
const std::function<int64_t(int64_t)>& next_accessor,
835 bool optimize_vehicle_costs, std::vector<int64_t>* assignment_costs,
836 std::vector<std::vector<int64_t>>* cumul_values,
837 std::vector<std::vector<int64_t>>* break_values);
852 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_LP_SCHEDULING_H_ ~RoutingCPSatWrapper() override
int64_t GetVariableUpperBound(int index) const override
int AddLinearConstraint(int64_t lower_bound, int64_t upper_bound, const std::vector< std::pair< int, double >> &variable_coeffs)
DimensionSchedulingStatus ComputeRouteCumulCostWithoutFixedTransits(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, int64_t *optimal_cost_without_transits)
DimensionSchedulingStatus OptimizeAndPackSingleRoute(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, const RoutingModel::ResourceGroup::Resource *resource, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *cumul_values, std::vector< int64_t > *break_values)
DimensionSchedulingStatus Solve(absl::Duration duration_limit) override
void ClearObjective() override
virtual double GetObjectiveCoefficient(int index) const =0
int NumVariables() const override
bool IsCPSATSolver() override
bool IsCPSATSolver() override
virtual ~RoutingLinearSolverWrapper()
void SetCoefficient(int ct, int index, double coefficient) override
DimensionSchedulingStatus ComputeCumuls(const std::function< int64_t(int64_t)> &next_accessor, std::vector< int64_t > *optimal_cumuls, std::vector< int64_t > *optimal_breaks, std::vector< std::vector< int >> *optimal_resource_indices_per_group)
virtual double GetValue(int index) const =0
virtual bool SetVariableBounds(int index, int64_t lower_bound, int64_t upper_bound)=0
void SetCoefficient(int ct_index, int index, double coefficient) override
int AddReifiedLinearConstraint(int64_t lower_bound, int64_t upper_bound, const std::vector< std::pair< int, double >> &weighted_variables)
virtual void SetObjectiveCoefficient(int index, double coefficient)=0
int CreateNewPositiveVariable() override
void SetVariableDisjointBounds(int index, const std::vector< int64_t > &starts, const std::vector< int64_t > &ends) override
DimensionSchedulingStatus
virtual int64_t GetVariableUpperBound(int index) const =0
Dimensions represent quantities accumulated at nodes along the routes.
std::vector< DimensionSchedulingStatus > OptimizeSingleRouteWithResources(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, const std::vector< RoutingModel::ResourceGroup::Resource > &resources, const std::vector< int > &resource_indices, bool optimize_vehicle_costs, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *costs_without_transits, std::vector< std::vector< int64_t >> *cumul_values, std::vector< std::vector< int64_t >> *break_values, bool clear_lp=true)
double GetValue(int index) const override
virtual void AddProductConstraint(int product_var, std::vector< int > vars)=0
virtual void SetCoefficient(int ct, int index, double coefficient)=0
int64_t GetVariableLowerBound(int index) const override
const RoutingDimension & dimension() const
int64_t ComputeBestAssignmentCost(const std::vector< std::vector< int64_t >> &primary_vehicle_to_resource_assignment_costs, const std::vector< std::vector< int64_t >> &secondary_vehicle_to_resource_assignment_costs, const std::function< bool(int)> &use_primary_for_vehicle, std::vector< int > *resource_indices) const
ResourceAssignmentOptimizer(const RoutingModel::ResourceGroup *resource_group, LocalDimensionCumulOptimizer *optimizer, LocalDimensionCumulOptimizer *mp_optimizer)
virtual void AddMaximumConstraint(int max_var, std::vector< int > vars)=0
DimensionSchedulingStatus ComputeCumulCostWithoutFixedTransits(const std::function< int64_t(int64_t)> &next_accessor, int64_t *optimal_cost_without_transits)
virtual int64_t GetObjectiveValue() const =0
const RoutingDimension *const dimension() const
DimensionSchedulingStatus ComputePackedRouteCumuls(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, const RoutingModel::ResourceGroup::Resource *resource, std::vector< int64_t > *packed_cumuls, std::vector< int64_t > *packed_breaks)
bool SolutionIsInteger() const override
int64_t GetObjectiveValue() const override
int64_t CumulMin(int index) const
A Resource sets attributes (costs/constraints) for a set of dimensions.
DimensionSchedulingStatus ComputePackedCumuls(const std::function< int64_t(int64_t)> &next_accessor, std::vector< int64_t > *packed_cumuls, std::vector< int64_t > *packed_breaks, std::vector< std::vector< int >> *resource_indices_per_group)
DimensionSchedulingStatus OptimizeAndPack(const std::function< int64_t(int64_t)> &next_accessor, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *cumul_values, std::vector< int64_t > *break_values, std::vector< std::vector< int >> *resource_indices_per_group)
virtual bool IsCPSATSolver()=0
virtual void AddObjectiveConstraint()=0
DimensionSchedulingStatus Solve(absl::Duration duration_limit) override
int CreateNewPositiveVariable() override
bool SolutionIsInteger() const override
void AddMaximumConstraint(int max_var, std::vector< int > vars) override
A ResourceGroup defines a set of available Resources with attributes on one or multiple dimensions.
DimensionSchedulingStatus OptimizeSingleRoute(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, RoutingLinearSolverWrapper *solver, std::vector< int64_t > *cumul_values, std::vector< int64_t > *break_values, int64_t *cost, int64_t *transit_cost, bool clear_lp=true)
void SetVariableDisjointBounds(int index, const std::vector< int64_t > &starts, const std::vector< int64_t > &ends) override
void SetObjectiveCoefficient(int index, double coefficient) override
void AddProductConstraint(int product_var, std::vector< int > vars) override
int64_t GetVariableUpperBound(int index) const override
int64_t CumulMax(int index) const
int64_t GetObjectiveValue() const override
int64_t GetVariableLowerBound(int index) const override
DimensionSchedulingStatus ComputeRouteCumuls(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, std::vector< int64_t > *optimal_cumuls, std::vector< int64_t > *optimal_breaks)
virtual int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound)=0
bool SetVariableBounds(int index, int64_t lower_bound, int64_t upper_bound) override
RoutingSearchParameters_SchedulingSolver
DimensionSchedulingStatus Optimize(const std::function< int64_t(int64_t)> &next_accessor, 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, int64_t *transit_cost, bool clear_lp=true)
const RoutingDimension * dimension() const
RoutingGlopWrapper(bool is_relaxation, const glop::GlopParameters ¶meters)
void AddObjectiveConstraint() override
DimensionCumulOptimizerCore(const RoutingDimension *dimension, bool use_precedence_propagator)
virtual void SetEnforcementLiteral(int ct, int condition)=0
void SetEnforcementLiteral(int ct, int condition) override
LocalDimensionCumulOptimizer(const RoutingDimension *dimension, RoutingSearchParameters::SchedulingSolver solver_type)
Collection of objects used to extend the Constraint Solver library.
bool PropagateCumulBounds(const std::function< int64_t(int64_t)> &next_accessor, int64_t cumul_offset)
void SetObjectiveCoefficient(int index, double coefficient) override
virtual int NumVariables() const =0
int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound) override
int CreateNewConstraint(int64_t lower_bound, int64_t upper_bound) override
bool ComputeAssignmentCostsForVehicle(int v, const std::function< int64_t(int64_t)> &next_accessor, bool optimize_vehicle_costs, std::vector< int64_t > *assignment_costs, std::vector< std::vector< int64_t >> *cumul_values, std::vector< std::vector< int64_t >> *break_values)
double GetValue(int index) const override
int NumVariables() const override
double GetObjectiveCoefficient(int index) const override
virtual DimensionSchedulingStatus Solve(absl::Duration duration_limit)=0
std::vector< DimensionSchedulingStatus > ComputeRouteCumulCostsForResourcesWithoutFixedTransits(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, const std::vector< RoutingModel::ResourceGroup::Resource > &resources, const std::vector< 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)
const RoutingDimension * dimension() const
void AddObjectiveConstraint() override
virtual int CreateNewPositiveVariable()=0
void AddProductConstraint(int product_var, std::vector< int > vars) override
const RoutingDimension * dimension() const
double GetObjectiveCoefficient(int index) const override
int AddVariable(int64_t lower_bound, int64_t upper_bound)
GlobalDimensionCumulOptimizer(const RoutingDimension *dimension, RoutingSearchParameters::SchedulingSolver solver_type)
virtual int64_t GetVariableLowerBound(int index) const =0
virtual bool SolutionIsInteger() const =0
virtual void SetVariableDisjointBounds(int index, const std::vector< int64_t > &starts, const std::vector< int64_t > &ends)=0
void AddMaximumConstraint(int max_var, std::vector< int > vars) override
void SetEnforcementLiteral(int ct, int condition) override
CumulBoundsPropagator(const RoutingDimension *dimension)
bool SetVariableBounds(int index, int64_t lower_bound, int64_t upper_bound) override
virtual void ClearObjective()=0
void ClearObjective() override
DimensionSchedulingStatus ComputeRouteCumulCost(int vehicle, const std::function< int64_t(int64_t)> &next_accessor, int64_t *optimal_cost)