diff --git a/examples/cpp/cvrptw_lib.h b/examples/cpp/cvrptw_lib.h index 7e2c9ed8b6..243d2c9b11 100644 --- a/examples/cpp/cvrptw_lib.h +++ b/examples/cpp/cvrptw_lib.h @@ -64,7 +64,7 @@ class LocationContainer { MTRandom randomizer_; const int64 speed_; - ITIVector locations_; + gtl::ITIVector locations_; }; // Random demand. diff --git a/ortools/base/int_type_indexed_vector.h b/ortools/base/int_type_indexed_vector.h index 7702a2e3a7..027b2cedf6 100644 --- a/ortools/base/int_type_indexed_vector.h +++ b/ortools/base/int_type_indexed_vector.h @@ -67,6 +67,7 @@ #include "ortools/base/int_type.h" #include "ortools/base/macros.h" +namespace gtl { // STL std::vector // ------------------------------------------------------------------ template > @@ -204,4 +205,6 @@ inline void swap(ITIVector& x, x.swap(y); } +} // namespace gtl + #endif // OR_TOOLS_BASE_INT_TYPE_INDEXED_VECTOR_H_ diff --git a/ortools/bop/bop_base.h b/ortools/bop/bop_base.h index 95cb1b513d..4624685a3b 100644 --- a/ortools/bop/bop_base.h +++ b/ortools/bop/bop_base.h @@ -170,14 +170,14 @@ class ProblemState { // Returns true when the variable var is fixed in the current problem state. // The value of the fixed variable is returned by GetVariableFixedValue(var). bool IsVariableFixed(VariableIndex var) const { return is_fixed_[var]; } - const ITIVector& is_fixed() const { return is_fixed_; } + const gtl::ITIVector& is_fixed() const { return is_fixed_; } // Returns the value of the fixed variable var. Should be only called on fixed // variables (CHECKed). bool GetVariableFixedValue(VariableIndex var) const { return fixed_values_[var]; } - const ITIVector& fixed_values() const { + const gtl::ITIVector& fixed_values() const { return fixed_values_; } @@ -221,8 +221,8 @@ class ProblemState { const LinearBooleanProblem& original_problem_; BopParameters parameters_; int64 update_stamp_; - ITIVector is_fixed_; - ITIVector fixed_values_; + gtl::ITIVector is_fixed_; + gtl::ITIVector fixed_values_; glop::DenseRow lp_values_; BopSolution solution_; std::vector assignment_preference_; diff --git a/ortools/bop/bop_lns.h b/ortools/bop/bop_lns.h index 2965b64a5c..2201d2ca04 100644 --- a/ortools/bop/bop_lns.h +++ b/ortools/bop/bop_lns.h @@ -174,7 +174,7 @@ class RelationGraphBasedNeighborhood : public NeighborhoodGenerator { // TODO(user): reuse by_variable_matrix_ from the LS? Note however than we // don't need the coefficients here. - ITIVector> columns_; + gtl::ITIVector> columns_; MTRandom* random_; }; diff --git a/ortools/bop/bop_ls.cc b/ortools/bop/bop_ls.cc index 7a394bb071..7e0f034b6f 100644 --- a/ortools/bop/bop_ls.cc +++ b/ortools/bop/bop_ls.cc @@ -537,7 +537,7 @@ ConstraintIndex OneFlipConstraintRepairer::ConstraintToRepair() const { TermIndex OneFlipConstraintRepairer::NextRepairingTerm( ConstraintIndex ct_index, TermIndex init_term_index, TermIndex start_term_index) const { - const ITIVector& terms = + const gtl::ITIVector& terms = by_constraint_matrix_[ct_index]; const int64 constraint_value = maintainer_.ConstraintValue(ct_index); const int64 lb = maintainer_.ConstraintLowerBound(ct_index); @@ -589,13 +589,13 @@ sat::Literal OneFlipConstraintRepairer::GetFlip(ConstraintIndex ct_index, } void OneFlipConstraintRepairer::SortTermsOfEachConstraints(int num_variables) { - ITIVector objective(num_variables, 0); + gtl::ITIVector objective(num_variables, 0); for (const ConstraintTerm& term : by_constraint_matrix_[AssignmentAndConstraintFeasibilityMaintainer:: kObjectiveConstraint]) { objective[term.var] = std::abs(term.weight); } - for (ITIVector& terms : by_constraint_matrix_) { + for (gtl::ITIVector& terms : by_constraint_matrix_) { std::sort(terms.begin(), terms.end(), [&objective](const ConstraintTerm& a, const ConstraintTerm& b) { return objective[a.var] > objective[b.var]; diff --git a/ortools/bop/bop_ls.h b/ortools/bop/bop_ls.h index d30e3dbb46..dfed4b61d4 100644 --- a/ortools/bop/bop_ls.h +++ b/ortools/bop/bop_ls.h @@ -227,7 +227,7 @@ class NonOrderedSetHasher { private: MTRandom random_; - ITIVector hashes_; + gtl::ITIVector hashes_; }; // This class is used to incrementally maintain an assignment and the @@ -384,15 +384,15 @@ class AssignmentAndConstraintFeasibilityMaintainer { int64 weight; }; - ITIVector> + gtl::ITIVector> by_variable_matrix_; - ITIVector constraint_lower_bounds_; - ITIVector constraint_upper_bounds_; + gtl::ITIVector constraint_lower_bounds_; + gtl::ITIVector constraint_upper_bounds_; BopSolution assignment_; BopSolution reference_; - ITIVector constraint_values_; + gtl::ITIVector constraint_values_; BacktrackableIntegerSet infeasible_constraint_set_; // This contains the list of variable flipped in assignment_. @@ -481,7 +481,7 @@ class OneFlipConstraintRepairer { // on most promising variables first. void SortTermsOfEachConstraints(int num_variables); - ITIVector> + gtl::ITIVector> by_constraint_matrix_; const AssignmentAndConstraintFeasibilityMaintainer& maintainer_; const sat::VariablesAssignment& sat_assignment_; @@ -593,7 +593,7 @@ class LocalSearchAssignmentIterator { SatWrapper* const sat_wrapper_; OneFlipConstraintRepairer repairer_; std::vector search_nodes_; - ITIVector initial_term_index_; + gtl::ITIVector initial_term_index_; // Temporary vector used by ApplyDecision(). std::vector tmp_propagated_literals_; diff --git a/ortools/bop/bop_portfolio.cc b/ortools/bop/bop_portfolio.cc index 7ed9c8c7f2..9839923dca 100644 --- a/ortools/bop/bop_portfolio.cc +++ b/ortools/bop/bop_portfolio.cc @@ -81,7 +81,7 @@ PortfolioOptimizer::~PortfolioOptimizer() { } // Note that unique pointers are not used due to unsupported emplace_back - // in ITIVectors. + // in gtl::ITIVectors. gtl::STLDeleteElements(&optimizers_); } @@ -326,7 +326,7 @@ void PortfolioOptimizer::CreateOptimizers( // OptimizerSelector //------------------------------------------------------------------------------ OptimizerSelector::OptimizerSelector( - const ITIVector& optimizers) + const gtl::ITIVector& optimizers) : run_infos_(), selected_index_(optimizers.size()) { for (OptimizerIndex i(0); i < optimizers.size(); ++i) { info_positions_.push_back(run_infos_.size()); diff --git a/ortools/bop/bop_portfolio.h b/ortools/bop/bop_portfolio.h index 1d9a787065..77aa9a47f4 100644 --- a/ortools/bop/bop_portfolio.h +++ b/ortools/bop/bop_portfolio.h @@ -86,7 +86,7 @@ class PortfolioOptimizer : public BopOptimizerBase { int64 state_update_stamp_; BopConstraintTerms objective_terms_; std::unique_ptr selector_; - ITIVector optimizers_; + gtl::ITIVector optimizers_; sat::SatSolver sat_propagator_; BopParameters parameters_; double lower_bound_; @@ -101,7 +101,7 @@ class OptimizerSelector { // Note that the list of optimizers is only used to get the names for // debug purposes, the ownership of the optimizers is not transfered. explicit OptimizerSelector( - const ITIVector& optimizers); + const gtl::ITIVector& optimizers); // Selects the next optimizer to run based on the user defined order and // history of success. Returns kInvalidOptimizerIndex if no optimizer is @@ -193,7 +193,7 @@ class OptimizerSelector { }; std::vector run_infos_; - ITIVector info_positions_; + gtl::ITIVector info_positions_; int selected_index_; }; diff --git a/ortools/bop/bop_solution.h b/ortools/bop/bop_solution.h index 8d4a592689..82aa785cce 100644 --- a/ortools/bop/bop_solution.h +++ b/ortools/bop/bop_solution.h @@ -73,10 +73,10 @@ class BopSolution { } // For range based iteration, i.e. for (const bool value : solution) {...}. - ITIVector::const_iterator begin() const { + gtl::ITIVector::const_iterator begin() const { return values_.begin(); } - ITIVector::const_iterator end() const { + gtl::ITIVector::const_iterator end() const { return values_.end(); } @@ -95,7 +95,7 @@ class BopSolution { const LinearBooleanProblem* problem_; std::string name_; - ITIVector values_; + gtl::ITIVector values_; // Those are mutable because they behave as const values for a given solution // but for performance reasons we want to be lazy on their computation, diff --git a/ortools/bop/bop_types.h b/ortools/bop/bop_types.h index ba380f4329..c05b493038 100644 --- a/ortools/bop/bop_types.h +++ b/ortools/bop/bop_types.h @@ -82,7 +82,7 @@ struct BopConstraintTerm { return search_id < other.search_id; } }; -typedef ITIVector BopConstraintTerms; +typedef gtl::ITIVector BopConstraintTerms; } // namespace bop } // namespace operations_research diff --git a/ortools/bop/integral_solver.cc b/ortools/bop/integral_solver.cc index ae83178ba1..21eec654c7 100644 --- a/ortools/bop/integral_solver.cc +++ b/ortools/bop/integral_solver.cc @@ -381,7 +381,7 @@ class IntegralProblemConverter { // constraint. Fractional AddWeightedIntegralVariable( ColIndex col, Fractional weight, - ITIVector* dense_weights); + gtl::ITIVector* dense_weights); // Scales weights and adds all non-zero scaled weights and literals to t. // t is a constraint or the objective. @@ -391,25 +391,25 @@ class IntegralProblemConverter { template double ScaleAndSparsifyWeights( double scaling_factor, int64 gcd, - const ITIVector& dense_weights, T* t); + const gtl::ITIVector& dense_weights, T* t); // Returns true when at least one element is non-zero. bool HasNonZeroWeigths( - const ITIVector& dense_weights) const; + const gtl::ITIVector& dense_weights) const; bool problem_is_boolean_and_has_only_integral_constraints_; // global_to_boolean_[i] represents the Boolean variable index in Bop; when // negative -global_to_boolean_[i] - 1 represents the index of the // integral variable in integral_variables_. - ITIVector + gtl::ITIVector global_to_boolean_; std::vector integral_variables_; std::vector integral_indices_; int num_boolean_variables_; enum VariableType { BOOLEAN, INTEGRAL, INTEGRAL_EXPRESSED_AS_BOOLEAN }; - ITIVector variable_types_; + gtl::ITIVector variable_types_; }; IntegralProblemConverter::IntegralProblemConverter() @@ -583,7 +583,7 @@ void IntegralProblemConverter::ConvertAllConstraints( std::vector coefficients; for (RowIndex row(0); row < linear_problem.num_constraints(); ++row) { Fractional offset = 0.0; - ITIVector dense_weights(num_boolean_variables_, + gtl::ITIVector dense_weights(num_boolean_variables_, 0.0); for (const SparseColumn::Entry e : transpose.column(RowToColIndex(row))) { // Cast in ColIndex due to the transpose. @@ -653,7 +653,7 @@ void IntegralProblemConverter::ConvertObjective( LinearBooleanProblem* boolean_problem) { LinearObjective* objective = boolean_problem->mutable_objective(); Fractional offset = 0.0; - ITIVector dense_weights(num_boolean_variables_, + gtl::ITIVector dense_weights(num_boolean_variables_, 0.0); // Compute the objective weights for the binary variable model. for (ColIndex col(0); col < linear_problem.num_variables(); ++col) { @@ -787,7 +787,7 @@ bool IntegralProblemConverter::CreateVariableUsingConstraint( integral_var->Clear(); const SparseMatrix& transpose = linear_problem.GetTransposeSparseMatrix(); - ITIVector dense_weights(num_boolean_variables_, + gtl::ITIVector dense_weights(num_boolean_variables_, 0.0); Fractional scale = 1.0; int64 variable_offset = 0; @@ -838,7 +838,7 @@ bool IntegralProblemConverter::CreateVariableUsingConstraint( Fractional IntegralProblemConverter::AddWeightedIntegralVariable( ColIndex col, Fractional weight, - ITIVector* dense_weights) { + gtl::ITIVector* dense_weights) { CHECK(nullptr != dense_weights); if (weight == 0.0) { @@ -865,7 +865,7 @@ Fractional IntegralProblemConverter::AddWeightedIntegralVariable( template double IntegralProblemConverter::ScaleAndSparsifyWeights( double scaling_factor, int64 gcd, - const ITIVector& dense_weights, T* t) { + const gtl::ITIVector& dense_weights, T* t) { CHECK(nullptr != t); double bound_error = 0.0; @@ -881,7 +881,7 @@ double IntegralProblemConverter::ScaleAndSparsifyWeights( return bound_error; } bool IntegralProblemConverter::HasNonZeroWeigths( - const ITIVector& dense_weights) const { + const gtl::ITIVector& dense_weights) const { for (const Fractional weight : dense_weights) { if (weight != 0.0) { return true; diff --git a/ortools/constraint_solver/gcc.cc b/ortools/constraint_solver/gcc.cc index 63b7918d60..9f13dd2cec 100644 --- a/ortools/constraint_solver/gcc.cc +++ b/ortools/constraint_solver/gcc.cc @@ -688,7 +688,7 @@ class GccConstraint : public Constraint { return changed; } - ITIVector variables_; + gtl::ITIVector variables_; const int64 size_; // NumericalRev current_level_; // int last_level_; @@ -700,7 +700,7 @@ class GccConstraint : public Constraint { std::vector stable_intervals_; std::vector potential_stable_sets_; std::vector new_min_; - ITIVector intervals_; + gtl::ITIVector intervals_; std::vector sorted_by_min_; std::vector sorted_by_max_; // bounds_[1..active_size_] hold set of min & max of the n intervals diff --git a/ortools/constraint_solver/routing.cc b/ortools/constraint_solver/routing.cc index a6564244a6..1bf0f0d61f 100644 --- a/ortools/constraint_solver/routing.cc +++ b/ortools/constraint_solver/routing.cc @@ -368,9 +368,9 @@ class RoutingCache : public RoutingModel::NodeEvaluator2 { } private: - ITIVector> + gtl::ITIVector> cached_; - ITIVector> + gtl::ITIVector> cache_; RoutingModel::NodeEvaluator2* const callback_; }; @@ -416,9 +416,9 @@ class StateDependentRoutingCache : public RoutingModel::VariableNodeEvaluator2 { } private: - ITIVector< + gtl::ITIVector< RoutingModel::NodeIndex, - ITIVector> + gtl::ITIVector> cache_; RoutingModel::VariableNodeEvaluator2* const callback_; }; @@ -2597,7 +2597,7 @@ struct SweepNodeSortDistance { } SweepNodeDistanceComparator; SweepArranger::SweepArranger( - const ITIVector>& points) + const gtl::ITIVector>& points) : coordinates_(2 * points.size(), 0), sectors_(1) { for (RoutingModel::NodeIndex i(0); i < points.size(); ++i) { coordinates_[2 * i] = points[i].first; diff --git a/ortools/constraint_solver/routing.h b/ortools/constraint_solver/routing.h index 4413df0b7e..3f8667b2dd 100644 --- a/ortools/constraint_solver/routing.h +++ b/ortools/constraint_solver/routing.h @@ -314,14 +314,14 @@ class RoutingModel { RoutingModel::NodeIndex end; // Bounds of cumul variables at start and end vehicle nodes. // dimension_{start,end}_cumuls_{min,max}[d] is the bound for dimension d. - ITIVector dimension_start_cumuls_min; - ITIVector dimension_start_cumuls_max; - ITIVector dimension_end_cumuls_min; - ITIVector dimension_end_cumuls_max; - ITIVector dimension_capacities; + gtl::ITIVector dimension_start_cumuls_min; + gtl::ITIVector dimension_start_cumuls_max; + gtl::ITIVector dimension_end_cumuls_min; + gtl::ITIVector dimension_end_cumuls_max; + gtl::ITIVector dimension_capacities; // dimension_evaluators[d]->Run(from, to) is the transit value of arc // from->to for a dimension d. - ITIVector dimension_evaluator_classes; + gtl::ITIVector dimension_evaluator_classes; // Fingerprint of unvisitable non-start/end nodes. uint64 unvisitable_nodes_fprint; @@ -1252,7 +1252,7 @@ class RoutingModel { RevSwitch is_bound_to_end_ct_added_; // Dimensions std::unordered_map dimension_name_to_index_; - ITIVector dimensions_; + gtl::ITIVector dimensions_; std::string primary_constrained_dimension_; // Costs IntVar* cost_; @@ -1260,14 +1260,14 @@ class RoutingModel { std::vector fixed_cost_of_vehicle_; std::vector cost_class_index_of_vehicle_; #ifndef SWIG - ITIVector cost_classes_; + gtl::ITIVector cost_classes_; #endif // SWIG bool costs_are_homogeneous_across_vehicles_; bool cache_callbacks_; std::vector cost_cache_; // Index by source index. std::vector vehicle_class_index_of_vehicle_; #ifndef SWIG - ITIVector vehicle_classes_; + gtl::ITIVector vehicle_classes_; #endif // SWIG std::function vehicle_start_class_callback_; // Cached callbacks @@ -1276,7 +1276,7 @@ class RoutingModel { std::unordered_map cached_state_dependent_callbacks_; // Disjunctions - ITIVector disjunctions_; + gtl::ITIVector disjunctions_; std::vector> node_to_disjunctions_; // Same vehicle costs std::vector> same_vehicle_costs_; @@ -1288,7 +1288,7 @@ class RoutingModel { std::vector> same_vehicle_groups_; // Index management std::vector index_to_node_; - ITIVector node_to_index_; + gtl::ITIVector node_to_index_; std::vector index_to_vehicle_; std::vector starts_; std::vector ends_; @@ -1735,14 +1735,14 @@ class RoutingDimension { // depot. Used in the Sweep first solution heuristic. class SweepArranger { public: - explicit SweepArranger(const ITIVector>& points); virtual ~SweepArranger() {} void ArrangeNodes(std::vector* nodes); void SetSectors(int sectors) { sectors_ = sectors; } private: - ITIVector coordinates_; + gtl::ITIVector coordinates_; int sectors_; DISALLOW_COPY_AND_ASSIGN(SweepArranger); diff --git a/ortools/constraint_solver/routing_search.cc b/ortools/constraint_solver/routing_search.cc index de184d828c..96240a9ad3 100644 --- a/ortools/constraint_solver/routing_search.cc +++ b/ortools/constraint_solver/routing_search.cc @@ -218,8 +218,8 @@ class NodeDisjunctionFilter : public RoutingLocalSearchFilter { const RoutingModel& routing_model_; - ITIVector active_per_disjunction_; - ITIVector inactive_per_disjunction_; + gtl::ITIVector active_per_disjunction_; + gtl::ITIVector inactive_per_disjunction_; int64 penalty_value_; }; } // namespace diff --git a/ortools/constraint_solver/sat_constraint.h b/ortools/constraint_solver/sat_constraint.h index 44049b3b70..2a826a1714 100644 --- a/ortools/constraint_solver/sat_constraint.h +++ b/ortools/constraint_solver/sat_constraint.h @@ -127,7 +127,7 @@ class BooleanVariableManager { std::vector registered_int_vars_; std::vector associated_variables_; std::unordered_map registration_index_map_; - ITIVector> variable_meaning_; + gtl::ITIVector> variable_meaning_; DISALLOW_COPY_AND_ASSIGN(BooleanVariableManager); }; diff --git a/ortools/flatzinc/cp_model_fz_solver.cc b/ortools/flatzinc/cp_model_fz_solver.cc index ad5f2eb24e..bcae96e82c 100644 --- a/ortools/flatzinc/cp_model_fz_solver.cc +++ b/ortools/flatzinc/cp_model_fz_solver.cc @@ -988,7 +988,7 @@ void SolveFzWithCpModelProto(const fz::Model& fz_model, pool.StartWorkers(); for (int worker_id = 0; worker_id < num_search_workers; ++worker_id) { const SatParameters local_params = - DiversifySearchParameters(m.parameters, m.proto, worker_id, 0); + DiversifySearchParameters(m.parameters, m.proto, worker_id); pool.Schedule([&fz_model, &m, &p, &stopped, local_params, worker_id, &best_response, &mutex]() { const CpSolverResponse local_response = @@ -1008,23 +1008,13 @@ void SolveFzWithCpModelProto(const fz::Model& fz_model, // Optimization problem solved in parallel. absl::Mutex mutex; const bool maximize = fz_model.maximize(); - const int kNumHeuristics = 5; - const int num_active_threads = - std::min(kNumHeuristics + 1, num_search_workers); - if (num_active_threads != num_search_workers) { - FZLOG << "Starting parallel search with " << num_active_threads - << " workers, including one with " - << num_search_workers - num_active_threads + 1 << " lns sub-threads" - << FZENDL; - } else { - FZLOG << "Starting parallel search with " << num_search_workers - << " workers" << FZENDL; - } + FZLOG << "Starting parallel search with " << num_search_workers + << " workers" << FZENDL; { - ThreadPool pool("Parallel_FlatZinc_sat", num_active_threads); + ThreadPool pool("Parallel_FlatZinc_sat", num_search_workers); pool.StartWorkers(); - for (int worker_id = 0; worker_id < num_active_threads; ++worker_id) { + for (int worker_id = 0; worker_id < num_search_workers; ++worker_id) { const auto solution_synchronization = [&mutex, &best_response]() { absl::MutexLock lock(&mutex); return best_response; @@ -1066,9 +1056,8 @@ void SolveFzWithCpModelProto(const fz::Model& fz_model, } }; - const SatParameters local_params = DiversifySearchParameters( - m.parameters, m.proto, worker_id, - num_search_workers - num_active_threads + 1); + const SatParameters local_params = + DiversifySearchParameters(m.parameters, m.proto, worker_id); pool.Schedule([&fz_model, &m, &p, solution_observer, solution_synchronization, objective_synchronization, diff --git a/ortools/glop/markowitz.h b/ortools/glop/markowitz.h index c3d32ff547..d20385b3bc 100644 --- a/ortools/glop/markowitz.h +++ b/ortools/glop/markowitz.h @@ -174,7 +174,7 @@ class MatrixNonZeroPattern { // non-sorted version. Investigate more. void MergeIntoSorted(RowIndex pivot_row, RowIndex row); - ITIVector> row_non_zero_; + gtl::ITIVector> row_non_zero_; StrictITIVector row_degree_; StrictITIVector col_degree_; DenseBooleanRow deleted_columns_; @@ -247,7 +247,7 @@ class SparseMatrixWithReusableColumnMemory { // mutable_column(col) is stored in columns_[mapping_[col]]. // The columns_ that can be reused have their index stored in free_columns_. const SparseColumn empty_column_; - ITIVector mapping_; + gtl::ITIVector mapping_; std::vector free_columns_; std::vector columns_; DISALLOW_COPY_AND_ASSIGN(SparseMatrixWithReusableColumnMemory); diff --git a/ortools/glop/preprocessor.cc b/ortools/glop/preprocessor.cc index 194c613e18..878aa81299 100644 --- a/ortools/glop/preprocessor.cc +++ b/ortools/glop/preprocessor.cc @@ -1307,8 +1307,8 @@ bool ImpliedFreePreprocessor::Run(LinearProgram* lp) { const int size = num_rows.value(); // TODO(user) : Replace SumWithNegativeInfiniteAndOneMissing and // SumWithPositiveInfiniteAndOneMissing with IntervalSumWithOneMissing. - ITIVector lb_sums(size); - ITIVector ub_sums(size); + gtl::ITIVector lb_sums(size); + gtl::ITIVector ub_sums(size); // Initialize the sums by adding all the bounds of the variables. for (ColIndex col(0); col < num_cols; ++col) { @@ -3389,7 +3389,7 @@ bool ShiftVariableBoundsPreprocessor::Run(LinearProgram* lp) { int num_bound_shifts = 0; const RowIndex num_rows = lp->num_constraints(); KahanSum objective_offset; - ITIVector row_offsets(num_rows.value()); + gtl::ITIVector row_offsets(num_rows.value()); offsets_.assign(num_cols, 0.0); for (ColIndex col(0); col < num_cols; ++col) { if (0.0 < variable_initial_lbs_[col] || 0.0 > variable_initial_ubs_[col]) { @@ -3621,7 +3621,7 @@ bool SolowHalimPreprocessor::Run(LinearProgram* lp) { } KahanSum objective_offset; - ITIVector row_offsets(num_rows.value()); + gtl::ITIVector row_offsets(num_rows.value()); column_transform_.resize(num_cols.value(), NOT_MODIFIED); for (ColIndex col(0); col < num_cols; ++col) { const Fractional coeff = lp->objective_coefficients()[col]; diff --git a/ortools/glop/preprocessor.h b/ortools/glop/preprocessor.h index 87367e3069..a028303f83 100644 --- a/ortools/glop/preprocessor.h +++ b/ortools/glop/preprocessor.h @@ -454,9 +454,9 @@ class SingletonPreprocessor : public Preprocessor { // This is used as a "cache" by MakeConstraintAnEqualityIfPossible() to avoid // scanning more than once each row. See the code to see how this is used. - ITIVector row_sum_is_cached_; - ITIVector row_lb_sum_; - ITIVector row_ub_sum_; + gtl::ITIVector row_sum_is_cached_; + gtl::ITIVector row_lb_sum_; + gtl::ITIVector row_ub_sum_; // The columns that are deleted by this preprocessor. SparseMatrix deleted_columns_; @@ -1001,7 +1001,7 @@ class SolowHalimPreprocessor : public Preprocessor { } ColumnTransformType; // Contains the coordinate change information for each column - ITIVector column_transform_; + gtl::ITIVector column_transform_; // Contains the initial problem bounds. DenseRow variable_initial_lbs_; diff --git a/ortools/glop/revised_simplex.cc b/ortools/glop/revised_simplex.cc index 5653b1c279..4480963d95 100644 --- a/ortools/glop/revised_simplex.cc +++ b/ortools/glop/revised_simplex.cc @@ -2958,9 +2958,9 @@ void RevisedSimplex::DisplayVariableBounds() { } } -ITIVector RevisedSimplex::ComputeDictionary( +gtl::ITIVector RevisedSimplex::ComputeDictionary( const DenseRow* column_scales) { - ITIVector dictionary(num_rows_.value()); + gtl::ITIVector dictionary(num_rows_.value()); for (ColIndex col(0); col < num_cols_; ++col) { ComputeDirection(col); for (const RowIndex row : direction_.non_zeros) { diff --git a/ortools/graph/cliques.h b/ortools/graph/cliques.h index 8c9d953d79..e2f3c9c8f7 100644 --- a/ortools/graph/cliques.h +++ b/ortools/graph/cliques.h @@ -272,7 +272,7 @@ class BronKerboschAlgorithm { // clique. // NOTE(user): We could store the delta between the iterations; however, // we need to evaluate the impact this would have on the performance. - ITIVector candidates; + gtl::ITIVector candidates; // The index of the first actual candidate in 'candidates'. This number is // also the number of elements of the "not" set stored at the beginning of // 'candidates'. @@ -448,7 +448,7 @@ void BronKerboschAlgorithm::PushState(NodeIndex selected) { DCHECK(time_limit_ != nullptr); DVLOG(2) << "PushState: New depth = " << states_.size() + 1 << ", selected node = " << selected; - ITIVector new_candidates; + gtl::ITIVector new_candidates; State* const previous_state = &states_.back(); const double deterministic_time = diff --git a/ortools/lp_data/lp_data.cc b/ortools/lp_data/lp_data.cc index efe16fec91..22f33046a2 100644 --- a/ortools/lp_data/lp_data.cc +++ b/ortools/lp_data/lp_data.cc @@ -55,7 +55,7 @@ bool AreBoundsFreeOrBoxed(Fractional lower_bound, Fractional upper_bound) { } template -double Average(const ITIVector& v) { +double Average(const gtl::ITIVector& v) { const size_t size = v.size(); DCHECK_LT(0, size); double sum = 0.0; @@ -69,7 +69,7 @@ double Average(const ITIVector& v) { } template -double StandardDeviation(const ITIVector& v) { +double StandardDeviation(const gtl::ITIVector& v) { const size_t size = v.size(); double n = 0.0; // n is used in a calculation involving doubles. double sigma_square = 0.0; @@ -86,7 +86,7 @@ double StandardDeviation(const ITIVector& v) { // Returns 0 when the vector is empty. template -T GetMaxElement(const ITIVector& v) { +T GetMaxElement(const gtl::ITIVector& v) { const size_t size = v.size(); if (size == 0) { return T(0); diff --git a/ortools/lp_data/lp_types.h b/ortools/lp_data/lp_types.h index 985ec3bce0..61181a6e60 100644 --- a/ortools/lp_data/lp_types.h +++ b/ortools/lp_data/lp_types.h @@ -241,16 +241,16 @@ inline std::ostream& operator<<(std::ostream& os, ConstraintStatus status) { // Returns the ConstraintStatus corresponding to a given VariableStatus. ConstraintStatus VariableToConstraintStatus(VariableStatus status); -// Wrapper around an ITIVector to allow (and enforce) creation/resize/assign +// Wrapper around an gtl::ITIVector to allow (and enforce) creation/resize/assign // to use the index type for the size. // -// TODO(user): This should probably move into ITIVector, but note that this +// TODO(user): This should probably move into gtl::ITIVector, but note that this // version is more strict and does not allow any other size types. template -class StrictITIVector : public ITIVector { +class StrictITIVector : public gtl::ITIVector { public: typedef IntType IndexType; // g++ 4.8.1 needs this. - typedef ITIVector ParentType; + typedef gtl::ITIVector ParentType; // This allows for brace initialization, which is really useful in tests. // It is not 'explicit' by design, so one can do vector = {...}; #if !defined(__ANDROID__) && (!defined(_MSC_VER) || (_MSC_VER >= 1800)) diff --git a/ortools/lp_data/matrix_scaler.cc b/ortools/lp_data/matrix_scaler.cc index 763ee507fd..b87a14a0a7 100644 --- a/ortools/lp_data/matrix_scaler.cc +++ b/ortools/lp_data/matrix_scaler.cc @@ -134,8 +134,8 @@ void SparseMatrixScaler::Scale(GlopParameters::ScalingAlgorithm method) { namespace { template -void ScaleVector(const ITIVector& scale, bool up, - ITIVector* vector_to_scale) { +void ScaleVector(const gtl::ITIVector& scale, bool up, + gtl::ITIVector* vector_to_scale) { RETURN_IF_NULL(vector_to_scale); const I size(std::min(scale.size(), vector_to_scale->size())); if (up) { @@ -152,7 +152,7 @@ void ScaleVector(const ITIVector& scale, bool up, template ColIndex CreateOrGetScaleIndex( InputIndexType num, LinearProgram* lp, - ITIVector* scale_var_indices) { + gtl::ITIVector* scale_var_indices) { if ((*scale_var_indices)[num] == -1) { (*scale_var_indices)[num] = lp->CreateNewVariable(); } @@ -373,8 +373,8 @@ Status SparseMatrixScaler::LPScale() { // Indices to variables in the LinearProgram populated by // GenerateLinearProgram. - ITIVector col_scale_var_indices; - ITIVector row_scale_var_indices; + gtl::ITIVector col_scale_var_indices; + gtl::ITIVector row_scale_var_indices; row_scale_var_indices.resize(RowToIntIndex(matrix_->num_rows()), kInvalidCol); col_scale_var_indices.resize(ColToIntIndex(matrix_->num_cols()), kInvalidCol); const ColIndex beta = linear_program->CreateNewVariable(); diff --git a/ortools/lp_data/permutation.h b/ortools/lp_data/permutation.h index cf9d295111..50f2039d15 100644 --- a/ortools/lp_data/permutation.h +++ b/ortools/lp_data/permutation.h @@ -84,7 +84,7 @@ class Permutation { int ComputeSignature() const; private: - ITIVector perm_; + gtl::ITIVector perm_; DISALLOW_COPY_AND_ASSIGN(Permutation); }; @@ -148,7 +148,7 @@ void Permutation::PopulateRandomly() { template bool Permutation::Check() const { const size_t size = perm_.size(); - ITIVector visited(size, false); + gtl::ITIVector visited(size, false); for (IndexType i(0); i < size; ++i) { if (perm_[i] < 0 || perm_[i] >= size) { return false; @@ -166,7 +166,7 @@ bool Permutation::Check() const { template int Permutation::ComputeSignature() const { const size_t size = perm_.size(); - ITIVector visited(size); + gtl::ITIVector visited(size); DCHECK(Check()); int signature = 1; for (IndexType i(0); i < size; ++i) { diff --git a/ortools/lp_data/sparse_row.h b/ortools/lp_data/sparse_row.h index 6cdb4c1daa..02757ba595 100644 --- a/ortools/lp_data/sparse_row.h +++ b/ortools/lp_data/sparse_row.h @@ -57,7 +57,7 @@ class SparseRow : public SparseVector { }; // A matrix stored by rows. -typedef ITIVector RowMajorSparseMatrix; +typedef gtl::ITIVector RowMajorSparseMatrix; } // namespace glop } // namespace operations_research diff --git a/ortools/sat/boolean_problem.cc b/ortools/sat/boolean_problem.cc index 18bc9ea93a..cbf9a2d648 100644 --- a/ortools/sat/boolean_problem.cc +++ b/ortools/sat/boolean_problem.cc @@ -739,7 +739,7 @@ void FindLinearBooleanProblemSymmetries( } void ApplyLiteralMappingToBooleanProblem( - const ITIVector& mapping, + const gtl::ITIVector& mapping, LinearBooleanProblem* problem) { Coefficient bound_shift; Coefficient max_value; @@ -829,7 +829,7 @@ void ProbeAndSimplifyProblem(SatPostsolver* postsolver, LOG(INFO) << "UNSAT when loading the problem."; } - ITIVector equiv_map; + gtl::ITIVector equiv_map; ProbeAndFindEquivalentLiteral(&solver, postsolver, /*drat_writer=*/nullptr, &equiv_map); @@ -855,7 +855,7 @@ void ProbeAndSimplifyProblem(SatPostsolver* postsolver, // Remap the variables into a dense set. All the variables for which the // equiv_map is not the identity are no longer needed. BooleanVariable new_var(0); - ITIVector var_map; + gtl::ITIVector var_map; for (BooleanVariable var(0); var < solver.NumVariables(); ++var) { if (equiv_map[Literal(var, true).Index()] == Literal(var, true).Index()) { var_map.push_back(new_var); diff --git a/ortools/sat/boolean_problem.h b/ortools/sat/boolean_problem.h index 1bdea8d9dd..38bfe498d7 100644 --- a/ortools/sat/boolean_problem.h +++ b/ortools/sat/boolean_problem.h @@ -129,7 +129,7 @@ void FindLinearBooleanProblemSymmetries( // of the correct size. It can also map a literal index to kTrueLiteralIndex // or kFalseLiteralIndex in order to fix the variable. void ApplyLiteralMappingToBooleanProblem( - const ITIVector& mapping, + const gtl::ITIVector& mapping, LinearBooleanProblem* problem); // A simple preprocessing step that does basic probing and removes the fixed and diff --git a/ortools/sat/clause.h b/ortools/sat/clause.h index ebde54f40d..f207be82fc 100644 --- a/ortools/sat/clause.h +++ b/ortools/sat/clause.h @@ -263,7 +263,7 @@ class LiteralWatchers : public SatPropagator { SatClause* clause; Literal blocking_literal; }; - ITIVector> watchers_on_false_; + gtl::ITIVector> watchers_on_false_; // SatClause reasons by trail_index. std::vector reasons_; @@ -481,7 +481,7 @@ class BinaryImplicationGraph : public SatPropagator { // // TODO(user): We could be even more efficient since a size of int32 is enough // for us and we could store in common the inlined/not-inlined size. - ITIVector> implications_; + gtl::ITIVector> implications_; int64 num_implications_; // Some stats. diff --git a/ortools/sat/cp_model_search.cc b/ortools/sat/cp_model_search.cc index 27f9f80427..3287bb86fc 100644 --- a/ortools/sat/cp_model_search.cc +++ b/ortools/sat/cp_model_search.cc @@ -251,8 +251,7 @@ std::function InstrumentSearchStrategy( SatParameters DiversifySearchParameters(const SatParameters& params, const CpModelProto& cp_model, - const int worker_id, - int num_lns_threads) { + const int worker_id) { // Note: in the flatzinc setting, we know we always have a fixed search // defined. // Things to try: @@ -263,7 +262,6 @@ SatParameters DiversifySearchParameters(const SatParameters& params, SatParameters new_params = params; new_params.set_random_seed(params.random_seed() + worker_id); if (cp_model.has_objective()) { - CHECK_LE(worker_id, 5); switch (worker_id) { case 0: { // Use default parameters and fixed search. new_params.set_search_branching(SatParameters::FIXED_SEARCH); @@ -277,7 +275,6 @@ SatParameters DiversifySearchParameters(const SatParameters& params, case 2: { // Remove LP relaxation. new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH); new_params.set_linearization_level(0); - new_params.set_binary_search_num_conflicts(10); break; } case 3: { // Reinforce LP relaxation. @@ -290,14 +287,10 @@ SatParameters DiversifySearchParameters(const SatParameters& params, new_params.set_optimize_with_core(true); break; } - case 5: { // LNS + default: { // LNS. new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH); new_params.set_use_lns(true); - new_params.set_lns_num_threads(num_lns_threads); - break; - } - default: { // Fail. - LOG(FATAL) << "Should not be here."; + new_params.set_lns_num_threads(1); } } } else { diff --git a/ortools/sat/cp_model_search.h b/ortools/sat/cp_model_search.h index 9a9dce26d2..27f858bdb3 100644 --- a/ortools/sat/cp_model_search.h +++ b/ortools/sat/cp_model_search.h @@ -46,14 +46,16 @@ std::function InstrumentSearchStrategy( // Returns a different parameters depending on the given worker_id. // This assumes that worker will get an id in [0, num_workers). +// // TODO(user): Find a way to know how many search heuristics there are, // and how many threads to pass to LNS with an optimization model. SatParameters DiversifySearchParameters(const SatParameters& params, const CpModelProto& cp_model, - const int worker_id, - int num_lns_threads); + const int worker_id); -// This methods update a given response with a new incoming response. +// This method updates a given response with a new incoming response. +// It returns true if the response is strictly improving upon the 'best' one. +// // TODO(user): Separate in two, 1 method for maintaining the best // intermediate solution, and one for cumulating the search statistics in // a final solution. diff --git a/ortools/sat/cp_model_solver.cc b/ortools/sat/cp_model_solver.cc index 0f0bd2cc6a..a2f3aeb7b9 100644 --- a/ortools/sat/cp_model_solver.cc +++ b/ortools/sat/cp_model_solver.cc @@ -283,8 +283,8 @@ class ModelWithMapping { // Recover from a IntervalVariable/BooleanVariable its associated CpModelProto // index. The value of -1 is used to indicate that there is no correspondence // (i.e. this variable is only used internally). - ITIVector reverse_boolean_map_; - ITIVector reverse_integer_map_; + gtl::ITIVector reverse_boolean_map_; + gtl::ITIVector reverse_integer_map_; // Used to return a feasible solution for the unused variables. std::vector lower_bounds_; @@ -2445,7 +2445,7 @@ CpSolverResponse SolveCpModelInternal( if (/* DISABLES CODE */ false && is_real_solve) { SatSolver* sat_solver = model->GetOrCreate(); SatPostsolver postsolver(sat_solver->NumVariables()); - ITIVector equiv_map; + gtl::ITIVector equiv_map; ProbeAndFindEquivalentLiteral(sat_solver, &postsolver, nullptr, &equiv_map); } diff --git a/ortools/sat/doc/channeling.md b/ortools/sat/doc/channeling.md index 4cd9655e1e..1d51f5d3cd 100644 --- a/ortools/sat/doc/channeling.md +++ b/ortools/sat/doc/channeling.md @@ -339,7 +339,7 @@ public class CodeSamplesSat static void Main() { - RabbitsAndPheasants(); + BinpackingProblem(); } } ``` diff --git a/ortools/sat/doc/index.md b/ortools/sat/doc/index.md index 279b696fb4..18f0498ad8 100644 --- a/ortools/sat/doc/index.md +++ b/ortools/sat/doc/index.md @@ -9,7 +9,7 @@ by type: - [integer arithmetic](integer_arithmetic.md) - [channeling constraints](channeling.md) - [scheduling](scheduling.md) -- [solving a CP-SAT model](solver.md) +- [Using the CP-SAT solver](solver.md) Code samples are given in C++ and python. Each language have different requirements for the code samples. @@ -39,8 +39,8 @@ The interface to the C++ CP-SAT solver is implemented through the **CpModelProto** class described in *ortools/sat/cp_model.proto*. -To help creating variables and constraints, we propose some inline helpers to -improve readability. +We provide some inline helper methods to simplify variable and constraint +creation. ```cpp #include "ortools/sat/cp_model.pb.h" @@ -69,7 +69,7 @@ void CodeSample() { ## C\# code samples -The C\# code implements the same interface as the python code, with a +The C\# code implements the same interface as the Python code, with a **CpModel**, and a **CpSolver** class. diff --git a/ortools/sat/doc/integer_arithmetic.md b/ortools/sat/doc/integer_arithmetic.md index 1580bdd1cd..130588977c 100644 --- a/ortools/sat/doc/integer_arithmetic.md +++ b/ortools/sat/doc/integer_arithmetic.md @@ -12,22 +12,22 @@ Integer variables are discrete variables ranging over 64 bit signed integer values. When creating them, a domain must be given. The format of this domain is a flattened list of disjoint intervals. -- To represent a continuous interval from 0 to 10, just pass a domain [0, 10]. +- To represent a interval from 0 to 10, just pass a domain [0, 10]. - To represent a single value (5), create a domain [5, 5]. - From these, it is easy to represent an enumerated list of values [-5, -4, -3, 1, 3, 4, 5, 6] is encoded as [-5, -3, 1, 1, 3, 6]. -- to exclude a single value, use int64 min and max values as in [int64min, -1, - 1, int64max]. +- To exclude a single value, use int64min and int64max values as in + [int64min, 4, 6, int64max]. ## Linear constraints -In **C++**, the only supported data structure is a linear constraints as in: +In **C++**, the model supports linear constraints as in: sum (a_i * x_i) in domain Where domain uses the same encoding as integer variables. -From this, usual modeling tricks can express general arithmetic constraints: +From this, the usual modeling tricks can express general arithmetic constraints: x > y @@ -40,10 +40,10 @@ can be rewritten as ## Rabbits and Pheasants examples -Let's solve a trivial example from children logic quizzes. +Let's solve a simple children's puzzle: the Rabbits and Pheasants problem. -We see rabbits and pheasants, we see 20 heads, and 56 legs. How many rabbits and -pheasants are there? +WIn a field of rabbits and pheasants, there are 20 heads and 56 legs. How many +rabbits and pheasants are there? ### Python code diff --git a/ortools/sat/doc/scheduling.md b/ortools/sat/doc/scheduling.md index f654c73aa3..3d3f0826a4 100644 --- a/ortools/sat/doc/scheduling.md +++ b/ortools/sat/doc/scheduling.md @@ -4,21 +4,20 @@ ## Introduction -Scheduling in Operations Research deals with tasks that times. In general, -scheduling problems have the following features: fixed or variable durations, -alternate ways of performing the same task, mutual exclusivity between tasks, -and temporal relations between tasks. +Scheduling in Operations Research involves problems of tasks, resources and +times. In general, scheduling problems have the following features: fixed or +variable durations, alternate ways of performing the same task, mutual +exclusivity between tasks, and temporal relations between tasks. ## Interval variables Intervals are constraints containing three integer variables (start, size, and end). Creating an interval constraint will enforce that start + size == end. -To create an interval, we need to create three variables, for the start, the -size, and the end of the interval. Then we create an interval constraint using -these three variables. +4:15PM, Jun 20 To define an interval, we need to create three variables: start, +size, and end.Then we create an interval constraint using these three variables. -We give two code snippets the demonstrate how to build these objects in python, +We give two code snippets the demonstrate how to build these objects in Python, C++, and C\#. ### Python code @@ -127,7 +126,7 @@ def OptionalIntervalSample(): model = cp_model.CpModel() horizon = 100 start_var = model.NewIntVar(0, horizon, 'start') - duration = 10 # Python cp/sat code accept integer variables or constants. + duration = 10 # Python CP-SAT code accepts integer variables or constants. end_var = model.NewIntVar(0, horizon, 'end') presence = model.NewBoolVar('presence') interval_var = model.NewOptionalIntervalVar(start_var, duration, end_var, @@ -220,7 +219,7 @@ public class CodeSamplesSat ## NoOverlap constraint -A no overlap constraints simply states that all intervals are disjoint. +A no overlap constraint simply states that all intervals are disjoint. ## Cumulative constraint diff --git a/ortools/sat/doc/solver.md b/ortools/sat/doc/solver.md index 409f65c17e..7dbd92160d 100644 --- a/ortools/sat/doc/solver.md +++ b/ortools/sat/doc/solver.md @@ -24,7 +24,7 @@ def MinimalCpSat(): x = model.NewIntVar(0, num_vals - 1, 'x') y = model.NewIntVar(0, num_vals - 1, 'y') z = model.NewIntVar(0, num_vals - 1, 'z') - # Adds an all-different constraint. + # Adds a different constraint. model.Add(x != y) # Creates a solver and solves the model. @@ -73,7 +73,7 @@ void SimpleSolve() { LOG(INFO) << CpSolverResponseStats(response); if (response.status() == CpSolverStatus::MODEL_SAT) { - // Get the value of x in the solution. + // Gets the value of x in the solution. const int64 value_x = response.solution(x); LOG(INFO) << "x = " << value_x; } @@ -145,7 +145,7 @@ def MinimalCpSatWithTimeLimit(): x = model.NewIntVar(0, num_vals - 1, 'x') y = model.NewIntVar(0, num_vals - 1, 'y') z = model.NewIntVar(0, num_vals - 1, 'z') - # Adds an all-different constraint. + # Adds a different constraint. model.Add(x != y) # Creates a solver and solves the model. @@ -197,13 +197,13 @@ void SolveWithTimeLimit() { parameters.set_max_time_in_seconds(10.0); model.Add(NewSatParameters(parameters)); - // Solve. + // Solves and print some model and solution statistics. LOG(INFO) << CpModelStats(cp_model); const CpSolverResponse response = SolveCpModel(cp_model, &model); LOG(INFO) << CpSolverResponseStats(response); if (response.status() == CpSolverStatus::MODEL_SAT) { - // Get the value of x in the solution. + // Gets the value of 'x' in the solution. const int64 value_x = response.solution(x); } } @@ -232,7 +232,7 @@ public class CodeSamplesSat IntVar x = model.NewIntVar(0, num_vals - 1, "x"); IntVar y = model.NewIntVar(0, num_vals - 1, "y"); IntVar z = model.NewIntVar(0, num_vals - 1, "z"); - // Creates the constraints. + // Adds a different constraint. model.Add(x != y); // Creates a solver and solves the model. @@ -271,7 +271,7 @@ The exact implementation depends on the target language. from ortools.sat.python import cp_model -# You need to subclass the cp_model.CpSolverSolutionCallback class. +# Subclass the cp_model.CpSolverSolutionCallback class. class VarArrayAndObjectiveSolutionPrinter(cp_model.CpSolverSolutionCallback): """Print intermediate solutions.""" @@ -300,8 +300,9 @@ def MinimalCpSatPrintIntermediateSolutions(): x = model.NewIntVar(0, num_vals - 1, 'x') y = model.NewIntVar(0, num_vals - 1, 'y') z = model.NewIntVar(0, num_vals - 1, 'z') - # Creates the constraints. + # Adds a different constraint. model.Add(x != y) + # Maximizes a linear combination of variables. model.Maximize(x + 2 * y + 3 * z) # Creates a solver and solves. @@ -438,9 +439,11 @@ public class CodeSamplesSat IntVar x = model.NewIntVar(0, num_vals - 1, 'x'); IntVar y = model.NewIntVar(0, num_vals - 1, 'y'); IntVar z = model.NewIntVar(0, num_vals - 1, 'z'); - // Creates the constraints. + + // Adds a different constraint. model.Add(x != y); - // Creates the objective. + + // Maximizes a linear combination of variables. model.Maximize(x + 2 * y + 3 * z); // Creates a solver and solves the model. @@ -498,13 +501,15 @@ def MinimalSatSearchForAllSolutions(): model = cp_model.CpModel() # Creates the variables. num_vals = 3 + x = model.NewIntVar(0, num_vals - 1, "x") y = model.NewIntVar(0, num_vals - 1, "y") z = model.NewIntVar(0, num_vals - 1, "z") - # Creates the constraint. + + # Adds a different constraint. model.Add(x != y) - # Creates a solver and solve. + # Creates a solver and solves. solver = cp_model.CpSolver() solution_printer = VarArraySolutionPrinter([x, y, z]) status = solver.SearchForAllSolutions(model, solution_printer) @@ -631,7 +636,8 @@ public class CodeSamplesSat IntVar x = model.NewIntVar(0, num_vals - 1, "x"); IntVar y = model.NewIntVar(0, num_vals - 1, "y"); IntVar z = model.NewIntVar(0, num_vals - 1, "z"); - // Creates the constraints. + + // Adds a different constraint. model.Add(x != y); // Creates a solver and solves the model. diff --git a/ortools/sat/drat_checker.h b/ortools/sat/drat_checker.h index 26a0724471..a1e4558725 100644 --- a/ortools/sat/drat_checker.h +++ b/ortools/sat/drat_checker.h @@ -222,7 +222,7 @@ class DratChecker { ClauseIndex first_infered_clause_index_; // The problem clauses, followed by the infered clauses. - ITIVector clauses_; + gtl::ITIVector clauses_; // A content addressable set of the non-deleted clauses in clauses_. After // adding a clause to clauses_, this set can be used to find if the same @@ -249,7 +249,7 @@ class DratChecker { // For each variable, the index of the unit clause that caused its assignment, // or kNoClauseIndex if the variable is not assigned, or was assigned to // falsify the clause that is currently being checked. - ITIVector assignment_source_; + gtl::ITIVector assignment_source_; // The stack of literals that remain to be assigned to true during boolean // constraint propagation, with high priority (unit clauses which are already @@ -272,7 +272,7 @@ class DratChecker { // satisfied (in more details: if a clause c is contained in // 'watched_literals_[l]' for literal l, then either c is satisfied with // 'assignment_', or l is unassigned or assigned to true). - ITIVector> watched_literals_; + gtl::ITIVector> watched_literals_; // The list of clauses with only one literal. This is needed for boolean // constraint propagation, in addition to watched literals, because watched diff --git a/ortools/sat/drat_proof_handler.cc b/ortools/sat/drat_proof_handler.cc index b91213efbd..e733207024 100644 --- a/ortools/sat/drat_proof_handler.cc +++ b/ortools/sat/drat_proof_handler.cc @@ -35,8 +35,8 @@ DratProofHandler::DratProofHandler(bool in_binary_format, File* output, } void DratProofHandler::ApplyMapping( - const ITIVector& mapping) { - ITIVector new_mapping; + const gtl::ITIVector& mapping) { + gtl::ITIVector new_mapping; for (BooleanVariable v(0); v < mapping.size(); ++v) { const BooleanVariable image = mapping[v]; if (image != kNoBooleanVariable) { diff --git a/ortools/sat/drat_proof_handler.h b/ortools/sat/drat_proof_handler.h index 6b632ca9f2..090457d2cc 100644 --- a/ortools/sat/drat_proof_handler.h +++ b/ortools/sat/drat_proof_handler.h @@ -55,7 +55,7 @@ class DratProofHandler { // // TODO(user): This is exactly the same mecanism as in the SatPostsolver // class. Factor out the code. - void ApplyMapping(const ITIVector& mapping); + void ApplyMapping(const gtl::ITIVector& mapping); // This need to be called when new variables are created. void SetNumVariables(int num_variables); @@ -101,7 +101,7 @@ class DratProofHandler { // This mapping will be applied to all clause passed to AddClause() or // DeleteClause() so that they are in term of the original problem. - ITIVector reverse_mapping_; + gtl::ITIVector reverse_mapping_; std::unique_ptr drat_checker_; std::unique_ptr drat_writer_; diff --git a/ortools/sat/integer.h b/ortools/sat/integer.h index 670577b5c7..4e185f9590 100644 --- a/ortools/sat/integer.h +++ b/ortools/sat/integer.h @@ -158,8 +158,8 @@ using InlinedIntegerLiteralVector = absl::InlinedVector; // A singleton that holds the INITIAL integer variable domains. struct IntegerDomains - : public ITIVector> { + : public gtl::ITIVector> { explicit IntegerDomains(Model* model) {} }; @@ -381,16 +381,17 @@ class IntegerEncoder { // We keep all the literals associated to an Integer variable in a map ordered // by bound (so we can properly add implications between the literals // corresponding to the same variable). - ITIVector> encoding_by_var_; + gtl::ITIVector> + encoding_by_var_; // Store for a given LiteralIndex the list of its associated IntegerLiterals. const InlinedIntegerLiteralVector empty_integer_literal_vector_; - ITIVector reverse_encoding_; + gtl::ITIVector reverse_encoding_; std::vector newly_fixed_integer_literals_; // Store for a given LiteralIndex its IntegerVariable view or kNoLiteralIndex // if there is none. - ITIVector literal_view_; + gtl::ITIVector literal_view_; // Mapping (variable == value) -> associated literal. Note that even if // there is more than one literal associated to the same fact, we just keep @@ -399,7 +400,7 @@ class IntegerEncoder { equality_to_associated_literal_; // Variables that are fully encoded. - ITIVector is_fully_encoded_; + gtl::ITIVector is_fully_encoded_; // A literal that is always true, convenient to encode trivial domains. // This will be lazily created when needed. @@ -674,13 +675,13 @@ class IntegerTrail : public SatPropagator { // Trail index of the last TrailEntry in the trail refering to this var. int current_trail_index; }; - ITIVector vars_; + gtl::ITIVector vars_; // This is used by FindLowestTrailIndexThatExplainBound() to speed up // the lookup. It keeps a trail index for each variable that may or may not // point to a TrailEntry regarding this variable. The validity of the index is // verified before beeing used. - mutable ITIVector var_trail_index_cache_; + mutable gtl::ITIVector var_trail_index_cache_; // Used by GetOrCreateConstantIntegerVariable() to return already created // constant variables that share the same value. @@ -714,7 +715,7 @@ class IntegerTrail : public SatPropagator { mutable std::vector bounds_reason_buffer_; // The "is_ignored" literal of the optional variables or kNoLiteralIndex. - ITIVector is_ignored_literals_; + gtl::ITIVector is_ignored_literals_; // This is only filled for variables with a domain more complex than a single // interval of values. All intervals are stored in a vector, and we keep @@ -735,7 +736,7 @@ class IntegerTrail : public SatPropagator { // Temporary data used by MergeReasonInto(). mutable std::vector tmp_queue_; mutable std::vector tmp_to_clear_; - mutable ITIVector tmp_var_to_trail_index_in_queue_; + mutable gtl::ITIVector tmp_var_to_trail_index_in_queue_; mutable SparseBitset added_variables_; // For EnqueueLiteral(), we store a special TrailEntry to recover the reason @@ -889,8 +890,8 @@ class GenericLiteralWatcher : public SatPropagator { int id; int watch_index; }; - ITIVector> literal_to_watcher_; - ITIVector> var_to_watcher_; + gtl::ITIVector> literal_to_watcher_; + gtl::ITIVector> var_to_watcher_; std::vector watchers_; SparseBitset modified_vars_; diff --git a/ortools/sat/intervals.h b/ortools/sat/intervals.h index ab0c7a78a8..4721fcc721 100644 --- a/ortools/sat/intervals.h +++ b/ortools/sat/intervals.h @@ -98,13 +98,13 @@ class IntervalsRepository { // Literal indicating if the tasks is executed. Tasks that are always executed // will have a kNoLiteralIndex entry in this vector. - ITIVector is_present_; + gtl::ITIVector is_present_; // The integer variables for each tasks. - ITIVector start_vars_; - ITIVector end_vars_; - ITIVector size_vars_; - ITIVector fixed_sizes_; + gtl::ITIVector start_vars_; + gtl::ITIVector end_vars_; + gtl::ITIVector size_vars_; + gtl::ITIVector fixed_sizes_; DISALLOW_COPY_AND_ASSIGN(IntervalsRepository); }; diff --git a/ortools/sat/lns.h b/ortools/sat/lns.h index e5d077098e..4ca407e462 100644 --- a/ortools/sat/lns.h +++ b/ortools/sat/lns.h @@ -91,21 +91,27 @@ inline void OptimizeWithLNS( int64 seed = 0; #if !defined(__PORTABLE_PLATFORM__) while (!stop_function()) { - std::vector> update_functions(num_threads); - { - ThreadPool pool("Parallel_LNS", num_threads); - pool.StartWorkers(); - for (int i = 0; i < num_threads; ++i) { - pool.Schedule( - [&update_functions, &generate_and_solve_function, i, seed]() { - update_functions[i] = generate_and_solve_function(seed + i); - }); + if (num_threads > 1) { + std::vector> update_functions(num_threads); + { + ThreadPool pool("Parallel_LNS", num_threads); + pool.StartWorkers(); + for (int i = 0; i < num_threads; ++i) { + pool.Schedule( + [&update_functions, &generate_and_solve_function, i, seed]() { + update_functions[i] = generate_and_solve_function(seed + i); + }); + } } - } - seed += num_threads; - for (int i = 0; i < num_threads; ++i) { - update_functions[i](); + seed += num_threads; + for (int i = 0; i < num_threads; ++i) { + update_functions[i](); + } + } else { + std::function update_function = + generate_and_solve_function(seed++); + update_function(); } } #else // __PORTABLE_PLATFORM__ diff --git a/ortools/sat/pb_constraint.cc b/ortools/sat/pb_constraint.cc index 1597fb3d54..0b285c32f1 100644 --- a/ortools/sat/pb_constraint.cc +++ b/ortools/sat/pb_constraint.cc @@ -99,9 +99,10 @@ bool ComputeBooleanLinearExpressionCanonicalForm( return true; } -bool ApplyLiteralMapping(const ITIVector& mapping, - std::vector* cst, - Coefficient* bound_shift, Coefficient* max_value) { +bool ApplyLiteralMapping( + const gtl::ITIVector& mapping, + std::vector* cst, Coefficient* bound_shift, + Coefficient* max_value) { int index = 0; Coefficient shift_due_to_fixed_variables(0); for (const LiteralWithCoeff& entry : *cst) { @@ -1085,7 +1086,7 @@ void PbConstraints::UpdateActivityIncrement() { } void PbConstraints::DeleteConstraintMarkedForDeletion() { - ITIVector index_mapping( + gtl::ITIVector index_mapping( constraints_.size(), ConstraintIndex(-1)); ConstraintIndex new_index(0); for (ConstraintIndex i(0); i < constraints_.size(); ++i) { diff --git a/ortools/sat/pb_constraint.h b/ortools/sat/pb_constraint.h index 24cfc4fb66..e378b778e9 100644 --- a/ortools/sat/pb_constraint.h +++ b/ortools/sat/pb_constraint.h @@ -92,9 +92,10 @@ bool ComputeBooleanLinearExpressionCanonicalForm( // // Finally, this will return false if some integer overflow or underflow // occurred during the constraint simplification. -bool ApplyLiteralMapping(const ITIVector& mapping, - std::vector* cst, - Coefficient* bound_shift, Coefficient* max_value); +bool ApplyLiteralMapping( + const gtl::ITIVector& mapping, + std::vector* cst, Coefficient* bound_shift, + Coefficient* max_value); // From a constraint 'expr <= ub' and the result (bound_shift, max_value) of // calling ComputeBooleanLinearExpressionCanonicalForm() on 'expr', this returns @@ -317,7 +318,7 @@ class MutableUpperBoundedLinearConstraint { // The encoding is special: // - If terms_[x] > 0, then the associated term is 'terms_[x] . x' // - If terms_[x] < 0, then the associated term is 'terms_[x] . (x - 1)' - ITIVector terms_; + gtl::ITIVector terms_; // The right hand side of the constraint (sum terms <= rhs_). Coefficient rhs_; @@ -639,11 +640,12 @@ class PbConstraints : public SatPropagator { std::vector> constraints_; // The current value of the threshold for each constraints. - ITIVector thresholds_; + gtl::ITIVector thresholds_; // For each literal, the list of all the constraints that contains it together // with the literal coefficient in these constraints. - ITIVector> to_update_; + gtl::ITIVector> + to_update_; // Bitset used to optimize the Untrail() function. SparseBitset to_untrail_; @@ -712,7 +714,7 @@ class VariableWithSameReasonIdentifier { private: const Trail& trail_; - ITIVector first_variable_; + gtl::ITIVector first_variable_; SparseBitset seen_; DISALLOW_COPY_AND_ASSIGN(VariableWithSameReasonIdentifier); diff --git a/ortools/sat/precedences.cc b/ortools/sat/precedences.cc index eb9536f95c..bb277c0220 100644 --- a/ortools/sat/precedences.cc +++ b/ortools/sat/precedences.cc @@ -695,7 +695,7 @@ void PrecedencesPropagator::AddGreaterThanAtLeastOneOfConstraints( SatSolver* solver = model->GetOrCreate(); // Fill the set of incoming conditional arcs for each variables. - ITIVector> incoming_arcs_; + gtl::ITIVector> incoming_arcs_; for (ArcIndex arc_index(0); arc_index < arcs_.size(); ++arc_index) { const ArcInfo& arc = arcs_[arc_index]; diff --git a/ortools/sat/precedences.h b/ortools/sat/precedences.h index b2d9c0ee54..d93809aef4 100644 --- a/ortools/sat/precedences.h +++ b/ortools/sat/precedences.h @@ -217,20 +217,20 @@ class PrecedencesPropagator : public SatPropagator, PropagatorInterface { // consecutive like in StaticGraph should have a big performance impact. // // TODO(user): We do not need to store ArcInfo.tail_var here. - ITIVector> impacted_arcs_; - ITIVector arcs_; + gtl::ITIVector> impacted_arcs_; + gtl::ITIVector arcs_; // This is similar to impacted_arcs_/arcs_ but it is only used to propagate // one of the presence literals when the arc cannot be present. An arc needs // to appear only once in potential_arcs_, but it will be referenced by // all its variable in impacted_potential_arcs_. - ITIVector> + gtl::ITIVector> impacted_potential_arcs_; - ITIVector potential_arcs_; + gtl::ITIVector potential_arcs_; // Temporary vectors used by ComputePrecedences(). - ITIVector var_to_degree_; - ITIVector var_to_last_index_; + gtl::ITIVector var_to_degree_; + gtl::ITIVector var_to_last_index_; struct SortedVar { IntegerVariable var; IntegerValue lower_bound; @@ -248,9 +248,9 @@ class PrecedencesPropagator : public SatPropagator, PropagatorInterface { // // TODO(user): Try a one-watcher approach instead. Note that in most cases // arc should be controlled by 1 or 2 literals, so not sure it is worth it. - ITIVector> + gtl::ITIVector> literal_to_new_impacted_arcs_; - ITIVector arc_counts_; + gtl::ITIVector arc_counts_; // Temp vectors to hold the reason of an assignment. std::vector literal_reason_; diff --git a/ortools/sat/sat_base.h b/ortools/sat/sat_base.h index fbeed0be02..f35beaa797 100644 --- a/ortools/sat/sat_base.h +++ b/ortools/sat/sat_base.h @@ -389,11 +389,11 @@ class Trail { VariablesAssignment assignment_; std::vector trail_; std::vector conflict_; - ITIVector info_; + gtl::ITIVector info_; SatClause* failing_sat_clause_; // Data used by EnqueueWithSameReasonAs(). - ITIVector + gtl::ITIVector reference_var_with_same_reason_as_; // Reason cache. Mutable since we want the API to be the same whether the @@ -420,8 +420,8 @@ class Trail { // variables, the memory address of the vectors (kept in reasons_) are still // valid. mutable std::deque> reasons_repository_; - mutable ITIVector> reasons_; - mutable ITIVector old_type_; + mutable gtl::ITIVector> reasons_; + mutable gtl::ITIVector old_type_; // This is used by RegisterPropagator() and Reason(). std::vector propagators_; diff --git a/ortools/sat/sat_decision.h b/ortools/sat/sat_decision.h index c5a3bf1228..ea2732f955 100644 --- a/ortools/sat/sat_decision.h +++ b/ortools/sat/sat_decision.h @@ -182,17 +182,17 @@ class SatDecisionPolicy { // Stores variable activity and the number of time each variable was "bumped". // The later is only used with the ERWA heuristic. - ITIVector activities_; - ITIVector tie_breakers_; - ITIVector num_bumps_; + gtl::ITIVector activities_; + gtl::ITIVector tie_breakers_; + gtl::ITIVector num_bumps_; // Used by NextBranch() to choose the polarity of the next decision. For the // phase saving, the last polarity is stored in trail_->Info(var). - ITIVector var_use_phase_saving_; - ITIVector var_polarity_; + gtl::ITIVector var_use_phase_saving_; + gtl::ITIVector var_polarity_; // Used in initial polarity computation. - ITIVector weighted_sign_; + gtl::ITIVector weighted_sign_; }; } // namespace sat diff --git a/ortools/sat/sat_parameters.proto b/ortools/sat/sat_parameters.proto index 9e4390e7e9..d7846a6b89 100644 --- a/ortools/sat/sat_parameters.proto +++ b/ortools/sat/sat_parameters.proto @@ -18,7 +18,7 @@ package operations_research.sat; // Contains the definitions for all the sat algorithm parameters and their // default values. // -// NEXT TAG: 106 +// NEXT TAG: 105 message SatParameters { // ========================================================================== // Branching and polarity @@ -568,14 +568,13 @@ message SatParameters { // Specify the number of parallel workers to use during search. // A number <= 1 means no parallelism. optional int32 num_search_workers = 100 [default = 0]; - optional bool deterministic_search = 101 [default = true]; // LNS parameters. - optional bool use_lns = 102 [default = false]; - optional int32 lns_num_threads = 103 [default = 1]; + optional bool use_lns = 101 [default = false]; + optional int32 lns_num_threads = 102 [default = 1]; // Randomize fixed search. - optional bool randomize_search = 104 [default = false]; + optional bool randomize_search = 103 [default = false]; // Search randomization will collect equivalent 'max valued' variables, and // pick one randomly. For instance, if the variable strategy is CHOOSE_FIRST, @@ -584,5 +583,5 @@ message SatParameters { // variables, then the set of max valued variables will be all unassigned // variables where // lm <= variable min <= lm + search_randomization_tolerance - optional int64 search_randomization_tolerance = 105 [default = 0]; + optional int64 search_randomization_tolerance = 104 [default = 0]; } diff --git a/ortools/sat/simplification.cc b/ortools/sat/simplification.cc index 5944633d86..4b5cfbd3da 100644 --- a/ortools/sat/simplification.cc +++ b/ortools/sat/simplification.cc @@ -56,8 +56,8 @@ void SatPostsolver::FixVariable(Literal x) { } void SatPostsolver::ApplyMapping( - const ITIVector& mapping) { - ITIVector new_mapping; + const gtl::ITIVector& mapping) { + gtl::ITIVector new_mapping; if (reverse_mapping_.size() < mapping.size()) { // We have new variables. while (reverse_mapping_.size() < mapping.size()) { @@ -231,9 +231,9 @@ void SatPresolver::AddClauseInternal(std::vector* clause) { } } -ITIVector SatPresolver::VariableMapping() +gtl::ITIVector SatPresolver::VariableMapping() const { - ITIVector result; + gtl::ITIVector result; BooleanVariable new_var(0); for (BooleanVariable var(0); var < NumVariables(); ++var) { if (literal_to_clause_sizes_[Literal(var, true).Index()] > 0 || @@ -256,7 +256,8 @@ void SatPresolver::LoadProblemIntoSatSolver(SatSolver* solver) { clause_to_process_.clear(); literal_to_clauses_.clear(); - const ITIVector mapping = VariableMapping(); + const gtl::ITIVector mapping = + VariableMapping(); int new_size = 0; for (BooleanVariable index : mapping) { if (index != kNoBooleanVariable) ++new_size; @@ -1018,7 +1019,7 @@ class PropagationGraph { void ProbeAndFindEquivalentLiteral( SatSolver* solver, SatPostsolver* postsolver, DratProofHandler* drat_proof_handler, - ITIVector* mapping) { + gtl::ITIVector* mapping) { solver->Backtrack(0); mapping->clear(); const int num_already_fixed_vars = solver->LiteralTrail().Index(); @@ -1187,7 +1188,7 @@ SatSolver::Status SolveWithPresolve(std::unique_ptr* solver, // Probe + find equivalent literals. // TODO(user): Use a derived time limit in the probing phase. - ITIVector equiv_map; + gtl::ITIVector equiv_map; ProbeAndFindEquivalentLiteral((*solver).get(), &postsolver, drat_proof_handler, &equiv_map); if ((*solver)->IsModelUnsat()) { diff --git a/ortools/sat/simplification.h b/ortools/sat/simplification.h index b61fe1e0f6..9dafa65251 100644 --- a/ortools/sat/simplification.h +++ b/ortools/sat/simplification.h @@ -68,7 +68,8 @@ class SatPostsolver { // // This can be called more than once. But each call must refer to the current // variables set (after all the previous mapping have been applied). - void ApplyMapping(const ITIVector& mapping); + void ApplyMapping( + const gtl::ITIVector& mapping); // Extracts the current assignment of the given solver and postsolve it. // @@ -109,7 +110,7 @@ class SatPostsolver { // All the added clauses will be mapped back to the initial variables using // this reverse mapping. This way, clauses_ and associated_literal_ are only // in term of the initial problem. - ITIVector reverse_mapping_; + gtl::ITIVector reverse_mapping_; // This will stores the fixed variables value and later the postsolved // assignment. @@ -146,7 +147,7 @@ class SatPresolver { // Registers a mapping to encode equivalent literals. // See ProbeAndFindEquivalentLiteral(). void SetEquivalentLiteralMapping( - const ITIVector& mapping) { + const gtl::ITIVector& mapping) { equiv_mapping_ = mapping; } @@ -181,7 +182,7 @@ class SatPresolver { // clause pointing to them. This return a mapping that maps this interval to // [0, new_size) such that now all variables are used. The unused variable // will be mapped to BooleanVariable(-1). - ITIVector VariableMapping() const; + gtl::ITIVector VariableMapping() const; // Loads the current presolved problem in to the given sat solver. // Note that the variables will be re-indexed according to the mapping given @@ -273,7 +274,7 @@ class SatPresolver { BooleanVariable variable; double weight; }; - ITIVector var_pq_elements_; + gtl::ITIVector var_pq_elements_; AdjustablePriorityQueue var_pq_; // Literal priority queue for BVA. The literals are ordered by descending @@ -304,7 +305,7 @@ class SatPresolver { // Temporary data for SimpleBva(). std::set m_lit_; std::vector m_cls_; - ITIVector literal_to_p_size_; + gtl::ITIVector literal_to_p_size_; std::vector> flattened_p_; std::vector tmp_new_clause_; @@ -319,17 +320,17 @@ class SatPresolver { // Occurrence list. For each literal, contains the ClauseIndex of the clause // that contains it (ordered by clause index). - ITIVector> literal_to_clauses_; + gtl::ITIVector> literal_to_clauses_; // Because we only lazily clean the occurrence list after clause deletions, // we keep the size of the occurrence list (without the deleted clause) here. - ITIVector literal_to_clause_sizes_; + gtl::ITIVector literal_to_clause_sizes_; // Used for postsolve. SatPostsolver* postsolver_; // Equivalent literal mapping. - ITIVector equiv_mapping_; + gtl::ITIVector equiv_mapping_; int num_trivial_clauses_; SatParameters parameters_; @@ -388,7 +389,7 @@ int ComputeResolvantSize(Literal x, const std::vector& a, void ProbeAndFindEquivalentLiteral( SatSolver* solver, SatPostsolver* postsolver, DratProofHandler* drat_proof_handler, - ITIVector* mapping); + gtl::ITIVector* mapping); // Given a 'solver' with a problem already loaded, this will try to simplify the // problem (i.e. presolve it) before calling solver->Solve(). In the process, diff --git a/ortools/sat/symmetry.h b/ortools/sat/symmetry.h index c87bd7ba3b..4b0aa910f4 100644 --- a/ortools/sat/symmetry.h +++ b/ortools/sat/symmetry.h @@ -109,7 +109,7 @@ class SymmetryPropagator : public SatPropagator { int permutation_index; Literal image; }; - ITIVector> images_; + gtl::ITIVector> images_; // For each permutation p, we maintain the list of all assigned literals // affected by p whose trail index is < propagation_trail_index_; sorted by @@ -140,7 +140,7 @@ class SymmetryPropagator : public SatPropagator { // The identity permutation over all the literals. // This is temporary modified to encode a sparse permutation and then always // restored to the identity. - mutable ITIVector tmp_literal_mapping_; + mutable gtl::ITIVector tmp_literal_mapping_; // Symmetry reason indexed by trail_index. struct ReasonInfo {