Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
|
Typedefs | |
using | InlinedIntegerLiteralVector = absl::InlinedVector<IntegerLiteral, 2> |
using | InlinedIntegerValueVector |
using | IntegerSumLE = LinearConstraintPropagator<false> |
using | IntegerSumLE128 = LinearConstraintPropagator<true> |
Enumerations | |
enum | SatFormat { DIMACS , DRAT } |
The file formats that can be used to save a list of clauses. More... | |
enum class | EnforcementStatus { IS_FALSE = 0 , CANNOT_PROPAGATE = 1 , CAN_PROPAGATE = 2 , IS_ENFORCED = 3 } |
Functions | |
void | SolveFzWithCpModelProto (const fz::Model &fz_model, const fz::FlatzincSatParameters &p, const std::string &sat_params, SolverLogger *logger, SolverLogger *solution_logger) |
std::vector< Rectangle > | GenerateNonConflictingRectangles (int num_rectangles, absl::BitGenRef random) |
std::vector< RectangleInRange > | MakeItemsFromRectangles (absl::Span< const Rectangle > rectangles, double slack_factor, absl::BitGenRef random) |
std::vector< ItemForPairwiseRestriction > | GenerateItemsRectanglesWithNoPairwiseConflict (const std::vector< Rectangle > &rectangles, double slack_factor, absl::BitGenRef random) |
std::vector< ItemForPairwiseRestriction > | GenerateItemsRectanglesWithNoPairwisePropagation (int num_rectangles, double slack_factor, absl::BitGenRef random) |
bool | Preprocess (absl::Span< PermutableItem > &items, std::pair< IntegerValue, IntegerValue > &bounding_box_size, int max_complexity) |
Exposed for testing. | |
BruteForceResult | BruteForceOrthogonalPacking (absl::Span< const IntegerValue > sizes_x, absl::Span< const IntegerValue > sizes_y, std::pair< IntegerValue, IntegerValue > bounding_box_size, int max_complexity) |
bool | PresolveFixed2dRectangles (absl::Span< const RectangleInRange > non_fixed_boxes, std::vector< Rectangle > *fixed_boxes) |
bool | ReduceNumberofBoxes (std::vector< Rectangle > *mandatory_rectangles, std::vector< Rectangle > *optional_rectangles) |
std::function< void(Model *)> | AllDifferentBinary (const std::vector< IntegerVariable > &vars) |
std::function< void(Model *)> | AllDifferentOnBounds (const std::vector< AffineExpression > &expressions) |
std::function< void(Model *)> | AllDifferentOnBounds (const std::vector< IntegerVariable > &vars) |
std::function< void(Model *)> | AllDifferentAC (const std::vector< IntegerVariable > &variables) |
void | ExtractAssignment (const LinearBooleanProblem &problem, const SatSolver &solver, std::vector< bool > *assignment) |
absl::Status | ValidateBooleanProblem (const LinearBooleanProblem &problem) |
CpModelProto | BooleanProblemToCpModelproto (const LinearBooleanProblem &problem) |
void | ChangeOptimizationDirection (LinearBooleanProblem *problem) |
bool | LoadBooleanProblem (const LinearBooleanProblem &problem, SatSolver *solver) |
Loads a BooleanProblem into a given SatSolver instance. | |
bool | LoadAndConsumeBooleanProblem (LinearBooleanProblem *problem, SatSolver *solver) |
void | UseObjectiveForSatAssignmentPreference (const LinearBooleanProblem &problem, SatSolver *solver) |
bool | AddObjectiveUpperBound (const LinearBooleanProblem &problem, Coefficient upper_bound, SatSolver *solver) |
Adds the constraint that the objective is smaller than the given upper bound. | |
bool | AddObjectiveConstraint (const LinearBooleanProblem &problem, bool use_lower_bound, Coefficient lower_bound, bool use_upper_bound, Coefficient upper_bound, SatSolver *solver) |
Coefficient | ComputeObjectiveValue (const LinearBooleanProblem &problem, const std::vector< bool > &assignment) |
Returns the objective value under the current assignment. | |
bool | IsAssignmentValid (const LinearBooleanProblem &problem, const std::vector< bool > &assignment) |
Checks that an assignment is valid for the given BooleanProblem. | |
std::string | LinearBooleanProblemToCnfString (const LinearBooleanProblem &problem) |
void | StoreAssignment (const VariablesAssignment &assignment, BooleanAssignment *output) |
void | ExtractSubproblem (const LinearBooleanProblem &problem, const std::vector< int > &constraint_indices, LinearBooleanProblem *subproblem) |
Constructs a sub-problem formed by the constraints with given indices. | |
template<typename Graph > | |
Graph * | GenerateGraphForSymmetryDetection (const LinearBooleanProblem &problem, std::vector< int > *initial_equivalence_classes) |
void | MakeAllLiteralsPositive (LinearBooleanProblem *problem) |
void | FindLinearBooleanProblemSymmetries (const LinearBooleanProblem &problem, std::vector< std::unique_ptr< SparsePermutation > > *generators) |
void | ApplyLiteralMappingToBooleanProblem (const util_intops::StrongVector< LiteralIndex, LiteralIndex > &mapping, LinearBooleanProblem *problem) |
void | ProbeAndSimplifyProblem (SatPostsolver *postsolver, LinearBooleanProblem *problem) |
double | AddOffsetAndScaleObjectiveValue (const LinearBooleanProblem &problem, Coefficient v) |
Adds the offset and returns the scaled version of the given objective value. | |
std::function< void(Model *)> | ExactlyOnePerRowAndPerColumn (const std::vector< std::vector< Literal > > &graph) |
void | LoadSubcircuitConstraint (int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< Literal > &literals, Model *model, bool multiple_subcircuit_through_zero) |
std::function< void(Model *)> | CircuitCovering (const std::vector< std::vector< Literal > > &graph, const std::vector< int > &distinguished_nodes) |
template<class IntContainer > | |
int | ReindexArcs (IntContainer *tails, IntContainer *heads, absl::flat_hash_map< int, int > *mapping_output=nullptr) |
int64_t | OverlapOfTwoIntervals (const ConstraintProto &interval1, const ConstraintProto &interval2, absl::Span< const int64_t > solution) |
--— CompiledNoOverlap2dConstraint --— | |
int64_t | NoOverlapMinRepairDistance (const ConstraintProto &interval1, const ConstraintProto &interval2, absl::Span< const int64_t > solution) |
void | AddCircuitFlowConstraints (LinearIncrementalEvaluator &linear_evaluator, const ConstraintProto &ct_proto) |
std::vector< IntegerValue > | ToIntegerValueVector (const std::vector< int64_t > &input) |
std::function< void(Model *)> | LiteralXorIs (const std::vector< Literal > &literals, bool value) |
Enforces the XOR of a set of literals to be equal to the given value. | |
std::function< void(Model *)> | GreaterThanAtLeastOneOf (IntegerVariable target_var, const absl::Span< const IntegerVariable > vars, const absl::Span< const IntegerValue > offsets, const absl::Span< const Literal > selectors, const absl::Span< const Literal > enforcements) |
std::function< void(Model *)> | PartialIsOneOfVar (IntegerVariable target_var, const std::vector< IntegerVariable > &vars, const std::vector< Literal > &selectors) |
BoolVar | Not (BoolVar x) |
std::ostream & | operator<< (std::ostream &os, const BoolVar &var) |
std::string | VarDebugString (const CpModelProto &proto, int index) |
std::ostream & | operator<< (std::ostream &os, const IntVar &var) |
std::ostream & | operator<< (std::ostream &os, const LinearExpr &e) |
std::ostream & | operator<< (std::ostream &os, const DoubleLinearExpr &e) |
std::ostream & | operator<< (std::ostream &os, const IntervalVar &var) |
int64_t | SolutionIntegerValue (const CpSolverResponse &r, const LinearExpr &expr) |
Evaluates the value of an linear expression in a solver response. | |
bool | SolutionBooleanValue (const CpSolverResponse &r, BoolVar x) |
Evaluates the value of a Boolean literal in a solver response. | |
template<typename H > | |
H | AbslHashValue (H h, const IntVar &i) |
– ABSL HASHING SUPPORT --------------------------------------------------— | |
template<typename H > | |
H | AbslHashValue (H h, const IntervalVar &i) |
LinearExpr | operator- (LinearExpr expr) |
LinearExpr | operator+ (const LinearExpr &lhs, const LinearExpr &rhs) |
LinearExpr | operator+ (LinearExpr &&lhs, const LinearExpr &rhs) |
LinearExpr | operator+ (const LinearExpr &lhs, LinearExpr &&rhs) |
LinearExpr | operator+ (LinearExpr &&lhs, LinearExpr &&rhs) |
LinearExpr | operator- (const LinearExpr &lhs, const LinearExpr &rhs) |
LinearExpr | operator- (LinearExpr &&lhs, const LinearExpr &rhs) |
LinearExpr | operator- (const LinearExpr &lhs, LinearExpr &&rhs) |
LinearExpr | operator- (LinearExpr &&lhs, LinearExpr &&rhs) |
LinearExpr | operator* (LinearExpr expr, int64_t factor) |
LinearExpr | operator* (int64_t factor, LinearExpr expr) |
DoubleLinearExpr | operator- (DoubleLinearExpr expr) |
For DoubleLinearExpr. | |
DoubleLinearExpr | operator+ (const DoubleLinearExpr &lhs, const DoubleLinearExpr &rhs) |
DoubleLinearExpr | operator+ (DoubleLinearExpr &&lhs, const DoubleLinearExpr &rhs) |
DoubleLinearExpr | operator+ (const DoubleLinearExpr &lhs, DoubleLinearExpr &&rhs) |
DoubleLinearExpr | operator+ (DoubleLinearExpr &&lhs, DoubleLinearExpr &&rhs) |
DoubleLinearExpr | operator+ (DoubleLinearExpr expr, double rhs) |
DoubleLinearExpr | operator+ (double lhs, DoubleLinearExpr expr) |
DoubleLinearExpr | operator- (const DoubleLinearExpr &lhs, const DoubleLinearExpr &rhs) |
DoubleLinearExpr | operator- (DoubleLinearExpr &&lhs, const DoubleLinearExpr &rhs) |
DoubleLinearExpr | operator- (const DoubleLinearExpr &lhs, DoubleLinearExpr &&rhs) |
DoubleLinearExpr | operator- (DoubleLinearExpr &&lhs, DoubleLinearExpr &&rhs) |
DoubleLinearExpr | operator- (DoubleLinearExpr epxr, double rhs) |
DoubleLinearExpr | operator- (double lhs, DoubleLinearExpr expr) |
DoubleLinearExpr | operator* (DoubleLinearExpr expr, double factor) |
DoubleLinearExpr | operator* (double factor, DoubleLinearExpr expr) |
bool | PossibleIntegerOverflow (const CpModelProto &model, absl::Span< const int > vars, absl::Span< const int64_t > coeffs, int64_t offset) |
std::string | ValidateCpModel (const CpModelProto &model, bool after_presolve) |
std::string | ValidateInputCpModel (const SatParameters ¶ms, const CpModelProto &model) |
bool | ConstraintIsFeasible (const CpModelProto &model, const ConstraintProto &constraint, absl::Span< const int64_t > variable_values) |
bool | SolutionIsFeasible (const CpModelProto &model, absl::Span< const int64_t > variable_values, const CpModelProto *mapping_proto, const std::vector< int > *postsolve_mapping) |
void | PropagateAutomaton (const AutomatonConstraintProto &proto, const PresolveContext &context, std::vector< absl::flat_hash_set< int64_t > > *states, std::vector< absl::flat_hash_set< int64_t > > *labels) |
Fills and propagates the set of reachable states/labels. | |
void | ExpandCpModel (PresolveContext *context) |
void | FinalExpansionForLinearConstraint (PresolveContext *context) |
Neighborhood | GenerateSchedulingNeighborhoodFromIntervalPrecedences (const absl::Span< const std::pair< int, int > > precedences, const CpSolverResponse &initial_solution, const NeighborhoodGeneratorHelper &helper) |
Neighborhood | GenerateSchedulingNeighborhoodFromRelaxedIntervals (absl::Span< const int > intervals_to_relax, absl::Span< const int > variables_to_fix, const CpSolverResponse &initial_solution, absl::BitGenRef random, const NeighborhoodGeneratorHelper &helper) |
void | LoadVariables (const CpModelProto &model_proto, bool view_all_booleans_as_integers, Model *m) |
void | LoadBooleanSymmetries (const CpModelProto &model_proto, Model *m) |
void | ExtractEncoding (const CpModelProto &model_proto, Model *m) |
void | ExtractElementEncoding (const CpModelProto &model_proto, Model *m) |
void | PropagateEncodingFromEquivalenceRelations (const CpModelProto &model_proto, Model *m) |
void | DetectOptionalVariables (const CpModelProto &model_proto, Model *m) |
Automatically detect optional variables. | |
void | AddFullEncodingFromSearchBranching (const CpModelProto &model_proto, Model *m) |
void | LoadBoolOrConstraint (const ConstraintProto &ct, Model *m) |
void | LoadBoolAndConstraint (const ConstraintProto &ct, Model *m) |
void | LoadAtMostOneConstraint (const ConstraintProto &ct, Model *m) |
void | LoadExactlyOneConstraint (const ConstraintProto &ct, Model *m) |
void | LoadBoolXorConstraint (const ConstraintProto &ct, Model *m) |
void | SplitAndLoadIntermediateConstraints (bool lb_required, bool ub_required, std::vector< IntegerVariable > *vars, std::vector< int64_t > *coeffs, Model *m) |
void | LoadLinearConstraint (const ConstraintProto &ct, Model *m) |
void | LoadAllDiffConstraint (const ConstraintProto &ct, Model *m) |
void | LoadIntProdConstraint (const ConstraintProto &ct, Model *m) |
void | LoadIntDivConstraint (const ConstraintProto &ct, Model *m) |
void | LoadIntModConstraint (const ConstraintProto &ct, Model *m) |
void | LoadLinMaxConstraint (const ConstraintProto &ct, Model *m) |
void | LoadNoOverlapConstraint (const ConstraintProto &ct, Model *m) |
void | LoadNoOverlap2dConstraint (const ConstraintProto &ct, Model *m) |
void | LoadCumulativeConstraint (const ConstraintProto &ct, Model *m) |
void | LoadReservoirConstraint (const ConstraintProto &ct, Model *m) |
void | LoadCircuitConstraint (const ConstraintProto &ct, Model *m) |
void | LoadRoutesConstraint (const ConstraintProto &ct, Model *m) |
bool | LoadConstraint (const ConstraintProto &ct, Model *m) |
void | LoadIntMinConstraint (const ConstraintProto &ct, Model *m) |
void | LoadIntMaxConstraint (const ConstraintProto &ct, Model *m) |
void | LoadCircuitCoveringConstraint (const ConstraintProto &ct, Model *m) |
void | PostsolveClause (const ConstraintProto &ct, std::vector< Domain > *domains) |
void | PostsolveExactlyOne (const ConstraintProto &ct, std::vector< Domain > *domains) |
void | SetEnforcementLiteralToFalse (const ConstraintProto &ct, std::vector< Domain > *domains) |
void | PostsolveLinear (const ConstraintProto &ct, std::vector< Domain > *domains) |
void | PostsolveLinMax (const ConstraintProto &ct, std::vector< Domain > *domains) |
void | PostsolveElement (const ConstraintProto &ct, std::vector< Domain > *domains) |
We only support 3 cases in the presolve currently. | |
void | PostsolveIntMod (const ConstraintProto &ct, std::vector< Domain > *domains) |
We only support assigning to an affine target. | |
void | PostsolveResponse (const int64_t num_variables_in_original_model, const CpModelProto &mapping_proto, const std::vector< int > &postsolve_mapping, std::vector< int64_t > *solution) |
void | FillTightenedDomainInResponse (const CpModelProto &original_model, const CpModelProto &mapping_proto, const std::vector< int > &postsolve_mapping, const std::vector< Domain > &search_domains, CpSolverResponse *response, SolverLogger *logger) |
bool | ImportModelWithBasicPresolveIntoContext (const CpModelProto &in_model, PresolveContext *context) |
bool | ImportModelAndDomainsWithBasicPresolveIntoContext (const CpModelProto &in_model, const std::vector< Domain > &domains, std::function< bool(int)> active_constraints, PresolveContext *context) |
void | CopyEverythingExceptVariablesAndConstraintsFieldsIntoContext (const CpModelProto &in_model, PresolveContext *context) |
Copies the non constraint, non variables part of the model. | |
CpSolverStatus | PresolveCpModel (PresolveContext *context, std::vector< int > *postsolve_mapping) |
Convenient wrapper to call the full presolve. | |
void | ApplyVariableMapping (const std::vector< int > &mapping, const PresolveContext &context) |
std::vector< std::pair< int, int > > | FindDuplicateConstraints (const CpModelProto &model_proto, bool ignore_enforcement) |
std::function< BooleanOrIntegerLiteral()> | ConstructUserSearchStrategy (const CpModelProto &cp_model_proto, Model *model) |
Constructs the search strategy specified in the given CpModelProto. | |
std::function< BooleanOrIntegerLiteral()> | ConstructHeuristicSearchStrategy (const CpModelProto &cp_model_proto, Model *model) |
Constructs a search strategy tailored for the current model. | |
std::function< BooleanOrIntegerLiteral()> | ConstructIntegerCompletionSearchStrategy (const std::vector< IntegerVariable > &variable_mapping, IntegerVariable objective_var, Model *model) |
Constructs an integer completion search strategy. | |
std::function< BooleanOrIntegerLiteral()> | ConstructHintSearchStrategy (const CpModelProto &cp_model_proto, CpModelMapping *mapping, Model *model) |
Constructs a search strategy that follow the hint from the model. | |
std::function< BooleanOrIntegerLiteral()> | ConstructFixedSearchStrategy (std::function< BooleanOrIntegerLiteral()> user_search, std::function< BooleanOrIntegerLiteral()> heuristic_search, std::function< BooleanOrIntegerLiteral()> integer_completion) |
std::function< BooleanOrIntegerLiteral()> | InstrumentSearchStrategy (const CpModelProto &cp_model_proto, const std::vector< IntegerVariable > &variable_mapping, std::function< BooleanOrIntegerLiteral()> instrumented_strategy, Model *model) |
absl::flat_hash_map< std::string, SatParameters > | GetNamedParameters (SatParameters base_params) |
std::vector< SatParameters > | GetFullWorkerParameters (const SatParameters &base_params, const CpModelProto &cp_model, int num_already_present, SubsolverNameFilter *filter) |
std::vector< SatParameters > | GetFirstSolutionBaseParams (const SatParameters &base_params) |
std::vector< SatParameters > | RepeatParameters (absl::Span< const SatParameters > base_params, int num_params_to_generate) |
std::string | CpSatSolverVersion () |
Returns a string that describes the version of the solver. | |
std::string | CpModelStats (const CpModelProto &model) |
Returns a string with some statistics on the given CpModelProto. | |
std::string | CpSolverResponseStats (const CpSolverResponse &response, bool has_objective) |
std::function< void(Model *)> | NewFeasibleSolutionObserver (const std::function< void(const CpSolverResponse &response)> &callback) |
std::function< void(Model *)> | NewFeasibleSolutionLogCallback (const std::function< std::string(const CpSolverResponse &response)> &callback) |
std::function< void(Model *)> | NewBestBoundCallback (const std::function< void(double)> &callback) |
std::function< SatParameters(Model *)> | NewSatParameters (const std::string ¶ms) |
std::function< SatParameters(Model *)> | NewSatParameters (const sat::SatParameters ¶meters) |
CpSolverResponse | SolveCpModel (const CpModelProto &model_proto, Model *model) |
CpSolverResponse | Solve (const CpModelProto &model_proto) |
Solves the given CpModelProto and returns an instance of CpSolverResponse. | |
CpSolverResponse | SolveWithParameters (const CpModelProto &model_proto, const SatParameters ¶ms) |
Solves the given CpModelProto with the given parameters. | |
CpSolverResponse | SolveWithParameters (const CpModelProto &model_proto, const std::string ¶ms) |
void | LoadAndSolveCpModelForTest (const CpModelProto &model_proto, Model *model) |
std::function< SatParameters(Model *)> | NewSatParameters (const SatParameters ¶meters) |
void | LoadDebugSolution (const CpModelProto &model_proto, Model *model) |
void | InitializeDebugSolution (const CpModelProto &model_proto, Model *model) |
std::vector< int64_t > | GetSolutionValues (const CpModelProto &model_proto, const Model &model) |
IntegerVariable | AddLPConstraints (bool objective_need_to_be_tight, const CpModelProto &model_proto, Model *m) |
Adds one LinearProgrammingConstraint per connected component of the model. | |
void | RegisterVariableBoundsLevelZeroExport (const CpModelProto &, SharedBoundsManager *shared_bounds_manager, Model *model) |
void | RegisterVariableBoundsLevelZeroImport (const CpModelProto &model_proto, SharedBoundsManager *shared_bounds_manager, Model *model) |
void | RegisterObjectiveBestBoundExport (IntegerVariable objective_var, SharedResponseManager *shared_response_manager, Model *model) |
void | RegisterObjectiveBoundsImport (SharedResponseManager *shared_response_manager, Model *model) |
void | RegisterClausesExport (int id, SharedClausesManager *shared_clauses_manager, Model *model) |
Registers a callback that will export good clauses discovered during search. | |
int | RegisterClausesLevelZeroImport (int id, SharedClausesManager *shared_clauses_manager, Model *model) |
void | LoadBaseModel (const CpModelProto &model_proto, Model *model) |
void | LoadFeasibilityPump (const CpModelProto &model_proto, Model *model) |
void | LoadCpModel (const CpModelProto &model_proto, Model *model) |
void | SolveLoadedCpModel (const CpModelProto &model_proto, Model *model) |
void | QuickSolveWithHint (const CpModelProto &model_proto, Model *model) |
void | MinimizeL1DistanceWithHint (const CpModelProto &model_proto, Model *model) |
void | PostsolveResponseWithFullSolver (int num_variables_in_original_model, CpModelProto mapping_proto, const std::vector< int > &postsolve_mapping, std::vector< int64_t > *solution) |
void | PostsolveResponseWrapper (const SatParameters ¶ms, int num_variable_in_original_model, const CpModelProto &mapping_proto, const std::vector< int > &postsolve_mapping, std::vector< int64_t > *solution) |
void | AdaptGlobalParameters (const CpModelProto &model_proto, Model *model) |
void | FindCpModelSymmetries (const SatParameters ¶ms, const CpModelProto &problem, std::vector< std::unique_ptr< SparsePermutation > > *generators, double deterministic_limit, SolverLogger *logger) |
void | DetectAndAddSymmetryToProto (const SatParameters ¶ms, CpModelProto *proto, SolverLogger *logger) |
Detects symmetries and fill the symmetry field. | |
bool | DetectAndExploitSymmetriesInPresolve (PresolveContext *context) |
int64_t | LinearExpressionGcd (const LinearExpressionProto &expr, int64_t gcd) |
void | DivideLinearExpression (int64_t divisor, LinearExpressionProto *expr) |
void | SetToNegatedLinearExpression (const LinearExpressionProto &input_expr, LinearExpressionProto *output_negated_expr) |
Fills the target as negated ref. | |
IndexReferences | GetReferencesUsedByConstraint (const ConstraintProto &ct) |
void | GetReferencesUsedByConstraint (const ConstraintProto &ct, std::vector< int > *variables, std::vector< int > *literals) |
void | ApplyToAllLiteralIndices (const std::function< void(int *)> &f, ConstraintProto *ct) |
void | ApplyToAllVariableIndices (const std::function< void(int *)> &f, ConstraintProto *ct) |
void | ApplyToAllIntervalIndices (const std::function< void(int *)> &f, ConstraintProto *ct) |
absl::string_view | ConstraintCaseName (ConstraintProto::ConstraintCase constraint_case) |
std::vector< int > | UsedVariables (const ConstraintProto &ct) |
std::vector< int > | UsedIntervals (const ConstraintProto &ct) |
Returns the sorted list of interval used by a constraint. | |
int64_t | ComputeInnerObjective (const CpObjectiveProto &objective, absl::Span< const int64_t > solution) |
bool | ExpressionContainsSingleRef (const LinearExpressionProto &expr) |
Returns true if a linear expression can be reduced to a single ref. | |
bool | ExpressionIsAffine (const LinearExpressionProto &expr) |
Checks if the expression is affine or constant. | |
int | GetSingleRefFromExpression (const LinearExpressionProto &expr) |
void | AddLinearExpressionToLinearConstraint (const LinearExpressionProto &expr, int64_t coefficient, LinearConstraintProto *linear) |
bool | SafeAddLinearExpressionToLinearConstraint (const LinearExpressionProto &expr, int64_t coefficient, LinearConstraintProto *linear) |
Same method, but returns if the addition was possible without overflowing. | |
bool | LinearExpressionProtosAreEqual (const LinearExpressionProto &a, const LinearExpressionProto &b, int64_t b_scaling=1) |
Returns true iff a == b * b_scaling. | |
uint64_t | FingerprintExpression (const LinearExpressionProto &lin, uint64_t seed) |
Returns a stable fingerprint of a linear expression. | |
uint64_t | FingerprintModel (const CpModelProto &model, uint64_t seed=kDefaultFingerprintSeed) |
Returns a stable fingerprint of a model. | |
void | SetupTextFormatPrinter (google::protobuf::TextFormat::Printer *printer) |
bool | ConvertCpModelProtoToCnf (const CpModelProto &cp_model, std::string *out) |
int | CombineSeed (int base_seed, int64_t delta) |
We assume delta >= 0 and we only use the low bit of delta. | |
int | NegatedRef (int ref) |
Small utility functions to deal with negative variable/literal references. | |
int | PositiveRef (int ref) |
bool | RefIsPositive (int ref) |
bool | HasEnforcementLiteral (const ConstraintProto &ct) |
Small utility functions to deal with half-reified constraints. | |
int | EnforcementLiteral (const ConstraintProto &ct) |
template<typename Set > | |
void | InsertVariablesFromConstraint (const CpModelProto &model_proto, int index, Set &output) |
Insert variables in a constraint into a set. | |
template<typename ProtoWithDomain > | |
bool | DomainInProtoContains (const ProtoWithDomain &proto, int64_t value) |
template<typename ProtoWithDomain > | |
void | FillDomainInProto (const Domain &domain, ProtoWithDomain *proto) |
Serializes a Domain into the domain field of a proto. | |
template<typename ProtoWithDomain > | |
Domain | ReadDomainFromProto (const ProtoWithDomain &proto) |
Reads a Domain from the domain field of a proto. | |
template<typename ProtoWithDomain > | |
std::vector< int64_t > | AllValuesInDomain (const ProtoWithDomain &proto) |
double | ScaleObjectiveValue (const CpObjectiveProto &proto, int64_t value) |
Scales back a objective value to a double value from the original model. | |
int64_t | ScaleInnerObjectiveValue (const CpObjectiveProto &proto, int64_t value) |
Similar to ScaleObjectiveValue() but uses the integer version. | |
double | UnscaleObjectiveValue (const CpObjectiveProto &proto, double value) |
Removes the objective scaling and offset from the given value. | |
template<class ExpressionList > | |
bool | ExpressionsContainsOnlyOneVar (const ExpressionList &exprs) |
Returns true if there exactly one variable appearing in all the expressions. | |
template<class T > | |
uint64_t | FingerprintRepeatedField (const google::protobuf::RepeatedField< T > &sequence, uint64_t seed) |
template<class T > | |
uint64_t | FingerprintSingleField (const T &field, uint64_t seed) |
template<class M > | |
bool | WriteModelProtoToFile (const M &proto, absl::string_view filename) |
bool | operator== (const BoolArgumentProto &lhs, const BoolArgumentProto &rhs) |
template<typename H > | |
H | AbslHashValue (H h, const BoolArgumentProto &m) |
bool | operator== (const LinearConstraintProto &lhs, const LinearConstraintProto &rhs) |
template<typename H > | |
H | AbslHashValue (H h, const LinearConstraintProto &m) |
std::function< void(Model *)> | Cumulative (const std::vector< IntervalVariable > &vars, const std::vector< AffineExpression > &demands, AffineExpression capacity, SchedulingConstraintHelper *helper) |
std::function< void(Model *)> | CumulativeTimeDecomposition (const std::vector< IntervalVariable > &vars, const std::vector< AffineExpression > &demands, AffineExpression capacity, SchedulingConstraintHelper *helper) |
std::function< void(Model *)> | CumulativeUsingReservoir (const std::vector< IntervalVariable > &vars, const std::vector< AffineExpression > &demands, AffineExpression capacity, SchedulingConstraintHelper *helper=nullptr) |
Another testing code, same assumptions as the CumulativeTimeDecomposition(). | |
void | AddCumulativeOverloadChecker (AffineExpression capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, Model *model) |
void | AddCumulativeOverloadCheckerDff (AffineExpression capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, Model *model) |
IntegerValue | GetFactorT (IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue max_magnitude) |
std::function< IntegerValue(IntegerValue)> | GetSuperAdditiveRoundingFunction (IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue t, IntegerValue max_scaling) |
std::function< IntegerValue(IntegerValue)> | GetSuperAdditiveStrengtheningFunction (IntegerValue positive_rhs, IntegerValue min_magnitude) |
std::function< IntegerValue(IntegerValue)> | GetSuperAdditiveStrengtheningMirFunction (IntegerValue positive_rhs, IntegerValue scaling) |
CutGenerator | CreatePositiveMultiplicationCutGenerator (AffineExpression z, AffineExpression x, AffineExpression y, int linearization_level, Model *model) |
A cut generator for z = x * y (x and y >= 0). | |
LinearConstraint | ComputeHyperplanAboveSquare (AffineExpression x, AffineExpression square, IntegerValue x_lb, IntegerValue x_ub, Model *model) |
LinearConstraint | ComputeHyperplanBelowSquare (AffineExpression x, AffineExpression square, IntegerValue x_value, Model *model) |
CutGenerator | CreateSquareCutGenerator (AffineExpression y, AffineExpression x, int linearization_level, Model *model) |
CutGenerator | CreateAllDifferentCutGenerator (const std::vector< AffineExpression > &exprs, Model *model) |
CutGenerator | CreateLinMaxCutGenerator (const IntegerVariable target, const std::vector< LinearExpression > &exprs, const std::vector< IntegerVariable > &z_vars, Model *model) |
bool | BuildMaxAffineUpConstraint (const LinearExpression &target, IntegerVariable var, const std::vector< std::pair< IntegerValue, IntegerValue > > &affines, Model *model, LinearConstraintBuilder *builder) |
CutGenerator | CreateMaxAffineCutGenerator (LinearExpression target, IntegerVariable var, std::vector< std::pair< IntegerValue, IntegerValue > > affines, const std::string cut_name, Model *model) |
CutGenerator | CreateCliqueCutGenerator (const std::vector< IntegerVariable > &base_variables, Model *model) |
std::function< IntegerValue(IntegerValue)> | ExtendNegativeFunction (std::function< IntegerValue(IntegerValue)> base_f, IntegerValue period) |
void | AddNonOverlappingRectangles (const std::vector< IntervalVariable > &x, const std::vector< IntervalVariable > &y, Model *model) |
void | GenerateNoOverlap2dEnergyCut (absl::Span< const std::vector< LiteralValueValue > > energies, absl::Span< int > rectangles, absl::string_view cut_name, Model *model, LinearConstraintManager *manager, SchedulingConstraintHelper *x_helper, SchedulingConstraintHelper *y_helper, SchedulingDemandHelper *y_demands_helper) |
CutGenerator | CreateNoOverlap2dEnergyCutGenerator (SchedulingConstraintHelper *x_helper, SchedulingConstraintHelper *y_helper, SchedulingDemandHelper *x_demands_helper, SchedulingDemandHelper *y_demands_helper, const std::vector< std::vector< LiteralValueValue > > &energies, Model *model) |
void | GenerateNoOvelap2dCompletionTimeCutsWithEnergy (absl::string_view cut_name, std::vector< DiffnCtEvent > events, bool use_lifting, bool skip_low_sizes, Model *model, LinearConstraintManager *manager) |
CutGenerator | CreateNoOverlap2dCompletionTimeCutGenerator (SchedulingConstraintHelper *x_helper, SchedulingConstraintHelper *y_helper, Model *model) |
std::vector< absl::Span< int > > | GetOverlappingRectangleComponents (absl::Span< const Rectangle > rectangles, absl::Span< int > active_rectangles) |
bool | ReportEnergyConflict (Rectangle bounding_box, absl::Span< const int > boxes, SchedulingConstraintHelper *x, SchedulingConstraintHelper *y) |
bool | BoxesAreInEnergyConflict (const std::vector< Rectangle > &rectangles, const std::vector< IntegerValue > &energies, absl::Span< const int > boxes, Rectangle *conflict) |
bool | AnalyzeIntervals (bool transpose, absl::Span< const int > local_boxes, absl::Span< const Rectangle > rectangles, absl::Span< const IntegerValue > rectangle_energies, IntegerValue *x_threshold, IntegerValue *y_threshold, Rectangle *conflict) |
absl::Span< int > | FilterBoxesAndRandomize (absl::Span< const Rectangle > cached_rectangles, absl::Span< int > boxes, IntegerValue threshold_x, IntegerValue threshold_y, absl::BitGenRef random) |
absl::Span< int > | FilterBoxesThatAreTooLarge (absl::Span< const Rectangle > cached_rectangles, absl::Span< const IntegerValue > energies, absl::Span< int > boxes) |
std::ostream & | operator<< (std::ostream &out, const IndexedInterval &interval) |
void | ConstructOverlappingSets (bool already_sorted, std::vector< IndexedInterval > *intervals, std::vector< std::vector< int > > *result) |
void | GetOverlappingIntervalComponents (std::vector< IndexedInterval > *intervals, std::vector< std::vector< int > > *components) |
std::vector< int > | GetIntervalArticulationPoints (std::vector< IndexedInterval > *intervals) |
void | AppendPairwiseRestrictions (absl::Span< const ItemForPairwiseRestriction > items, std::vector< PairwiseRestriction > *result) |
void | AppendPairwiseRestrictions (absl::Span< const ItemForPairwiseRestriction > items, absl::Span< const ItemForPairwiseRestriction > other_items, std::vector< PairwiseRestriction > *result) |
IntegerValue | Smallest1DIntersection (IntegerValue range_min, IntegerValue range_max, IntegerValue size, IntegerValue interval_min, IntegerValue interval_max) |
FindRectanglesResult | FindRectanglesWithEnergyConflictMC (const std::vector< RectangleInRange > &intervals, absl::BitGenRef random, double temperature, double candidate_energy_usage_factor) |
std::string | RenderDot (std::optional< Rectangle > bb, absl::Span< const Rectangle > solution) |
std::vector< Rectangle > | FindEmptySpaces (const Rectangle &bounding_box, std::vector< Rectangle > ocupied_rectangles) |
void | ReduceModuloBasis (absl::Span< const std::vector< absl::int128 > > basis, const int elements_to_consider, std::vector< absl::int128 > &v) |
std::vector< int > | GreedyFastDecreasingGcd (const absl::Span< const int64_t > coeffs) |
DiophantineSolution | SolveDiophantine (absl::Span< const int64_t > coeffs, int64_t rhs, absl::Span< const int64_t > var_lbs, absl::Span< const int64_t > var_ubs) |
floor (|P|/2)< | |
void | AddDisjunctive (const std::vector< IntervalVariable > &intervals, Model *model) |
void | AddDisjunctiveWithBooleanPrecedencesOnly (const std::vector< IntervalVariable > &intervals, Model *model) |
bool | ContainsLiteral (absl::Span< const Literal > clause, Literal literal) |
bool | Resolve (absl::Span< const Literal > clause, absl::Span< const Literal > other_clause, Literal complementary_literal, VariablesAssignment *assignment, std::vector< Literal > *resolvent) |
bool | AddProblemClauses (const std::string &file_path, DratChecker *drat_checker) |
bool | AddInferedAndDeletedClauses (const std::string &file_path, DratChecker *drat_checker) |
bool | PrintClauses (const std::string &file_path, SatFormat format, absl::Span< const std::vector< Literal > > clauses, int num_variables) |
DEFINE_STRONG_INDEX_TYPE (ClauseIndex) | |
Index of a clause (>= 0). | |
const ClauseIndex | kNoClauseIndex (-1) |
EncodingNode | LazyMerge (EncodingNode *a, EncodingNode *b, SatSolver *solver) |
void | IncreaseNodeSize (EncodingNode *node, SatSolver *solver) |
EncodingNode | FullMerge (Coefficient upper_bound, EncodingNode *a, EncodingNode *b, SatSolver *solver) |
EncodingNode * | MergeAllNodesWithDeque (Coefficient upper_bound, const std::vector< EncodingNode * > &nodes, SatSolver *solver, std::deque< EncodingNode > *repository) |
EncodingNode * | LazyMergeAllNodeWithPQAndIncreaseLb (Coefficient weight, const std::vector< EncodingNode * > &nodes, SatSolver *solver, std::deque< EncodingNode > *repository) |
void | ReduceNodes (Coefficient upper_bound, Coefficient *lower_bound, std::vector< EncodingNode * > *nodes, SatSolver *solver) |
std::vector< Literal > | ExtractAssumptions (Coefficient stratified_lower_bound, const std::vector< EncodingNode * > &nodes, SatSolver *solver) |
Coefficient | ComputeCoreMinWeight (const std::vector< EncodingNode * > &nodes, const std::vector< Literal > &core) |
Coefficient | MaxNodeWeightSmallerThan (const std::vector< EncodingNode * > &nodes, Coefficient upper_bound) |
std::vector< LiteralValueValue > | TryToReconcileEncodings (const AffineExpression &size2_affine, const AffineExpression &affine, absl::Span< const ValueLiteralPair > affine_var_encoding, bool put_affine_left_in_result, IntegerEncoder *integer_encoder) |
std::vector< LiteralValueValue > | TryToReconcileSize2Encodings (const AffineExpression &left, const AffineExpression &right, IntegerEncoder *integer_encoder) |
template<typename Storage > | |
InclusionDetector (const Storage &storage) -> InclusionDetector< Storage > | |
Deduction guide. | |
std::vector< IntegerVariable > | NegationOf (const std::vector< IntegerVariable > &vars) |
Returns the vector of the negated variables. | |
std::ostream & | operator<< (std::ostream &os, const ValueLiteralPair &p) |
DEFINE_STRONG_INT64_TYPE (IntegerValue) | |
constexpr IntegerValue | kMaxIntegerValue (std::numeric_limits< IntegerValue::ValueType >::max() - 1) |
constexpr IntegerValue | kMinIntegerValue (-kMaxIntegerValue.value()) |
double | ToDouble (IntegerValue value) |
template<class IntType > | |
IntType | IntTypeAbs (IntType t) |
IntegerValue | CeilRatio (IntegerValue dividend, IntegerValue positive_divisor) |
IntegerValue | FloorRatio (IntegerValue dividend, IntegerValue positive_divisor) |
IntegerValue | CapProdI (IntegerValue a, IntegerValue b) |
Overflows and saturated arithmetic. | |
IntegerValue | CapSubI (IntegerValue a, IntegerValue b) |
IntegerValue | CapAddI (IntegerValue a, IntegerValue b) |
bool | ProdOverflow (IntegerValue t, IntegerValue value) |
bool | AtMinOrMaxInt64I (IntegerValue t) |
IntegerValue | PositiveRemainder (IntegerValue dividend, IntegerValue positive_divisor) |
bool | AddTo (IntegerValue a, IntegerValue *result) |
bool | AddProductTo (IntegerValue a, IntegerValue b, IntegerValue *result) |
Computes result += a * b, and return false iff there is an overflow. | |
DEFINE_STRONG_INDEX_TYPE (IntegerVariable) | |
const IntegerVariable | kNoIntegerVariable (-1) |
IntegerVariable | NegationOf (IntegerVariable i) |
bool | VariableIsPositive (IntegerVariable i) |
IntegerVariable | PositiveVariable (IntegerVariable i) |
DEFINE_STRONG_INDEX_TYPE (PositiveOnlyIndex) | |
Special type for storing only one thing for var and NegationOf(var). | |
PositiveOnlyIndex | GetPositiveOnlyIndex (IntegerVariable var) |
std::string | IntegerTermDebugString (IntegerVariable var, IntegerValue coeff) |
std::ostream & | operator<< (std::ostream &os, IntegerLiteral i_lit) |
std::ostream & | operator<< (std::ostream &os, absl::Span< const IntegerLiteral > literals) |
template<typename H > | |
H | AbslHashValue (H h, const AffineExpression &e) |
std::function< BooleanVariable(Model *)> | NewBooleanVariable () |
std::function< IntegerVariable(Model *)> | ConstantIntegerVariable (int64_t value) |
std::function< IntegerVariable(Model *)> | NewIntegerVariable (int64_t lb, int64_t ub) |
std::function< IntegerVariable(Model *)> | NewIntegerVariable (const Domain &domain) |
IntegerVariable | CreateNewIntegerVariableFromLiteral (Literal lit, Model *model) |
std::function< IntegerVariable(Model *)> | NewIntegerVariableFromLiteral (Literal lit) |
std::function< int64_t(const Model &)> | LowerBound (IntegerVariable v) |
std::function< int64_t(const Model &)> | UpperBound (IntegerVariable v) |
std::function< bool(const Model &)> | IsFixed (IntegerVariable v) |
std::function< int64_t(const Model &)> | Value (IntegerVariable v) |
This checks that the variable is fixed. | |
std::function< void(Model *)> | GreaterOrEqual (IntegerVariable v, int64_t lb) |
std::function< void(Model *)> | LowerOrEqual (IntegerVariable v, int64_t ub) |
std::function< void(Model *)> | Equality (IntegerVariable v, int64_t value) |
Fix v to a given value. | |
std::function< void(Model *)> | Implication (absl::Span< const Literal > enforcement_literals, IntegerLiteral i) |
std::function< void(Model *)> | ImpliesInInterval (Literal in_interval, IntegerVariable v, int64_t lb, int64_t ub) |
in_interval => v in [lb, ub]. | |
std::function< std::vector< ValueLiteralPair >(Model *)> | FullyEncodeVariable (IntegerVariable var) |
std::function< void(Model *)> | IsOneOf (IntegerVariable var, const std::vector< Literal > &selectors, const std::vector< IntegerValue > &values) |
template<typename VectorInt > | |
std::function< void(Model *)> | WeightedSumLowerOrEqual (const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t upper_bound) |
Weighted sum <= constant. | |
template<typename VectorInt > | |
std::function< void(Model *)> | WeightedSumGreaterOrEqual (const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t lower_bound) |
Weighted sum >= constant. | |
template<typename VectorInt > | |
std::function< void(Model *)> | FixedWeightedSum (const std::vector< IntegerVariable > &vars, const VectorInt &coefficients, int64_t value) |
Weighted sum == constant. | |
void | AddWeightedSumLowerOrEqual (absl::Span< const Literal > enforcement_literals, absl::Span< const IntegerVariable > vars, absl::Span< const int64_t > coefficients, int64_t upper_bound, Model *model) |
enforcement_literals => sum <= upper_bound | |
void | AddWeightedSumGreaterOrEqual (absl::Span< const Literal > enforcement_literals, absl::Span< const IntegerVariable > vars, absl::Span< const int64_t > coefficients, int64_t lower_bound, Model *model) |
enforcement_literals => sum >= lower_bound | |
std::function< void(Model *)> | ConditionalWeightedSumLowerOrEqual (const std::vector< Literal > &enforcement_literals, const std::vector< IntegerVariable > &vars, const std::vector< int64_t > &coefficients, int64_t upper_bound) |
std::function< void(Model *)> | ConditionalWeightedSumGreaterOrEqual (const std::vector< Literal > &enforcement_literals, const std::vector< IntegerVariable > &vars, const std::vector< int64_t > &coefficients, int64_t upper_bound) |
void | LoadConditionalLinearConstraint (const absl::Span< const Literal > enforcement_literals, const LinearConstraint &cst, Model *model) |
LinearConstraint version. | |
void | LoadLinearConstraint (const LinearConstraint &cst, Model *model) |
void | AddConditionalAffinePrecedence (const absl::Span< const Literal > enforcement_literals, AffineExpression left, AffineExpression right, Model *model) |
template<typename VectorInt > | |
std::function< IntegerVariable(Model *)> | NewWeightedSum (const VectorInt &coefficients, const std::vector< IntegerVariable > &vars) |
std::function< void(Model *)> | IsEqualToMinOf (IntegerVariable min_var, const std::vector< IntegerVariable > &vars) |
std::function< void(Model *)> | IsEqualToMinOf (const LinearExpression &min_expr, const std::vector< LinearExpression > &exprs) |
std::function< void(Model *)> | IsEqualToMaxOf (IntegerVariable max_var, const std::vector< IntegerVariable > &vars) |
template<class T > | |
void | RegisterAndTransferOwnership (Model *model, T *ct) |
std::function< void(Model *)> | ProductConstraint (AffineExpression a, AffineExpression b, AffineExpression p) |
Adds the constraint: a * b = p. | |
std::function< void(Model *)> | DivisionConstraint (AffineExpression num, AffineExpression denom, AffineExpression div) |
Adds the constraint: num / denom = div. (denom > 0). | |
std::function< void(Model *)> | FixedDivisionConstraint (AffineExpression a, IntegerValue b, AffineExpression c) |
Adds the constraint: a / b = c where b is a constant. | |
std::function< void(Model *)> | FixedModuloConstraint (AffineExpression a, IntegerValue b, AffineExpression c) |
Adds the constraint: a % b = c where b is a constant. | |
IntegerLiteral | AtMinValue (IntegerVariable var, IntegerTrail *integer_trail) |
IntegerLiteral | ChooseBestObjectiveValue (IntegerVariable var, Model *model) |
If a variable appear in the objective, branch on its best objective value. | |
IntegerLiteral | GreaterOrEqualToMiddleValue (IntegerVariable var, IntegerTrail *integer_trail) |
IntegerLiteral | SplitAroundGivenValue (IntegerVariable var, IntegerValue value, Model *model) |
IntegerLiteral | SplitAroundLpValue (IntegerVariable var, Model *model) |
IntegerLiteral | SplitUsingBestSolutionValueInRepository (IntegerVariable var, const SharedSolutionRepository< int64_t > &solution_repo, Model *model) |
std::function< BooleanOrIntegerLiteral()> | FirstUnassignedVarAtItsMinHeuristic (const std::vector< IntegerVariable > &vars, Model *model) |
std::function< BooleanOrIntegerLiteral()> | MostFractionalHeuristic (Model *model) |
Choose the variable with most fractional LP value. | |
std::function< BooleanOrIntegerLiteral()> | BoolPseudoCostHeuristic (Model *model) |
std::function< BooleanOrIntegerLiteral()> | LpPseudoCostHeuristic (Model *model) |
std::function< BooleanOrIntegerLiteral()> | UnassignedVarWithLowestMinAtItsMinHeuristic (const std::vector< IntegerVariable > &vars, Model *model) |
std::function< BooleanOrIntegerLiteral()> | SequentialSearch (std::vector< std::function< BooleanOrIntegerLiteral()> > heuristics) |
std::function< BooleanOrIntegerLiteral()> | SequentialValueSelection (std::vector< std::function< IntegerLiteral(IntegerVariable)> > value_selection_heuristics, std::function< BooleanOrIntegerLiteral()> var_selection_heuristic, Model *model) |
bool | LinearizedPartIsLarge (Model *model) |
std::function< BooleanOrIntegerLiteral()> | IntegerValueSelectionHeuristic (std::function< BooleanOrIntegerLiteral()> var_selection_heuristic, Model *model) |
std::function< BooleanOrIntegerLiteral()> | SatSolverHeuristic (Model *model) |
Returns the BooleanOrIntegerLiteral advised by the underlying SAT solver. | |
std::function< BooleanOrIntegerLiteral()> | ShaveObjectiveLb (Model *model) |
std::function< BooleanOrIntegerLiteral()> | PseudoCost (Model *model) |
std::function< BooleanOrIntegerLiteral()> | SchedulingSearchHeuristic (Model *model) |
A simple heuristic for scheduling models. | |
std::function< BooleanOrIntegerLiteral()> | DisjunctivePrecedenceSearchHeuristic (Model *model) |
std::function< BooleanOrIntegerLiteral()> | CumulativePrecedenceSearchHeuristic (Model *model) |
std::function< BooleanOrIntegerLiteral()> | RandomizeOnRestartHeuristic (bool lns_mode, Model *model) |
std::function< BooleanOrIntegerLiteral()> | FollowHint (const std::vector< BooleanOrIntegerVariable > &vars, const std::vector< IntegerValue > &values, Model *model) |
std::function< bool()> | RestartEveryKFailures (int k, SatSolver *solver) |
A restart policy that restarts every k failures. | |
std::function< bool()> | SatSolverRestartPolicy (Model *model) |
A restart policy that uses the underlying sat solver's policy. | |
void | ConfigureSearchHeuristics (Model *model) |
std::vector< std::function< BooleanOrIntegerLiteral()> > | CompleteHeuristics (absl::Span< const std::function< BooleanOrIntegerLiteral()> > incomplete_heuristics, const std::function< BooleanOrIntegerLiteral()> &completion_heuristic) |
SatSolver::Status | ResetAndSolveIntegerProblem (const std::vector< Literal > &assumptions, Model *model) |
SatSolver::Status | SolveIntegerProblemWithLazyEncoding (Model *model) |
IntegerLiteral | SplitDomainUsingBestSolutionValue (IntegerVariable var, Model *model) |
IntegerValue | ComputeEnergyMinInWindow (IntegerValue start_min, IntegerValue start_max, IntegerValue end_min, IntegerValue end_max, IntegerValue size_min, IntegerValue demand_min, absl::Span< const LiteralValueValue > filtered_energy, IntegerValue window_start, IntegerValue window_end) |
void | AddIntegerVariableFromIntervals (SchedulingConstraintHelper *helper, Model *model, std::vector< IntegerVariable > *vars) |
Cuts helpers. | |
void | AppendVariablesFromCapacityAndDemands (const AffineExpression &capacity, SchedulingDemandHelper *demands_helper, Model *model, std::vector< IntegerVariable > *vars) |
DEFINE_STRONG_INDEX_TYPE (IntervalVariable) | |
const IntervalVariable | kNoIntervalVariable (-1) |
std::function< int64_t(const Model &)> | MinSize (IntervalVariable v) |
std::function< int64_t(const Model &)> | MaxSize (IntervalVariable v) |
std::function< bool(const Model &)> | IsOptional (IntervalVariable v) |
std::function< Literal(const Model &)> | IsPresentLiteral (IntervalVariable v) |
std::function< IntervalVariable(Model *)> | NewInterval (int64_t min_start, int64_t max_end, int64_t size) |
std::function< IntervalVariable(Model *)> | NewInterval (IntegerVariable start, IntegerVariable end, IntegerVariable size) |
std::function< IntervalVariable(Model *)> | NewIntervalWithVariableSize (int64_t min_start, int64_t max_end, int64_t min_size, int64_t max_size) |
std::function< IntervalVariable(Model *)> | NewOptionalInterval (int64_t min_start, int64_t max_end, int64_t size, Literal is_present) |
std::function< IntervalVariable(Model *)> | NewOptionalInterval (IntegerVariable start, IntegerVariable end, IntegerVariable size, Literal is_present) |
std::function< IntervalVariable(Model *)> | NewOptionalIntervalWithVariableSize (int64_t min_start, int64_t max_end, int64_t min_size, int64_t max_size, Literal is_present) |
double | ComputeActivity (const LinearConstraint &constraint, const util_intops::StrongVector< IntegerVariable, double > &values) |
double | ComputeL2Norm (const LinearConstraint &constraint) |
Returns sqrt(sum square(coeff)). | |
IntegerValue | ComputeInfinityNorm (const LinearConstraint &constraint) |
Returns the maximum absolute value of the coefficients. | |
double | ScalarProduct (const LinearConstraint &ct1, const LinearConstraint &ct2) |
void | DivideByGCD (LinearConstraint *constraint) |
void | RemoveZeroTerms (LinearConstraint *constraint) |
Removes the entries with a coefficient of zero. | |
void | MakeAllCoefficientsPositive (LinearConstraint *constraint) |
Makes all coefficients positive by transforming a variable to its negation. | |
void | MakeAllVariablesPositive (LinearConstraint *constraint) |
Makes all variables "positive" by transforming a variable to its negation. | |
bool | NoDuplicateVariable (const LinearConstraint &ct) |
Returns false if duplicate variables are found in ct. | |
LinearExpression | CanonicalizeExpr (const LinearExpression &expr) |
bool | ValidateLinearConstraintForOverflow (const LinearConstraint &constraint, const IntegerTrail &integer_trail) |
LinearExpression | NegationOf (const LinearExpression &expr) |
Preserves canonicality. | |
LinearExpression | PositiveVarExpr (const LinearExpression &expr) |
Returns the same expression with positive variables. | |
IntegerValue | GetCoefficient (const IntegerVariable var, const LinearExpression &expr) |
IntegerValue | GetCoefficientOfPositiveVar (const IntegerVariable var, const LinearExpression &expr) |
bool | PossibleOverflow (const IntegerTrail &integer_trail, const LinearConstraint &constraint) |
std::ostream & | operator<< (std::ostream &os, const LinearConstraint &ct) |
void | CleanTermsAndFillConstraint (std::vector< std::pair< IntegerVariable, IntegerValue > > *terms, LinearExpression *output) |
void | CleanTermsAndFillConstraint (std::vector< std::pair< IntegerVariable, IntegerValue > > *terms, LinearConstraint *output) |
std::ostream & | operator<< (std::ostream &os, const EnforcementStatus &e) |
DEFINE_STRONG_INDEX_TYPE (EnforcementId) | |
void | AppendRelaxationForEqualityEncoding (IntegerVariable var, const Model &model, LinearRelaxation *relaxation, int *num_tight, int *num_loose) |
void | AppendPartialGreaterThanEncodingRelaxation (IntegerVariable var, const Model &model, LinearRelaxation *relaxation) |
void | AppendBoolOrRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AppendBoolAndRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation, ActivityBoundHelper *activity_helper) |
void | AppendAtMostOneRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AppendExactlyOneRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
std::vector< Literal > | CreateAlternativeLiteralsWithView (int num_literals, Model *model, LinearRelaxation *relaxation) |
void | AppendCircuitRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
Routing relaxation and cut generators. | |
void | AppendRoutesRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AddCircuitCutGenerator (const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation) |
void | AddRoutesCutGenerator (const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation) |
std::optional< int > | DetectMakespan (const std::vector< IntervalVariable > &intervals, const std::vector< AffineExpression > &demands, const AffineExpression &capacity, Model *model) |
void | AppendNoOverlapRelaxationAndCutGenerator (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AppendCumulativeRelaxationAndCutGenerator (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AddCumulativeRelaxation (const AffineExpression &capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, const std::optional< AffineExpression > &makespan, Model *model, LinearRelaxation *relaxation) |
Scheduling relaxations and cut generators. | |
void | AppendNoOverlap2dRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
Adds the energetic relaxation sum(areas) <= bounding box area. | |
void | AppendLinMaxRelaxationPart1 (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AppendMaxAffineRelaxation (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AddMaxAffineCutGenerator (const ConstraintProto &ct, Model *model, LinearRelaxation *relaxation) |
void | AppendLinMaxRelaxationPart2 (IntegerVariable target, const std::vector< Literal > &alternative_literals, const std::vector< LinearExpression > &exprs, Model *model, LinearRelaxation *relaxation) |
void | AppendLinearConstraintRelaxation (const ConstraintProto &ct, bool linearize_enforced_constraints, Model *model, LinearRelaxation *relaxation, ActivityBoundHelper *activity_helper) |
void | TryToLinearizeConstraint (const CpModelProto &model_proto, const ConstraintProto &ct, int linearization_level, Model *model, LinearRelaxation *relaxation, ActivityBoundHelper *helper=nullptr) |
Adds linearization of different types of constraints. | |
void | AddIntProdCutGenerator (const ConstraintProto &ct, int linearization_level, Model *m, LinearRelaxation *relaxation) |
Cut generators. | |
void | AppendSquareRelaxation (const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation) |
void | AddSquareCutGenerator (const ConstraintProto &ct, int linearization_level, Model *m, LinearRelaxation *relaxation) |
void | AddAllDiffRelaxationAndCutGenerator (const ConstraintProto &ct, int linearization_level, Model *m, LinearRelaxation *relaxation) |
bool | IntervalIsVariable (const IntervalVariable interval, IntervalsRepository *intervals_repository) |
void | AddCumulativeCutGenerator (const AffineExpression &capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands_helper, const std::optional< AffineExpression > &makespan, Model *m, LinearRelaxation *relaxation) |
void | AddNoOverlapCutGenerator (SchedulingConstraintHelper *helper, const std::optional< AffineExpression > &makespan, Model *m, LinearRelaxation *relaxation) |
void | AddNoOverlap2dCutGenerator (const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation) |
void | AddLinMaxCutGenerator (const ConstraintProto &ct, Model *m, LinearRelaxation *relaxation) |
void | AppendElementEncodingRelaxation (Model *m, LinearRelaxation *relaxation) |
LinearRelaxation | ComputeLinearRelaxation (const CpModelProto &model_proto, Model *m) |
Builds the linear relaxation of a CpModelProto. | |
std::vector< double > | ScaleContinuousVariables (double scaling, double max_bound, MPModelProto *mp_model) |
int64_t | FindRationalFactor (double x, int64_t limit, double tolerance) |
bool | MakeBoundsOfIntegerVariablesInteger (const SatParameters ¶ms, MPModelProto *mp_model, SolverLogger *logger) |
void | ChangeLargeBoundsToInfinity (double max_magnitude, MPModelProto *mp_model, SolverLogger *logger) |
void | RemoveNearZeroTerms (const SatParameters ¶ms, MPModelProto *mp_model, SolverLogger *logger) |
bool | MPModelProtoValidationBeforeConversion (const SatParameters ¶ms, const MPModelProto &mp_model, SolverLogger *logger) |
std::vector< double > | DetectImpliedIntegers (MPModelProto *mp_model, SolverLogger *logger) |
double | FindBestScalingAndComputeErrors (const std::vector< double > &coefficients, absl::Span< const double > lower_bounds, absl::Span< const double > upper_bounds, int64_t max_absolute_activity, double wanted_absolute_activity_precision, double *relative_coeff_error, double *scaled_sum_error) |
bool | ConvertMPModelProtoToCpModelProto (const SatParameters ¶ms, const MPModelProto &mp_model, CpModelProto *cp_model, SolverLogger *logger) |
bool | ConvertCpModelProtoToMPModelProto (const CpModelProto &input, MPModelProto *output) |
bool | ScaleAndSetObjective (const SatParameters ¶ms, const std::vector< std::pair< int, double > > &objective, double objective_offset, bool maximize, CpModelProto *cp_model, SolverLogger *logger) |
bool | ConvertBinaryMPModelProtoToBooleanProblem (const MPModelProto &mp_model, LinearBooleanProblem *problem) |
void | ConvertBooleanProblemToLinearProgram (const LinearBooleanProblem &problem, glop::LinearProgram *lp) |
Converts a Boolean optimization problem to its lp formulation. | |
double | ComputeTrueObjectiveLowerBound (const CpModelProto &model_proto_with_floating_point_objective, const CpObjectiveProto &integer_objective, const int64_t inner_integer_objective_lower_bound) |
void | MinimizeCoreWithPropagation (TimeLimit *limit, SatSolver *solver, std::vector< Literal > *core) |
void | MinimizeCoreWithSearch (TimeLimit *limit, SatSolver *solver, std::vector< Literal > *core) |
bool | ProbeLiteral (Literal assumption, SatSolver *solver) |
void | FilterAssignedLiteral (const VariablesAssignment &assignment, std::vector< Literal > *core) |
A core cannot be all true. | |
SatSolver::Status | MinimizeIntegerVariableWithLinearScanAndLazyEncoding (IntegerVariable objective_var, const std::function< void()> &feasible_solution_observer, Model *model) |
void | RestrictObjectiveDomainWithBinarySearch (IntegerVariable objective_var, const std::function< void()> &feasible_solution_observer, Model *model) |
void | PresolveBooleanLinearExpression (std::vector< Literal > *literals, std::vector< Coefficient > *coefficients, Coefficient *offset) |
std::string | ValidateParameters (const SatParameters ¶ms) |
bool | ComputeBooleanLinearExpressionCanonicalForm (std::vector< LiteralWithCoeff > *cst, Coefficient *bound_shift, Coefficient *max_value) |
bool | ApplyLiteralMapping (const util_intops::StrongVector< LiteralIndex, LiteralIndex > &mapping, std::vector< LiteralWithCoeff > *cst, Coefficient *bound_shift, Coefficient *max_value) |
bool | BooleanLinearExpressionIsCanonical (absl::Span< const LiteralWithCoeff > cst) |
Returns true iff the Boolean linear expression is in canonical form. | |
void | SimplifyCanonicalBooleanLinearConstraint (std::vector< LiteralWithCoeff > *cst, Coefficient *rhs) |
Coefficient | ComputeCanonicalRhs (Coefficient upper_bound, Coefficient bound_shift, Coefficient max_value) |
Coefficient | ComputeNegatedCanonicalRhs (Coefficient lower_bound, Coefficient bound_shift, Coefficient max_value) |
DEFINE_STRONG_INT64_TYPE (Coefficient) | |
const Coefficient | kCoefficientMax (std::numeric_limits< Coefficient::ValueType >::max()) |
template<typename H > | |
H | AbslHashValue (H h, const LiteralWithCoeff &term) |
std::ostream & | operator<< (std::ostream &os, LiteralWithCoeff term) |
std::function< void(Model *)> | LowerOrEqual (IntegerVariable a, IntegerVariable b) |
a <= b. | |
std::function< void(Model *)> | LowerOrEqualWithOffset (IntegerVariable a, IntegerVariable b, int64_t offset) |
a + offset <= b. | |
std::function< void(Model *)> | AffineCoeffOneLowerOrEqualWithOffset (AffineExpression a, AffineExpression b, int64_t offset) |
a + offset <= b. (when a and b are of the form 1 * var + offset). | |
void | AddConditionalSum2LowerOrEqual (absl::Span< const Literal > enforcement_literals, IntegerVariable a, IntegerVariable b, int64_t ub, Model *model) |
l => (a + b <= ub). | |
void | AddConditionalSum3LowerOrEqual (absl::Span< const Literal > enforcement_literals, IntegerVariable a, IntegerVariable b, IntegerVariable c, int64_t ub, Model *model) |
std::function< void(Model *)> | GreaterOrEqual (IntegerVariable a, IntegerVariable b) |
a >= b. | |
std::function< void(Model *)> | Equality (IntegerVariable a, IntegerVariable b) |
a == b. | |
std::function< void(Model *)> | EqualityWithOffset (IntegerVariable a, IntegerVariable b, int64_t offset) |
a + offset == b. | |
std::function< void(Model *)> | ConditionalLowerOrEqualWithOffset (IntegerVariable a, IntegerVariable b, int64_t offset, Literal is_le) |
is_le => (a + offset <= b). | |
bool | LoadModelForProbing (PresolveContext *context, Model *local_model) |
template<typename ProtoWithVarsAndCoeffs > | |
bool | CanonicalizeLinearExpressionInternal (absl::Span< const int > enforcements, ProtoWithVarsAndCoeffs *proto, int64_t *offset, std::vector< std::pair< int, int64_t > > *tmp_terms, PresolveContext *context) |
bool | AddLinearConstraintMultiple (int64_t factor, const ConstraintProto &to_add, ConstraintProto *to_modify) |
bool | SubstituteVariable (int var, int64_t var_coeff_in_definition, const ConstraintProto &definition, ConstraintProto *ct) |
bool | FindSingleLinearDifference (const LinearConstraintProto &lin1, const LinearConstraintProto &lin2, int *var1, int64_t *coeff1, int *var2, int64_t *coeff2) |
Same as LinearsDifferAtOneTerm() below but also fills the differing terms. | |
bool | ClauseIsEnforcementImpliesLiteral (absl::Span< const int > clause, absl::Span< const int > enforcement, int literal) |
bool | LinearsDifferAtOneTerm (const LinearConstraintProto &lin1, const LinearConstraintProto &lin2) |
bool | LookForTrivialSatSolution (double deterministic_time_limit, Model *model, SolverLogger *logger) |
bool | FailedLiteralProbingRound (ProbingOptions options, Model *model) |
int | SUniv (int i) |
void | RecordLPRelaxationValues (Model *model) |
Adds the current LP solution to the pool. | |
ReducedDomainNeighborhood | GetRinsRensNeighborhood (const SharedResponseManager *response_manager, const SharedLPSolutionRepository *lp_solutions, SharedIncompleteSolutionManager *incomplete_solutions, double difficulty, absl::BitGenRef random) |
void | GenerateInterestingSubsets (int num_nodes, const std::vector< std::pair< int, int > > &arcs, int stop_at_num_components, std::vector< int > *subset_data, std::vector< absl::Span< const int > > *subsets) |
void | ExtractAllSubsetsFromForest (const std::vector< int > &parent, std::vector< int > *subset_data, std::vector< absl::Span< const int > > *subsets, int node_limit) |
std::vector< int > | ComputeGomoryHuTree (int num_nodes, const std::vector< ArcWithLpValue > &relevant_arcs) |
void | SymmetrizeArcs (std::vector< ArcWithLpValue > *arcs) |
void | SeparateSubtourInequalities (int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< Literal > &literals, absl::Span< const int64_t > demands, int64_t capacity, LinearConstraintManager *manager, Model *model) |
CutGenerator | CreateStronglyConnectedGraphCutGenerator (int num_nodes, std::vector< int > tails, std::vector< int > heads, std::vector< Literal > literals, Model *model) |
CutGenerator | CreateCVRPCutGenerator (int num_nodes, std::vector< int > tails, std::vector< int > heads, std::vector< Literal > literals, std::vector< int64_t > demands, int64_t capacity, Model *model) |
void | SeparateFlowInequalities (int num_nodes, absl::Span< const int > tails, absl::Span< const int > heads, absl::Span< const AffineExpression > arc_capacities, std::function< void(const std::vector< bool > &in_subset, IntegerValue *min_incoming_flow, IntegerValue *min_outgoing_flow)> get_flows, const util_intops::StrongVector< IntegerVariable, double > &lp_values, LinearConstraintManager *manager, Model *model) |
CutGenerator | CreateFlowCutGenerator (int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< AffineExpression > &arc_capacities, std::function< void(const std::vector< bool > &in_subset, IntegerValue *min_incoming_flow, IntegerValue *min_outgoing_flow)> get_flows, Model *model) |
DEFINE_STRONG_INDEX_TYPE (BooleanVariable) | |
Index of a variable (>= 0). | |
const BooleanVariable | kNoBooleanVariable (-1) |
DEFINE_STRONG_INDEX_TYPE (LiteralIndex) | |
Index of a literal (>= 0), see Literal below. | |
const LiteralIndex | kNoLiteralIndex (-1) |
const LiteralIndex | kTrueLiteralIndex (-2) |
const LiteralIndex | kFalseLiteralIndex (-3) |
std::ostream & | operator<< (std::ostream &os, Literal literal) |
template<typename Sink , typename... T> | |
void | AbslStringify (Sink &sink, Literal arg) |
std::ostream & | operator<< (std::ostream &os, absl::Span< const Literal > literals) |
std::vector< Literal > | Literals (absl::Span< const int > input) |
std::string | SatStatusString (SatSolver::Status status) |
Returns a string representation of a SatSolver::Status. | |
void | MinimizeCore (SatSolver *solver, std::vector< Literal > *core) |
std::function< void(Model *)> | BooleanLinearConstraint (int64_t lower_bound, int64_t upper_bound, std::vector< LiteralWithCoeff > *cst) |
std::function< void(Model *)> | CardinalityConstraint (int64_t lower_bound, int64_t upper_bound, const std::vector< Literal > &literals) |
std::function< void(Model *)> | ExactlyOneConstraint (const std::vector< Literal > &literals) |
std::function< void(Model *)> | AtMostOneConstraint (const std::vector< Literal > &literals) |
std::function< void(Model *)> | ClauseConstraint (absl::Span< const Literal > literals) |
std::function< void(Model *)> | Implication (Literal a, Literal b) |
a => b. | |
std::function< void(Model *)> | Equality (Literal a, Literal b) |
a == b. | |
std::function< void(Model *)> | ReifiedBoolOr (const std::vector< Literal > &literals, Literal r) |
r <=> (at least one literal is true). This is a reified clause. | |
std::function< void(Model *)> | EnforcedClause (absl::Span< const Literal > enforcement_literals, absl::Span< const Literal > clause) |
enforcement_literals => clause. | |
std::function< void(Model *)> | ReifiedBoolAnd (const std::vector< Literal > &literals, Literal r) |
std::function< void(Model *)> | ReifiedBoolLe (Literal a, Literal b, Literal r) |
r <=> (a <= b). | |
std::function< int64_t(const Model &)> | Value (Literal l) |
This checks that the variable is fixed. | |
std::function< int64_t(const Model &)> | Value (BooleanVariable b) |
This checks that the variable is fixed. | |
std::function< void(Model *)> | ExcludeCurrentSolutionAndBacktrack () |
std::ostream & | operator<< (std::ostream &os, SatSolver::Status status) |
void | GenerateCumulativeEnergeticCutsWithMakespanAndFixedCapacity (absl::string_view cut_name, const util_intops::StrongVector< IntegerVariable, double > &lp_values, std::vector< EnergyEvent > events, IntegerValue capacity, AffineExpression makespan, TimeLimit *time_limit, Model *model, LinearConstraintManager *manager) |
void | GenerateCumulativeEnergeticCuts (const std::string &cut_name, const util_intops::StrongVector< IntegerVariable, double > &lp_values, std::vector< EnergyEvent > events, const AffineExpression &capacity, TimeLimit *time_limit, Model *model, LinearConstraintManager *manager) |
CutGenerator | CreateCumulativeEnergyCutGenerator (SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands_helper, const AffineExpression &capacity, const std::optional< AffineExpression > &makespan, Model *model) |
CutGenerator | CreateNoOverlapEnergyCutGenerator (SchedulingConstraintHelper *helper, const std::optional< AffineExpression > &makespan, Model *model) |
CutGenerator | CreateCumulativeTimeTableCutGenerator (SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands_helper, const AffineExpression &capacity, Model *model) |
void | GenerateCutsBetweenPairOfNonOverlappingTasks (absl::string_view cut_name, const util_intops::StrongVector< IntegerVariable, double > &lp_values, std::vector< CachedIntervalData > events, IntegerValue capacity_max, Model *model, LinearConstraintManager *manager) |
CutGenerator | CreateCumulativePrecedenceCutGenerator (SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands_helper, const AffineExpression &capacity, Model *model) |
CutGenerator | CreateNoOverlapPrecedenceCutGenerator (SchedulingConstraintHelper *helper, Model *model) |
bool | ComputeMinSumOfWeightedEndMins (std::vector< PermutableEvent > &events, IntegerValue capacity_max, IntegerValue &min_sum_of_end_mins, IntegerValue &min_sum_of_weighted_end_mins, IntegerValue unweighted_threshold, IntegerValue weighted_threshold) |
void | GenerateShortCompletionTimeCutsWithExactBound (const std::string &cut_name, std::vector< CtEvent > events, IntegerValue capacity_max, Model *model, LinearConstraintManager *manager) |
void | GenerateCompletionTimeCutsWithEnergy (absl::string_view cut_name, std::vector< CtEvent > events, IntegerValue capacity_max, bool skip_low_sizes, Model *model, LinearConstraintManager *manager) |
CutGenerator | CreateNoOverlapCompletionTimeCutGenerator (SchedulingConstraintHelper *helper, Model *model) |
CutGenerator | CreateCumulativeCompletionTimeCutGenerator (SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands_helper, const AffineExpression &capacity, Model *model) |
bool | SimplifyClause (const std::vector< Literal > &a, std::vector< Literal > *b, LiteralIndex *opposite_literal, int64_t *num_inspected_literals) |
LiteralIndex | DifferAtGivenLiteral (const std::vector< Literal > &a, const std::vector< Literal > &b, Literal l) |
bool | ComputeResolvant (Literal x, const std::vector< Literal > &a, const std::vector< Literal > &b, std::vector< Literal > *out) |
int | ComputeResolvantSize (Literal x, const std::vector< Literal > &a, const std::vector< Literal > &b) |
void | ProbeAndFindEquivalentLiteral (SatSolver *solver, SatPostsolver *postsolver, DratProofHandler *drat_proof_handler, util_intops::StrongVector< LiteralIndex, LiteralIndex > *mapping, SolverLogger *logger) |
void | SequentialLoop (std::vector< std::unique_ptr< SubSolver > > &subsolvers) |
void | DeterministicLoop (std::vector< std::unique_ptr< SubSolver > > &subsolvers, int num_threads, int batch_size, int max_num_batches) |
void | NonDeterministicLoop (std::vector< std::unique_ptr< SubSolver > > &subsolvers, const int num_threads) |
std::vector< std::vector< int > > | BasicOrbitopeExtraction (absl::Span< const std::unique_ptr< SparsePermutation > > generators) |
std::vector< int > | GetOrbits (int n, absl::Span< const std::unique_ptr< SparsePermutation > > generators) |
std::vector< int > | GetOrbitopeOrbits (int n, absl::Span< const std::vector< int > > orbitope) |
void | TransformToGeneratorOfStabilizer (int to_stabilize, std::vector< std::unique_ptr< SparsePermutation > > *generators) |
void | FillSolveStatsInResponse (Model *model, CpSolverResponse *response) |
std::string | ExtractSubSolverName (const std::string &improvement_info) |
std::function< void(Model *)> | LiteralTableConstraint (const std::vector< std::vector< Literal > > &literal_tuples, const std::vector< Literal > &line_literals) |
template<typename IntegerType > | |
constexpr IntegerType | IntegerTypeMinimumValue () |
The minimal value of an envelope, for instance the envelope of the empty set. | |
template<> | |
constexpr IntegerValue | IntegerTypeMinimumValue () |
void | AddReservoirConstraint (std::vector< AffineExpression > times, std::vector< AffineExpression > deltas, std::vector< Literal > presences, int64_t min_level, int64_t max_level, Model *model) |
std::string | FormatCounter (int64_t num) |
Prints a positive number with separators for easier reading (ex: 1'348'065). | |
std::string | FormatTable (std::vector< std::vector< std::string > > &table, int spacing) |
void | RandomizeDecisionHeuristic (absl::BitGenRef random, SatParameters *parameters) |
Randomizes the decision heuristic of the given SatParameters. | |
int64_t | ModularInverse (int64_t x, int64_t m) |
int64_t | PositiveMod (int64_t x, int64_t m) |
Just returns x % m but with a result always in [0, m). | |
int64_t | ProductWithModularInverse (int64_t coeff, int64_t mod, int64_t rhs) |
bool | SolveDiophantineEquationOfSizeTwo (int64_t &a, int64_t &b, int64_t &cte, int64_t &x0, int64_t &y0) |
int64_t | FloorSquareRoot (int64_t a) |
The argument must be non-negative. | |
int64_t | CeilSquareRoot (int64_t a) |
int64_t | ClosestMultiple (int64_t value, int64_t base) |
bool | LinearInequalityCanBeReducedWithClosestMultiple (int64_t base, absl::Span< const int64_t > coeffs, absl::Span< const int64_t > lbs, absl::Span< const int64_t > ubs, int64_t rhs, int64_t *new_rhs) |
int | MoveOneUnprocessedLiteralLast (const absl::btree_set< LiteralIndex > &processed, int relevant_prefix_size, std::vector< Literal > *literals) |
int | WeightedPick (absl::Span< const double > input, absl::BitGenRef random) |
void | CompressTuples (absl::Span< const int64_t > domain_sizes, std::vector< std::vector< int64_t > > *tuples) |
std::vector< std::vector< absl::InlinedVector< int64_t, 2 > > > | FullyCompressTuples (absl::Span< const int64_t > domain_sizes, std::vector< std::vector< int64_t > > *tuples) |
std::vector< absl::Span< int > > | AtMostOneDecomposition (const std::vector< std::vector< int > > &graph, absl::BitGenRef random, std::vector< int > *buffer) |
std::string | FormatName (absl::string_view name) |
This is used to format our table first row entry. | |
int64_t | SafeDoubleToInt64 (double value) |
bool | IsNegatableInt64 (absl::int128 x) |
Tells whether a int128 can be casted to a int64_t that can be negated. | |
template<typename IntType , bool ceil> | |
IntType | CeilOrFloorOfRatio (IntType numerator, IntType denominator) |
template<typename IntType > | |
IntType | CeilOfRatio (IntType numerator, IntType denominator) |
template<typename IntType > | |
IntType | FloorOfRatio (IntType numerator, IntType denominator) |
void | ScanModelForDominanceDetection (PresolveContext &context, VarDomination *var_domination) |
void | ScanModelForDualBoundStrengthening (const PresolveContext &context, DualBoundStrengthening *dual_bound_strengthening) |
Scan the model so that dual_bound_strengthening.Strenghten() works. | |
bool | ExploitDominanceRelations (const VarDomination &var_domination, PresolveContext *context) |
Variables | |
static constexpr int | kMaxProblemSize = 16 |
constexpr uint64_t | kDefaultFingerprintSeed = 0xa5b85c5e198ed849 |
Default seed for fingerprints. | |
for | i = 0 ... k-2 |
for | b [i][j] = 0 if j > i+1 |
constexpr int | kObjectiveConstraint = -1 |
We use some special constraint index in our variable <-> constraint graph. | |
constexpr int | kAffineRelationConstraint = -2 |
constexpr int | kAssumptionsConstraint = -3 |
const int | kUnsatTrailIndex = -1 |
A constant used by the EnqueueDecision*() API. | |
constexpr int64_t | kTableAnyValue = std::numeric_limits<int64_t>::min() |
Solution Feasibility.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
using operations_research::sat::InlinedIntegerLiteralVector = absl::InlinedVector<IntegerLiteral, 2> |
using operations_research::sat::IntegerSumLE = LinearConstraintPropagator<false> |
Definition at line 162 of file integer_expr.h.
Definition at line 163 of file integer_expr.h.
|
strong |
An enforced constraint can be in one of these 4 states.
Definition at line 50 of file linear_propagation.h.
The file formats that can be used to save a list of clauses.
Enumerator | |
---|---|
DIMACS | |
DRAT |
Definition at line 334 of file drat_checker.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const AffineExpression & | e ) |
H operations_research::sat::AbslHashValue | ( | H | h, |
const BoolArgumentProto & | m ) |
Definition at line 324 of file cp_model_utils.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const IntervalVar & | i ) |
Definition at line 520 of file cp_model.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const IntVar & | i ) |
– ABSL HASHING SUPPORT --------------------------------------------------—
Definition at line 515 of file cp_model.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const LinearConstraintProto & | m ) |
Definition at line 346 of file cp_model_utils.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const LiteralWithCoeff & | term ) |
Definition at line 65 of file pb_constraint.h.
void operations_research::sat::AbslStringify | ( | Sink & | sink, |
Literal | arg ) |
Definition at line 123 of file sat_base.h.
void operations_research::sat::AdaptGlobalParameters | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Update params.num_workers() if the old field was used.
Initialize the number of workers if set to 0.
Sometimes, hardware_concurrency will return 0. So always default to 1.
We currently only use the feasibility pump or rins/rens if it is enabled and some other parameters are not on.
We disable this if the global param asked for no LP.
Disable shared bounds if we are in single thread and we are not tightening the domains.
Definition at line 1707 of file cp_model_solver_helpers.cc.
void operations_research::sat::AddAllDiffRelaxationAndCutGenerator | ( | const ConstraintProto & | ct, |
int | linearization_level, | ||
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Build union of affine expressions domains to check if this is a permutation.
In case of a permutation, the linear constraint is tight.
Definition at line 1545 of file linear_relaxation.cc.
void operations_research::sat::AddCircuitCutGenerator | ( | const ConstraintProto & | ct, |
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Definition at line 575 of file linear_relaxation.cc.
void operations_research::sat::AddCircuitFlowConstraints | ( | LinearIncrementalEvaluator & | linear_evaluator, |
const ConstraintProto & | ct_proto ) |
Definition at line 1445 of file constraint_violation.cc.
|
inline |
Definition at line 652 of file integer_expr.h.
|
inline |
l => (a + b <= ub).
Definition at line 603 of file precedences.h.
|
inline |
l => (a + b + c <= ub).
Definition at line 620 of file precedences.h.
void operations_research::sat::AddCumulativeCutGenerator | ( | const AffineExpression & | capacity, |
SchedulingConstraintHelper * | helper, | ||
SchedulingDemandHelper * | demands_helper, | ||
const std::optional< AffineExpression > & | makespan, | ||
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Checks if at least one rectangle has a variable size, is optional, or if the demand or the capacity are variable.
Checks variable demand.
Definition at line 1611 of file linear_relaxation.cc.
void operations_research::sat::AddCumulativeOverloadChecker | ( | AffineExpression | capacity, |
SchedulingConstraintHelper * | helper, | ||
SchedulingDemandHelper * | demands, | ||
Model * | model ) |
Enforces the existence of a preemptive schedule where every task is executed inside its interval, using energy units of the resource during execution.
Important: This only uses the energies min/max and not the actual demand of a task. It can thus be used in some non-conventional situation.
All energy expression are assumed to take a non-negative value; if the energy of a task is 0, the task can run anywhere. The schedule never uses more than capacity units of energy at a given time.
This is mathematically equivalent to making a model with energy(task) different tasks with demand and size 1, but is much more efficient, since it uses O(tasks
) variables instead of O(sum_{task} |energy(task)|).
Definition at line 42 of file cumulative_energy.cc.
void operations_research::sat::AddCumulativeOverloadCheckerDff | ( | AffineExpression | capacity, |
SchedulingConstraintHelper * | helper, | ||
SchedulingDemandHelper * | demands, | ||
Model * | model ) |
Same as above, but applying a Dual Feasible Function (also known as a conservative scale) before looking for overload.
Definition at line 53 of file cumulative_energy.cc.
void operations_research::sat::AddCumulativeRelaxation | ( | const AffineExpression & | capacity, |
SchedulingConstraintHelper * | helper, | ||
SchedulingDemandHelper * | demands_helper, | ||
const std::optional< AffineExpression > & | makespan, | ||
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Scheduling relaxations and cut generators.
This relaxation will compute the bounding box of all tasks in the cumulative, and add the constraint that the sum of energies of each task must fit in the capacity * span area.
Adds linearization of cumulative constraints.The second part adds an energetic equation linking the duration of all potential tasks to the actual span * capacity of the cumulative constraint. It uses the makespan to compute the span of the constraint if defined.
There are no active intervals, no need to add the relaxation.
If nothing is variable, and the coefficients cannot be reduced, the linear relaxation will already be enforced by the scheduling propagators.
Specialized case 1: sizes are fixed with a non 1 gcd and no makespan.
We can simplify the capacity only if it is fixed.
Copy the decomposed energy.
The energy is defined if the vector is not empty. Let's reduce the coefficients.
We know the size is fixed.
Add the available energy of the cumulative.
The energy is defined if the vector is not empty.
The energy is not a decomposed product, but it could still be constant or linear. If not, a McCormick relaxation will be introduced. AddQuadraticLowerBound() supports all cases.
Create and link span_start and span_end to the starts and ends of the tasks.
Definition at line 791 of file linear_relaxation.cc.
void operations_research::sat::AddDisjunctive | ( | const std::vector< IntervalVariable > & | intervals, |
Model * | model ) |
Enforces a disjunctive (or no overlap) constraint on the given interval variables. The intervals are interpreted as [start, end) and the constraint enforces that no time point belongs to two intervals.
Depending on the parameters, create all pair of conditional precedences.
Experiments to use the timetable only to propagate the disjunctive.
We decided to create the propagators in this particular order, but it shouldn't matter much because of the different priorities used.
This one will not propagate anything if we added all precedence literals since the linear propagator will already do that in that case.
Only one direction is needed by this one.
Definition at line 39 of file disjunctive.cc.
void operations_research::sat::AddDisjunctiveWithBooleanPrecedencesOnly | ( | const std::vector< IntervalVariable > & | intervals, |
Model * | model ) |
Creates Boolean variables for all the possible precedences of the form (task i is before task j) and forces that, for each couple of task (i,j), either i is before j or j is before i. Do not create any other propagators.
Definition at line 155 of file disjunctive.cc.
void operations_research::sat::AddFullEncodingFromSearchBranching | ( | const CpModelProto & | model_proto, |
Model * | m ) |
Inspect the search strategy stored in the model, and adds a full encoding to variables appearing in a SELECT_MEDIAN_VALUE search strategy if the search branching is set to FIXED_SEARCH.
Definition at line 983 of file cp_model_loader.cc.
bool operations_research::sat::AddInferedAndDeletedClauses | ( | const std::string & | file_path, |
DratChecker * | drat_checker ) |
Adds to the given drat checker the infered and deleted clauses from the file at the given path, which must be in DRAT format. Returns true iff the file was successfully parsed.
Definition at line 564 of file drat_checker.cc.
void operations_research::sat::AddIntegerVariableFromIntervals | ( | SchedulingConstraintHelper * | helper, |
Model * | model, | ||
std::vector< IntegerVariable > * | vars ) |
Cuts helpers.
Definition at line 1212 of file intervals.cc.
void operations_research::sat::AddIntProdCutGenerator | ( | const ConstraintProto & | ct, |
int | linearization_level, | ||
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Cut generators.
Constraint is z == x * y.
We currently only support variables with non-negative domains.
Change signs to return to the case where all variables are a domain with non negative values only.
Definition at line 1443 of file linear_relaxation.cc.
bool operations_research::sat::AddLinearConstraintMultiple | ( | int64_t | factor, |
const ConstraintProto & | to_add, | ||
ConstraintProto * | to_modify ) |
Does "to_modify += factor * to_add". Both constraint must be linear. Returns false and does not change anything in case of overflow.
Copy to_modify terms.
Add factor * to_add and check first kind of overflow.
Merge terms, return false if we get an overflow here.
Copy terms.
Write new rhs. We want to be exact during the multiplication. Note that in practice this domain is fixed, so this will always be the case.
Definition at line 183 of file presolve_util.cc.
void operations_research::sat::AddLinearExpressionToLinearConstraint | ( | const LinearExpressionProto & | expr, |
int64_t | coefficient, | ||
LinearConstraintProto * | linear ) |
Adds a linear expression proto to a linear constraint in place.
Important: The domain must already be set, otherwise the offset will be lost. We also do not do any duplicate detection, so the constraint might need presolving afterwards.
Definition at line 585 of file cp_model_utils.cc.
void operations_research::sat::AddLinMaxCutGenerator | ( | const ConstraintProto & | ct, |
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Add initial big-M linear relaxation. z_vars[i] == 1 <=> target = exprs[i].
Definition at line 1735 of file linear_relaxation.cc.
IntegerVariable operations_research::sat::AddLPConstraints | ( | bool | objective_need_to_be_tight, |
const CpModelProto & | model_proto, | ||
Model * | m ) |
Adds one LinearProgrammingConstraint per connected component of the model.
Non const as we will std::move() stuff out of there.
The bipartite graph of LP constraints might be disconnected: make a partition of the variables into connected components. Constraint nodes are indexed by [0..num_lp_constraints), variable nodes by [num_lp_constraints..num_lp_constraints+num_variables).
Make sure any constraint that touch the objective is not discarded even if it is the only one in its component. This is important to propagate as much as possible the objective bound by using any bounds the LP give us on one of its components. This is critical on the zephyrus problems for instance.
Dispatch every constraint to its LinearProgrammingConstraint.
Load the constraint.
Dispatch every cut generator to its LinearProgrammingConstraint.
Add the objective.
First pass: set objective coefficients on the lp constraints, and store the cp terms in one vector per component.
Component is too small. We still need to store the objective term.
Second pass: Build the cp sub-objectives per component.
Register LP constraints. Note that this needs to be done after all the constraints have been added.
Definition at line 390 of file cp_model_solver_helpers.cc.
void operations_research::sat::AddMaxAffineCutGenerator | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
If the target is constant, propagation is enough.
Definition at line 1086 of file linear_relaxation.cc.
void operations_research::sat::AddNonOverlappingRectangles | ( | const std::vector< IntervalVariable > & | x, |
const std::vector< IntervalVariable > & | y, | ||
Model * | model ) |
Enforces that the boxes with corners in (x, y), (x + dx, y), (x, y + dy) and (x + dx, y + dy) do not overlap.
We must first check if the cumulative relaxation is possible.
Abort as the task would be conditioned by two literals.
We cannot use x_size as the demand of the cumulative based on the y_intervals.
We cannot use y_size as the demand of the cumulative based on the y_intervals.
void operations_research::sat::AddNoOverlap2dCutGenerator | ( | const ConstraintProto & | ct, |
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Checks if at least one rectangle has a variable dimension or is optional.
Ignore absent rectangles.
Checks non-present intervals.
Checks variable sized intervals.
Definition at line 1668 of file linear_relaxation.cc.
void operations_research::sat::AddNoOverlapCutGenerator | ( | SchedulingConstraintHelper * | helper, |
const std::optional< AffineExpression > & | makespan, | ||
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Checks if at least one rectangle has a variable size or is optional.
Definition at line 1645 of file linear_relaxation.cc.
bool operations_research::sat::AddObjectiveConstraint | ( | const LinearBooleanProblem & | problem, |
bool | use_lower_bound, | ||
Coefficient | lower_bound, | ||
bool | use_upper_bound, | ||
Coefficient | upper_bound, | ||
SatSolver * | solver ) |
Adds the constraint that the objective is smaller or equals to the given upper bound.
Definition at line 349 of file boolean_problem.cc.
bool operations_research::sat::AddObjectiveUpperBound | ( | const LinearBooleanProblem & | problem, |
Coefficient | upper_bound, | ||
SatSolver * | solver ) |
Adds the constraint that the objective is smaller than the given upper bound.
Definition at line 341 of file boolean_problem.cc.
|
inline |
Adds the offset and returns the scaled version of the given objective value.
Definition at line 39 of file boolean_problem.h.
bool operations_research::sat::AddProblemClauses | ( | const std::string & | file_path, |
DratChecker * | drat_checker ) |
Adds to the given drat checker the problem clauses from the file at the given path, which must be in DIMACS format. Returns true iff the file was successfully parsed.
Ignore empty and comment lines.
Definition at line 515 of file drat_checker.cc.
|
inline |
void operations_research::sat::AddReservoirConstraint | ( | std::vector< AffineExpression > | times, |
std::vector< AffineExpression > | deltas, | ||
std::vector< Literal > | presences, | ||
int64_t | min_level, | ||
int64_t | max_level, | ||
Model * | model ) |
Adds a reservoir constraint to the model. Note that to account for level not containing zero at time zero, we might needs to create an artificial fixed event.
This instantiate one or more ReservoirTimeTabling class to perform the propagation.
We only create a side if it can fail.
Definition at line 31 of file timetable.cc.
void operations_research::sat::AddRoutesCutGenerator | ( | const ConstraintProto & | ct, |
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Definition at line 589 of file linear_relaxation.cc.
void operations_research::sat::AddSquareCutGenerator | ( | const ConstraintProto & | ct, |
int | linearization_level, | ||
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Constraint is square == x * x.
We currently only support variables with non-negative domains.
Change the sigh of x if its domain is non-positive.
Definition at line 1521 of file linear_relaxation.cc.
|
inline |
|
inline |
enforcement_literals => sum >= lower_bound
We just negate everything and use an <= constraint.
Definition at line 584 of file integer_expr.h.
|
inline |
enforcement_literals => sum <= upper_bound
Linear1.
Detect precedences with 2 and 3 terms.
If value == min(expression), then we can avoid creating the sum.
Tricky: as we create integer literal, we might propagate stuff and the bounds might change, so if the expression_min increase with the bound we use, then the literal must be false.
Definition at line 468 of file integer_expr.h.
|
inline |
a + offset <= b. (when a and b are of the form 1 * var + offset).
Definition at line 588 of file precedences.h.
std::function< void(Model *)> operations_research::sat::AllDifferentAC | ( | const std::vector< IntegerVariable > & | variables | ) |
This constraint forces all variables to take different values. This is meant to be used as a complement to an alldifferent decomposition like AllDifferentBinary(): DO NOT USE WITHOUT ONE. Doing the filtering that the decomposition can do with an appropriate algorithm should be cheaper and yield more accurate explanations.
It uses the matching algorithm described in Regin at AAAI1994: "A filtering algorithm for constraints of difference in CSPs".
This will fully encode variables.
Definition at line 99 of file all_different.cc.
std::function< void(Model *)> operations_research::sat::AllDifferentBinary | ( | const std::vector< IntegerVariable > & | vars | ) |
Enforces that the given tuple of variables takes different values. This fully encodes all the variables and simply enforces a <= 1 constraint on each possible values.
Fully encode all the given variables and construct a mapping value -> List of literal each indicating that a given variable takes this value.
Add an at most one constraint for each value.
If the number of values is equal to the number of variables, we have a permutation. We can add a bool_or for each literals attached to a value.
Definition at line 38 of file all_different.cc.
std::function< void(Model *)> operations_research::sat::AllDifferentOnBounds | ( | const std::vector< AffineExpression > & | expressions | ) |
Definition at line 72 of file all_different.cc.
std::function< void(Model *)> operations_research::sat::AllDifferentOnBounds | ( | const std::vector< IntegerVariable > & | vars | ) |
Enforces that the given tuple of variables takes different values. Same as AllDifferentBinary() but use a different propagator that only enforce the so called "bound consistency" on the variable domains.
Compared to AllDifferentBinary() this doesn't require fully encoding the variables and it is also quite fast. Note that the propagation is different, this will not remove already taken values from inside a domain, but it will propagates more the domain bounds.
Definition at line 83 of file all_different.cc.
std::vector< int64_t > operations_research::sat::AllValuesInDomain | ( | const ProtoWithDomain & | proto | ) |
Returns the list of values in a given domain. This will fail if the domain contains more than one millions values.
Definition at line 147 of file cp_model_utils.h.
bool operations_research::sat::AnalyzeIntervals | ( | bool | transpose, |
absl::Span< const int > | boxes, | ||
absl::Span< const Rectangle > | rectangles, | ||
absl::Span< const IntegerValue > | rectangle_energies, | ||
IntegerValue * | x_threshold, | ||
IntegerValue * | y_threshold, | ||
Rectangle * | conflict = nullptr ) |
A O(n^2) algorithm to analyze all the relevant X intervals and infer a threshold of the y size of a bounding box after which there is no point checking for energy overload.
Returns false on conflict, and fill the bounding box that caused the conflict.
If transpose is true, we analyze the relevant Y intervals instead.
First, we compute the possible x_min values (removing duplicates). We also sort the relevant tasks by their x_max.
The maximum y dimension of a bounding area for which there is a potential conflict.
This is currently only used for logging.
All quantities at index j correspond to the interval [starts[j], x_max].
Sentinel.
Iterate over all boxes by increasing x_max values.
Add this box contribution to all the [starts[j], x_max] intervals.
If the new box is disjoint in y from the ones added so far, there cannot be a new conflict involving this box, so we skip until we add new boxes.
We have a conflict.
Because we currently do not have a conflict involving the new box, the only way to have one is to remove enough energy to reduce the y domain.
In this case, we need to remove at least old_energy_at_max to have a conflict.
If the new box height is above the conflict_height, do not count it now. We only need to consider conflict involving the new box.
Definition at line 226 of file diffn_util.cc.
void operations_research::sat::AppendAtMostOneRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Definition at line 416 of file linear_relaxation.cc.
void operations_research::sat::AppendBoolAndRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation, | ||
ActivityBoundHelper * | activity_helper ) |
If we have many_literals => many_fixed literal, it is important to try to use a tight big-M if we can. This is important on neos-957323.pb.gz for instance.
We split the literal into disjoint AMO and we encode each with sum Not(literals) <= sum Not(enforcement)
Definition at line 347 of file linear_relaxation.cc.
void operations_research::sat::AppendBoolOrRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Definition at line 333 of file linear_relaxation.cc.
void operations_research::sat::AppendCircuitRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Routing relaxation and cut generators.
Each node must have exactly one incoming and one outgoing arc (note that it can be the unique self-arc of this node too).
We separate the two constraints.
Definition at line 487 of file linear_relaxation.cc.
void operations_research::sat::AppendCumulativeRelaxationAndCutGenerator | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Adds linearization of cumulative constraints.The second part adds an energetic equation linking the duration of all potential tasks to the actual span * capacity of the cumulative constraint.
We remove the makespan data from the intervals the demands vector.
We try to linearize the energy of each task (size * demand).
We can now add the relaxation and the cut generators.
Definition at line 748 of file linear_relaxation.cc.
void operations_research::sat::AppendElementEncodingRelaxation | ( | Model * | m, |
LinearRelaxation * | relaxation ) |
If we have an exactly one between literals l_i, and each l_i => var == value_i, then we can add a strong linear relaxation: var = sum l_i * value_i.
This codes detect this and add the corresponding linear equations.
If the term has no view, we abort.
Definition at line 1785 of file linear_relaxation.cc.
void operations_research::sat::AppendExactlyOneRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
We just encode the at most one part that might be partially linearized later.
Definition at line 425 of file linear_relaxation.cc.
void operations_research::sat::AppendLinearConstraintRelaxation | ( | const ConstraintProto & | ct, |
bool | linearize_enforced_constraints, | ||
Model * | model, | ||
LinearRelaxation * | relaxation, | ||
ActivityBoundHelper * | activity_helper = nullptr ) |
Appends linear constraints to the relaxation. This also handles the relaxation of linear constraints with enforcement literals. A linear constraint lb <= ax <= ub with enforcement literals {ei} is relaxed as following. lb <= (Sum Negated(ei) * (lb - implied_lb)) + ax <= inf -inf <= (Sum Negated(ei) * (ub - implied_ub)) + ax <= ub Where implied_lb and implied_ub are trivial lower and upper bounds of the constraint.
Reified version.
We linearize fully reified constraints of size 1 all together for a given variable. But we need to process half-reified ones or constraint with more than one enforcement.
Compute min/max activity.
Everything here should have a view.
And(ei) => terms >= rhs_domain_min <=> Sum_i (~ei * (rhs_domain_min - min_activity)) + terms >= rhs_domain_min
And(ei) => terms <= rhs_domain_max <=> Sum_i (~ei * (rhs_domain_max - max_activity)) + terms <= rhs_domain_max
Definition at line 1184 of file linear_relaxation.cc.
void operations_research::sat::AppendLinMaxRelaxationPart1 | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Adds linearization of int max constraints. Returns a vector of z vars such that: z_vars[l] == 1 <=> target = exprs[l].
Consider the Lin Max constraint with d expressions and n variables in the form: target = max {exprs[l] = Sum (wli * xi + bl)}. l in {1,..,d}. Li = lower bound of xi Ui = upper bound of xi. Let zl be in {0,1} for all l in {1,..,d}. The target = exprs[l] when zl = 1.
The following is a valid linearization for Lin Max. target >= exprs[l], for all l in {1,..,d} target <= Sum_i(wki * xi) + Sum_l((Nkl + bl) * zl), for all k in {1,..,d} Where Nkl is a large number defined as: Nkl = Sum_i(max((wli - wki)*Li, (wli - wki)*Ui)) = Sum (max corner difference for variable i, target expr k, max expr l) Reference: "Strong mixed-integer programming formulations for trained neural networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).
We want to linearize target = max(exprs[1], exprs[2], ..., exprs[d]). Part 1: Encode target >= max(exprs[1], exprs[2], ..., exprs[d])
Definition at line 1044 of file linear_relaxation.cc.
void operations_research::sat::AppendLinMaxRelaxationPart2 | ( | IntegerVariable | target, |
const std::vector< Literal > & | alternative_literals, | ||
const std::vector< LinearExpression > & | exprs, | ||
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Part 2: Encode upper bound on X.
Add linking constraint to the CP solver sum zi = 1 and for all i, zi => max = expr_i.
First add the CP constraints.
For the relaxation, we use different constraints with a stronger linear relaxation as explained in the .h
Cache coefficients.
Definition at line 1110 of file linear_relaxation.cc.
void operations_research::sat::AppendMaxAffineRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Definition at line 1066 of file linear_relaxation.cc.
void operations_research::sat::AppendNoOverlap2dRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Adds the energetic relaxation sum(areas) <= bounding box area.
We have only one active literal.
Not including the term if we don't have a view is ok.
Definition at line 973 of file linear_relaxation.cc.
void operations_research::sat::AppendNoOverlapRelaxationAndCutGenerator | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Adds linearization of no overlap constraints. It adds an energetic equation linking the duration of all potential tasks to the actual span of the no overlap constraint.
Definition at line 711 of file linear_relaxation.cc.
void operations_research::sat::AppendPairwiseRestrictions | ( | absl::Span< const ItemForPairwiseRestriction > | items, |
absl::Span< const ItemForPairwiseRestriction > | other_items, | ||
std::vector< PairwiseRestriction > * | result ) |
Same as above, but test items
against other_items
and append the restrictions found to result
.
Definition at line 633 of file diffn_util.cc.
void operations_research::sat::AppendPairwiseRestrictions | ( | absl::Span< const ItemForPairwiseRestriction > | items, |
std::vector< PairwiseRestriction > * | result ) |
Find pair of items that are either in conflict or could have their range shrinked to avoid conflict.
Definition at line 623 of file diffn_util.cc.
void operations_research::sat::AppendPartialGreaterThanEncodingRelaxation | ( | IntegerVariable | var, |
const Model & | model, | ||
LinearRelaxation * | relaxation ) |
This is a different relaxation that use a partial set of literal li such that (li <=> var >= xi). In which case we use the following encoding:
Like for AppendRelaxationForEqualityEncoding() we skip any li that do not have an integer view.
Start by the var >= side. And also add the implications between used literals.
Skip the entry if the literal doesn't have a view.
Add var <= prev_var, which is the same as var + not(prev_var) <= 1
Do the same for the var <= side by using NegationOfVar().
Skip the entry if the literal doesn't have a view.
Definition at line 262 of file linear_relaxation.cc.
void operations_research::sat::AppendRelaxationForEqualityEncoding | ( | IntegerVariable | var, |
const Model & | model, | ||
LinearRelaxation * | relaxation, | ||
int * | num_tight, | ||
int * | num_loose ) |
Looks at all the encoding literal (li <=> var == value_i) that have a view and add a linear relaxation of their relationship with var.
If the encoding is full, we can just add:
When the set of such encoding literals do not cover the full domain of var, we do something a bit more involved. Let min_not_encoded/max_not_encoded the min and max value of the domain of var that is NOT part of the encoding. We add:
Note of the special case where min_not_encoded == max_not_encoded that kind of reduce to the full encoding, except with a different "rhs" value.
We also increment the corresponding counter if we added something. We consider the relaxation "tight" if the encoding was full or if min_not_encoded == max_not_encoded.
This means that there are no non-encoded value and we have a full encoding. We substract the minimum value to reduce its size.
It is possible that the linear1 encoding respect our overflow precondition but not the Var = sum bool * value one. In this case, we just don't encode it this way. Hopefully, most normal model will not run into this.
In this special case, the two constraints below can be merged into an equality: var = rhs + sum l_i * (value_i - rhs).
min + sum l_i * (value_i - min) <= var.
var <= max + sum l_i * (value_i - max).
Definition at line 136 of file linear_relaxation.cc.
void operations_research::sat::AppendRoutesRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Each node except node zero must have exactly one incoming and one outgoing arc (note that it can be the unique self-arc of this node too). For node zero, the number of incoming arcs should be the same as the number of outgoing arcs.
We separate the two constraints.
Definition at line 525 of file linear_relaxation.cc.
void operations_research::sat::AppendSquareRelaxation | ( | const ConstraintProto & | ct, |
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Constraint is square == x * x.
We currently only support variables with non-negative domains.
Change the sigh of x if its domain is non-positive.
Check for potential overflows.
The hyperplan will use x_ub - 1 and x_ub.
Definition at line 1479 of file linear_relaxation.cc.
void operations_research::sat::AppendVariablesFromCapacityAndDemands | ( | const AffineExpression & | capacity, |
SchedulingDemandHelper * | demands_helper, | ||
Model * | model, | ||
std::vector< IntegerVariable > * | vars ) |
Definition at line 1238 of file intervals.cc.
bool operations_research::sat::ApplyLiteralMapping | ( | const util_intops::StrongVector< LiteralIndex, LiteralIndex > & | mapping, |
std::vector< LiteralWithCoeff > * | cst, | ||
Coefficient * | bound_shift, | ||
Coefficient * | max_value ) |
Maps all the literals of the given constraint using the given mapping. The mapping may map a literal index to kTrueLiteralIndex or kFalseLiteralIndex in which case the literal will be considered fixed to the appropriate value.
Finally, this will return false if some integer overflow or underflow occurred during the constraint simplification.
Nothing to do if the literal is false.
Definition at line 117 of file pb_constraint.cc.
void operations_research::sat::ApplyLiteralMappingToBooleanProblem | ( | const util_intops::StrongVector< LiteralIndex, LiteralIndex > & | mapping, |
LinearBooleanProblem * | problem ) |
Maps all the literals of the problem. Note that this converts the cost of a variable correctly, that is if a variable with cost is mapped to another, the cost of the later is updated.
Preconditions: the mapping must map l and not(l) to the same variable and be of the correct size. It can also map a literal index to kTrueLiteralIndex or kFalseLiteralIndex in order to fix the variable.
First the objective.
Now the clauses.
Add bound_shift to the bounds and remove a bound if it is now trivial.
This is because ApplyLiteralMapping make all coefficient positive.
If the constraint is always true, we just leave it empty.
Remove empty constraints.
Computes the new number of variables and set it.
Definition at line 755 of file boolean_problem.cc.
void operations_research::sat::ApplyToAllIntervalIndices | ( | const std::function< void(int *)> & | f, |
ConstraintProto * | ct ) |
Definition at line 368 of file cp_model_utils.cc.
void operations_research::sat::ApplyToAllLiteralIndices | ( | const std::function< void(int *)> & | f, |
ConstraintProto * | ct ) |
Definition at line 207 of file cp_model_utils.cc.
void operations_research::sat::ApplyToAllVariableIndices | ( | const std::function< void(int *)> & | function, |
ConstraintProto * | ct ) |
Applies the given function to all variables/literals/intervals indices of the constraint. This function is used in a few places to have a "generic" code dealing with constraints.
Definition at line 270 of file cp_model_utils.cc.
void operations_research::sat::ApplyVariableMapping | ( | const std::vector< int > & | mapping, |
const PresolveContext & | context ) |
Replaces all the instance of a variable i (and the literals referring to it) by mapping[i]. The definition of variables i is also moved to its new index. Variables with a negative mapping value are ignored and it is an error if such variable is referenced anywhere (this is CHECKed).
The image of the mapping should be dense in [0, new_num_variables), this is also CHECKed.
Remap all the variable/literal references in the constraints and the enforcement literals in the variables.
Remap the objective variables.
Remap the assumptions.
Remap the search decision heuristic.
Remove strategy with empty affine expression.
Remap the solution hint. Note that after remapping, we may have duplicate variable, so we only keep the first occurrence.
We always move a hint within bounds. This also make sure a hint of INT_MIN or INT_MAX does not overflow.
Move the variable definitions.
Check that all variables are used.
Definition at line 13057 of file cp_model_presolve.cc.
|
inline |
IntegerLiteral operations_research::sat::AtMinValue | ( | IntegerVariable | var, |
IntegerTrail * | integer_trail ) |
Returns decision corresponding to var at its lower bound. Returns an invalid literal if the variable is fixed.
Definition at line 57 of file integer_search.cc.
|
inline |
Definition at line 919 of file sat_solver.h.
std::vector< absl::Span< int > > operations_research::sat::AtMostOneDecomposition | ( | const std::vector< std::vector< int > > & | graph, |
absl::BitGenRef | random, | ||
std::vector< int > * | buffer ) |
Assuming n "literal" in [0, n), and a graph such that graph[i] list the literal in [0, n) implied to false when the literal with index i is true, this returns an heuristic decomposition of the literals into disjoint at most ones.
Note(user): Symmetrize the matrix if not already, maybe rephrase in term of undirected graph, and clique decomposition.
std::vector< std::vector< int > > operations_research::sat::BasicOrbitopeExtraction | ( | absl::Span< const std::unique_ptr< SparsePermutation > > | generators | ) |
Given the generator for a permutation group of [0, n-1], tries to identify a grouping of the variables in an p x q matrix such that any permutations of the columns of this matrix is in the given group.
The name comes from: "Packing and Partitioning Orbitopes", Volker Kaibel, Marc E. Pfetsch, https://arxiv.org/abs/math/0603678 . Here we just detect it, independently of the constraints on the variables in this matrix. We can also detect non-Boolean orbitope.
In order to detect orbitope, this basic algorithm requires that the generators of the orbitope must only contain one or more 2-cyle (i.e transpositions). Thus they must be involutions. The list of transpositions in the SparsePermutation must also be listed in a canonical order.
Count the number of permutations that are compositions of 2-cycle and regroup them according to the number of cycles.
Heuristic: we try to grow the orbitope that has the most potential for fixing variables.
We will track the element already added so we never have duplicates.
Greedily grow the orbitope.
Start using the first permutation.
We want to find a column such that g sends it to variables not already in the orbitope matrix.
Note(user): This relies on the cycle in each permutation to be ordered by smaller element first. This way we don't have to account any row permutation of the orbitope matrix. The code that detect the symmetries of the problem should already return permutation in this canonical format.
Extract the two elements of this transposition.
We want one element to appear in matching_column_index and the other to not appear at all.
If grow is of full size, we can extend the orbitope.
Definition at line 30 of file symmetry_util.cc.
|
inline |
Model based functions.
Definition at line 880 of file sat_solver.h.
bool operations_research::sat::BooleanLinearExpressionIsCanonical | ( | absl::Span< const LiteralWithCoeff > | cst | ) |
Returns true iff the Boolean linear expression is in canonical form.
Definition at line 150 of file pb_constraint.cc.
CpModelProto operations_research::sat::BooleanProblemToCpModelproto | ( | const LinearBooleanProblem & | problem | ) |
Converts a LinearBooleanProblem to a CpModelProto which should eventually replace completely the LinearBooleanProblem proto.
The term was coeff * (1 - var).
Definition at line 164 of file boolean_problem.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::BoolPseudoCostHeuristic | ( | Model * | model | ) |
Variant used for LbTreeSearch experimentation. Note that each decision is in O(num_variables), but it is kind of ok with LbTreeSearch as we only call this for "new" decision, not when we move around in the tree.
Only look at non-fixed booleans.
Get associated literal.
Definition at line 203 of file integer_search.cc.
bool operations_research::sat::BoxesAreInEnergyConflict | ( | const std::vector< Rectangle > & | rectangles, |
const std::vector< IntegerValue > & | energies, | ||
absl::Span< const int > | boxes, | ||
Rectangle * | conflict = nullptr ) |
Visible for testing. The algo is in O(n^4) so shouldn't be used directly. Returns true if there exist a bounding box with too much energy.
First consider all relevant intervals along the x axis.
Redo the same on the y coordinate for the current x interval which is [starts[j], x_max].
Definition at line 159 of file diffn_util.cc.
BruteForceResult operations_research::sat::BruteForceOrthogonalPacking | ( | absl::Span< const IntegerValue > | sizes_x, |
absl::Span< const IntegerValue > | sizes_y, | ||
std::pair< IntegerValue, IntegerValue > | bounding_box_size, | ||
int | max_complexity ) |
It is unlikely that preprocessing will remove half of the items, so don't lose time trying.
VLOG_EVERY_N_SEC(3, 3) << "Found a feasible packing by brute force. Dot:\n " << RenderDot(bounding_box_size, result);
Definition at line 640 of file 2d_packing_brute_force.cc.
bool operations_research::sat::BuildMaxAffineUpConstraint | ( | const LinearExpression & | target, |
IntegerVariable | var, | ||
const std::vector< std::pair< IntegerValue, IntegerValue > > & | affines, | ||
Model * | model, | ||
LinearConstraintBuilder * | builder ) |
Helper for the affine max constraint.
This function will reset the bounds of the builder.
target <= y_at_min + (delta_y / delta_x) * (var - x_min) delta_x * target <= delta_x * y_at_min + delta_y * (var - x_min) -delta_y * var + delta_x * target <= delta_x * y_at_min - delta_y * x_min
Checks the rhs for overflows.
Checks target * delta_x for overflow.
Prevent to create constraints that can overflow.
LinearExpression operations_research::sat::CanonicalizeExpr | ( | const LinearExpression & | expr | ) |
Returns the same expression in the canonical form (all positive coefficients).
Definition at line 380 of file linear_constraint.cc.
bool operations_research::sat::CanonicalizeLinearExpressionInternal | ( | absl::Span< const int > | enforcements, |
ProtoWithVarsAndCoeffs * | proto, | ||
int64_t * | offset, | ||
std::vector< std::pair< int, int64_t > > * | tmp_terms, | ||
PresolveContext * | context ) |
First regroup the terms on the same variables and sum the fixed ones.
Remove fixed variable and take affine representative.
If the constraint is enforced, we can assume the variable is at 1.
We can assume the variable is at zero.
Definition at line 2340 of file presolve_context.cc.
|
inline |
|
inline |
|
inline |
|
inline |
Definition at line 890 of file sat_solver.h.
IntType operations_research::sat::CeilOfRatio | ( | IntType | numerator, |
IntType | denominator ) |
IntType operations_research::sat::CeilOrFloorOfRatio | ( | IntType | numerator, |
IntType | denominator ) |
|
inline |
int64_t operations_research::sat::CeilSquareRoot | ( | int64_t | a | ) |
void operations_research::sat::ChangeLargeBoundsToInfinity | ( | double | max_magnitude, |
MPModelProto * | mp_model, | ||
SolverLogger * | logger ) |
This function changes bounds of variables or constraints that have a magnitude greater than mip_max_valid_magnitude.
Definition at line 237 of file lp_utils.cc.
void operations_research::sat::ChangeOptimizationDirection | ( | LinearBooleanProblem * | problem | ) |
Keeps the same objective but change the optimization direction from a minimization problem to a maximization problem.
Ex: if the problem was to minimize 2 + x, the new problem will be to maximize 2 + x subject to exactly the same constraints.
We need 'auto' here to keep the open-source compilation happy (it uses the public protobuf release).
Definition at line 221 of file boolean_problem.cc.
IntegerLiteral operations_research::sat::ChooseBestObjectiveValue | ( | IntegerVariable | var, |
Model * | model ) |
If a variable appear in the objective, branch on its best objective value.
Definition at line 64 of file integer_search.cc.
std::function< void(Model *)> operations_research::sat::CircuitCovering | ( | const std::vector< std::vector< Literal > > & | graph, |
const std::vector< int > & | distinguished_nodes ) |
Definition at line 697 of file circuit.cc.
|
inline |
Definition at line 933 of file sat_solver.h.
|
inline |
Specific function. Returns true if the negation of all literals in clause except literal is exactly equal to the literal of enforcement.
We assumes that enforcement and negated(clause) are sorted lexicographically Or negated(enforcement) and clause. Both option works. If not, we will only return false more often. When we return true, the property is enforced.
Definition at line 331 of file presolve_util.h.
|
inline |
Sort and add coeff of duplicate variables. Note that a variable and its negation will appear one after another in the natural order.
Definition at line 368 of file linear_constraint.h.
|
inline |
Sorts and merges duplicate IntegerVariable in the given "terms". Fills the given LinearConstraint or LinearExpression with the result.
Sort and add coeff of duplicate variables. Note that a variable and its negation will appear one after another in the natural order.
Definition at line 337 of file linear_constraint.h.
int64_t operations_research::sat::ClosestMultiple | ( | int64_t | value, |
int64_t | base ) |
int operations_research::sat::CombineSeed | ( | int | base_seed, |
int64_t | delta ) |
We assume delta >= 0 and we only use the low bit of delta.
Definition at line 938 of file cp_model_utils.cc.
std::vector< std::function< BooleanOrIntegerLiteral()> > operations_research::sat::CompleteHeuristics | ( | absl::Span< const std::function< BooleanOrIntegerLiteral()> > | incomplete_heuristics, |
const std::function< BooleanOrIntegerLiteral()> & | completion_heuristic ) |
Concatenates each input_heuristic with a default heuristic that instantiate all the problem's Boolean variables, into a new vector.
Definition at line 1307 of file integer_search.cc.
void operations_research::sat::CompressTuples | ( | absl::Span< const int64_t > | domain_sizes, |
std::vector< std::vector< int64_t > > * | tuples ) |
double operations_research::sat::ComputeActivity | ( | const LinearConstraint & | constraint, |
const util_intops::StrongVector< IntegerVariable, double > & | values ) |
Returns the activity of the given constraint. That is the current value of the linear terms.
Definition at line 165 of file linear_constraint.cc.
bool operations_research::sat::ComputeBooleanLinearExpressionCanonicalForm | ( | std::vector< LiteralWithCoeff > * | cst, |
Coefficient * | bound_shift, | ||
Coefficient * | max_value ) |
Puts the given Boolean linear expression in canonical form:
This function also computes:
Finally, this will return false, if some integer overflow or underflow occurred during the reduction to the canonical form.
Note(user): For some reason, the IntType checking doesn't work here ?! that is a bit worrying, but the code seems to behave correctly.
First, sort by literal to remove duplicate literals. This also remove term with a zero coefficient.
Here current_literal is equal to (1 - representative).
Then, make all coefficients positive by replacing a term "-c x" into "c(1-x) - c" which is the same as "c(not x) - c".
Finally sort by increasing coefficients.
Definition at line 55 of file pb_constraint.cc.
Coefficient operations_research::sat::ComputeCanonicalRhs | ( | Coefficient | upper_bound, |
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 a new rhs such that 'canonical expression <= rhs' is an equivalent constraint. This function deals with all the possible overflow corner cases.
The result will be in [-1, max_value] where -1 means unsatisfiable and max_value means trivialy satisfiable.
Positive overflow. The constraint is trivially true. This is because the canonical linear expression is in [0, max_value].
Negative overflow. The constraint is infeasible.
Definition at line 174 of file pb_constraint.cc.
Coefficient operations_research::sat::ComputeCoreMinWeight | ( | const std::vector< EncodingNode * > & | nodes, |
const std::vector< Literal > & | core ) |
Returns the minimum weight of the nodes in the core. Note that the literal in the core must appear in the same order as the one in nodes.
Definition at line 560 of file encoding.cc.
IntegerValue operations_research::sat::ComputeEnergyMinInWindow | ( | IntegerValue | start_min, |
IntegerValue | start_max, | ||
IntegerValue | end_min, | ||
IntegerValue | end_max, | ||
IntegerValue | size_min, | ||
IntegerValue | demand_min, | ||
absl::Span< const LiteralValueValue > | filtered_energy, | ||
IntegerValue | window_start, | ||
IntegerValue | window_end ) |
Utilities
Returns zero if the interval do not necessarily overlap.
Definition at line 865 of file intervals.cc.
std::vector< int > operations_research::sat::ComputeGomoryHuTree | ( | int | num_nodes, |
const std::vector< ArcWithLpValue > & | relevant_arcs ) |
Given a set of arcs on a directed graph with n nodes (in [0, num_nodes)), returns a "parent" vector of size n encoding a rooted Gomory-Hu tree.
IMPORTANT: This algorithm currently "symmetrize" the graph, so we will actually have all the min-cuts that minimize sum incoming + sum outgoing lp values. The algo do not work as is on an asymmetric graph. Note however that because of flow conservation, our outgoing lp values should be the same as our incoming one on a circuit/route constraint.
We use a simple implementation described in "Very Simple Methods for All Pairs Network Flow Analysis", Dan Gusfield, 1990, https://ranger.uta.edu/~weems/NOTES5311/LAB/LAB2SPR21/gusfield.huGomory.pdf
Initialize the graph. Note that we use only arcs with a relevant lp value, so this should be small in practice.
Compute an equivalent max-flow tree, according to the paper. This version should actually produce a Gomory-Hu cut tree.
Definition at line 517 of file routing_cuts.cc.
LinearConstraint operations_research::sat::ComputeHyperplanAboveSquare | ( | AffineExpression | x, |
AffineExpression | square, | ||
IntegerValue | x_lb, | ||
IntegerValue | x_ub, | ||
Model * | model ) |
LinearConstraint operations_research::sat::ComputeHyperplanBelowSquare | ( | AffineExpression | x, |
AffineExpression | square, | ||
IntegerValue | x_value, | ||
Model * | model ) |
Below hyperplan for square = x * x: y should be above the line (x_value, x_value ^ 2) to (x_value + 1, (x_value + 1) ^ 2) The slope of that line is 2 * x_value + 1 square >= below_slope * (x - x_value) + x_value ^ 2 square >= below_slope * x - x_value ^ 2 - x_value
IntegerValue operations_research::sat::ComputeInfinityNorm | ( | const LinearConstraint & | ct | ) |
Returns the maximum absolute value of the coefficients.
Definition at line 209 of file linear_constraint.cc.
int64_t operations_research::sat::ComputeInnerObjective | ( | const CpObjectiveProto & | objective, |
absl::Span< const int64_t > | solution ) |
Computes the "inner" objective of a response that contains a solution. This is the objective without offset and scaling. Call ScaleObjectiveValue() to get the user facing objective.
Definition at line 556 of file cp_model_utils.cc.
double operations_research::sat::ComputeL2Norm | ( | const LinearConstraint & | ct | ) |
Returns sqrt(sum square(coeff)).
Definition at line 201 of file linear_constraint.cc.
LinearRelaxation operations_research::sat::ComputeLinearRelaxation | ( | const CpModelProto & | model_proto, |
Model * | m ) |
Builds the linear relaxation of a CpModelProto.
Collect AtMostOne to compute better Big-M.
Linearize the constraints.
Linearize the encoding of variable that are fully encoded.
We first try to linearize the values encoding.
Then we try to linearize the inequality encoding. Note that on some problem like pizza27i.mps.gz, adding both equality and inequality encoding is a must.
Even if the variable is fully encoded, sometimes not all its associated literal have a view (if they are not part of the original model for instance).
We display the stats before linearizing the at most ones.
Linearize the at most one constraints. Note that we transform them into maximum "at most one" first and we removes redundant ones.
We converted all at_most_one to LP constraints, so we need to clear them so that we don't do extra work in the connected component computation.
Propagate unary constraints.
Remove size one LP constraints from the main algorithms, they are not useful.
We add a clique cut generation over all Booleans of the problem.
We add a generator touching all the variable in the builder.
Definition at line 1827 of file linear_relaxation.cc.
bool operations_research::sat::ComputeMinSumOfWeightedEndMins | ( | std::vector< PermutableEvent > & | events, |
IntegerValue | capacity_max, | ||
IntegerValue & | min_sum_of_end_mins, | ||
IntegerValue & | min_sum_of_weighted_end_mins, | ||
IntegerValue | unweighted_threshold, | ||
IntegerValue | weighted_threshold ) |
Reusable storage for ComputeWeightedSumOfEndMinsForOnePermutation().
Definition at line 1095 of file scheduling_cuts.cc.
Coefficient operations_research::sat::ComputeNegatedCanonicalRhs | ( | Coefficient | lower_bound, |
Coefficient | bound_shift, | ||
Coefficient | max_value ) |
Same as ComputeCanonicalRhs(), but uses the initial constraint lower bound instead. From a constraint 'lb <= expression', this returns a rhs such that 'canonical expression with literals negated <= rhs'.
The new bound is "max_value - (lower_bound + bound_shift)", but we must pay attention to possible overflows.
Positive overflow. The constraint is infeasible.
Negative overflow. The constraint is trivialy satisfiable.
If shifted_lb <= 0 then the constraint is trivialy satisfiable. We test this so we are sure that max_value - shifted_lb doesn't overflow below.
Definition at line 192 of file pb_constraint.cc.
Coefficient operations_research::sat::ComputeObjectiveValue | ( | const LinearBooleanProblem & | problem, |
const std::vector< bool > & | assignment ) |
Returns the objective value under the current assignment.
Definition at line 359 of file boolean_problem.cc.
bool operations_research::sat::ComputeResolvant | ( | Literal | x, |
const std::vector< Literal > & | a, | ||
const std::vector< Literal > & | b, | ||
std::vector< Literal > * | out ) |
Visible for testing. Computes the resolvant of 'a' and 'b' obtained by performing the resolution on 'x'. If the resolvant is trivially true this returns false, otherwise it returns true and fill 'out' with the resolvant.
This is the basic operation when a variable is eliminated by clause distribution.
Copy remaining literals.
Definition at line 1027 of file simplification.cc.
int operations_research::sat::ComputeResolvantSize | ( | Literal | x, |
const std::vector< Literal > & | a, | ||
const std::vector< Literal > & | b ) |
Same as ComputeResolvant() but just returns the resolvant size. Returns -1 when ComputeResolvant() returns false.
Definition at line 1062 of file simplification.cc.
double operations_research::sat::ComputeTrueObjectiveLowerBound | ( | const CpModelProto & | model_proto_with_floating_point_objective, |
const CpObjectiveProto & | integer_objective, | ||
int64_t | inner_integer_objective_lower_bound ) |
Given a CpModelProto with a floating point objective, and its scaled integer version with a known lower bound, this uses the variable bounds to derive a correct lower bound on the original objective.
Create an LP with the correct variable domain.
Add the original problem floating point objective. This is user given, so we do need to deal with duplicate entries.
Add a single constraint "integer_objective >= lower_bound".
This should be fast. However, in case of numerical difficulties, we bound the number of iterations.
Error. Hoperfully this shouldn't happen.
Definition at line 1703 of file lp_utils.cc.
|
inline |
is_le => (a + offset <= b).
Definition at line 656 of file precedences.h.
|
inline |
Definition at line 605 of file integer_expr.h.
|
inline |
Definition at line 596 of file integer_expr.h.
void operations_research::sat::ConfigureSearchHeuristics | ( | Model * | model | ) |
Given a base "fixed_search" function that should mainly control in which order integer variables are lazily instantiated (and at what value), this uses the current solver parameters to set the SearchHeuristics class in the given model.
Not all Boolean might appear in fixed_search(), so once there is no decision left, we fix all Booleans that are still undecided.
Push user search if present.
Do a portfolio with the default sat heuristics.
Use default restart policies.
Definition at line 1185 of file integer_search.cc.
|
inline |
absl::string_view operations_research::sat::ConstraintCaseName | ( | ConstraintProto::ConstraintCase | constraint_case | ) |
Returns the name of the ConstraintProto::ConstraintCase oneof enum. Note(user): There is no such function in the proto API as of 16/01/2017.
Definition at line 429 of file cp_model_utils.cc.
bool operations_research::sat::ConstraintIsFeasible | ( | const CpModelProto & | model, |
const ConstraintProto & | constraint, | ||
absl::Span< const int64_t > | variable_values ) |
Checks a single constraint for feasibility. This has some overhead, and should only be used for debugging. The full model is needed for scheduling constraints that refers to intervals.
Definition at line 1684 of file cp_model_checker.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ConstructFixedSearchStrategy | ( | std::function< BooleanOrIntegerLiteral()> | user_search, |
std::function< BooleanOrIntegerLiteral()> | heuristic_search, | ||
std::function< BooleanOrIntegerLiteral()> | integer_completion ) |
Constructs our "fixed" search strategy which start with ConstructUserSearchStrategy() but is completed by a couple of automatic heuristics.
We start by the user specified heuristic.
Definition at line 402 of file cp_model_search.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ConstructHeuristicSearchStrategy | ( | const CpModelProto & | cp_model_proto, |
Model * | model ) |
Constructs a search strategy tailored for the current model.
Tricky: we need to create this at level zero in case there are no linear constraint in the model at the beginning.
Definition at line 327 of file cp_model_search.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ConstructHintSearchStrategy | ( | const CpModelProto & | cp_model_proto, |
CpModelMapping * | mapping, | ||
Model * | model ) |
Constructs a search strategy that follow the hint from the model.
Constructs a search strategy that follows the hints from the model.
Definition at line 383 of file cp_model_search.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ConstructIntegerCompletionSearchStrategy | ( | const std::vector< IntegerVariable > & | variable_mapping, |
IntegerVariable | objective_var, | ||
Model * | model ) |
Constructs an integer completion search strategy.
Make sure we try to fix the objective to its lowest value first.
Definition at line 358 of file cp_model_search.cc.
void operations_research::sat::ConstructOverlappingSets | ( | bool | already_sorted, |
std::vector< IndexedInterval > * | intervals, | ||
std::vector< std::vector< int > > * | result ) |
Given n fixed intervals, returns the subsets of intervals that overlap during at least one time unit. Note that we only return "maximal" subset and filter subset strictly included in another.
All Intervals must have a positive size.
The algo is in O(n log n) + O(result_size) which is usually O(n^2).
We do a line sweep. The "current" subset crossing the "line" at (time, time + 1) will be in (*intervals)[start_index, end_index) at the end of the loop block.
First, if there is some deletion, we will push the "old" set to the result before updating it. Otherwise, we will have a superset later, so we just continue for now.
Do not output subset of size one.
Add all the new intervals starting exactly at "time".
Definition at line 421 of file diffn_util.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ConstructUserSearchStrategy | ( | const CpModelProto & | cp_model_proto, |
Model * | model ) |
Constructs the search strategy specified in the given CpModelProto.
To store equivalent variables in randomized search.
The size of the domain is not multiplied by the coeff.
The size of the domain is not multiplied by the coeff.
We need to use -value as we want the minimum valued variables. We add a random noise to get improve the entropy.
We can stop scanning if the variable selection strategy is to use the first unbound variable and no randomization is needed.
Check if one active variable has been found.
Pick the winner when decisions are randomized.
Definition at line 184 of file cp_model_search.cc.
bool operations_research::sat::ContainsLiteral | ( | absl::Span< const Literal > | clause, |
Literal | literal ) |
Returns true if the given clause contains the given literal. This works in O(clause.size()).
Definition at line 474 of file drat_checker.cc.
bool operations_research::sat::ConvertBinaryMPModelProtoToBooleanProblem | ( | const MPModelProto & | mp_model, |
LinearBooleanProblem * | problem ) |
Converts an integer program with only binary variables to a Boolean optimization problem. Returns false if the problem didn't contains only binary integer variable, or if the coefficients couldn't be converted to integer with a good enough precision.
Test if the variables are binary variables. Add constraints for the fixed variables.
This will be changed to false as soon as we detect the variable to be non-binary. This is done this way so we can display a nice error message before aborting the function and returning false.
4 cases.
Binary variable. Ok.
Fixed variable at 1.
Fixed variable at 0.
No possible integer value!
Abort if the variable is not binary.
Variables needed to scale the double coefficients into int64_t.
Add all constraints.
First scale the coefficients of the constraints.
Add the bounds. Note that we do not pass them to GetBestScalingOfDoublesToInt64() because we know that the sum of absolute coefficients of the constraint fit on an int64_t. If one of the scaled bound overflows, we don't care by how much because in this case the constraint is just trivial or unsatisfiable.
Otherwise, the constraint is not needed.
Otherwise, the constraint is not needed.
Display the error/scaling without taking into account the objective first.
Add the objective.
Display the objective error/scaling.
If the problem was a maximization one, we need to modify the objective.
Test the precision of the conversion.
Definition at line 1460 of file lp_utils.cc.
void operations_research::sat::ConvertBooleanProblemToLinearProgram | ( | const LinearBooleanProblem & | problem, |
glop::LinearProgram * | lp ) |
Converts a Boolean optimization problem to its lp formulation.
Variables name are optional.
Objective.
Definition at line 1639 of file lp_utils.cc.
bool operations_research::sat::ConvertCpModelProtoToCnf | ( | const CpModelProto & | cp_model, |
std::string * | out ) |
We should have no objective, only unassigned Boolean, and only bool_or and bool_and.
We can convert.
Definition at line 881 of file cp_model_utils.cc.
bool operations_research::sat::ConvertCpModelProtoToMPModelProto | ( | const CpModelProto & | input, |
MPModelProto * | output ) |
Converts a CP-SAT model to a MPModelProto one. This only works for pure linear model (otherwise it returns false). This is mainly useful for debugging or using CP-SAT presolve and then trying other MIP solvers.
Copy variables.
Copy integer or float objective.
Copy constraint.
Compute min/max activity.
term <= ub + coeff * (1 - enf);
term >= lb + coeff * (1 - enf)
Definition at line 1150 of file lp_utils.cc.
bool operations_research::sat::ConvertMPModelProtoToCpModelProto | ( | const SatParameters & | params, |
const MPModelProto & | mp_model, | ||
CpModelProto * | cp_model, | ||
SolverLogger * | logger ) |
Converts a MIP problem to a CpModel. Returns false if the coefficients couldn't be converted to integers with a good enough precision.
There is a bunch of caveats and you can find more details on the SatParameters proto documentation for the mip_* parameters.
To make sure we cannot have integer overflow, we use this bound for any unbounded variable.
Add the variables.
Deal with the corner case of a domain far away from zero.
Notify if a continuous variable has a small domain as this is likely to make an all integer solution far from a continuous one.
Add the constraints. We scale each of them individually.
Add the indicator.
Display the error/scaling on the constraints.
Since cp_model support a floating point objective, we use that. This will allow us to scale the objective a bit later so we can potentially do more domain reduction first.
If the objective is fixed to zero, we consider there is none.
Definition at line 933 of file lp_utils.cc.
void operations_research::sat::CopyEverythingExceptVariablesAndConstraintsFieldsIntoContext | ( | const CpModelProto & | in_model, |
PresolveContext * | context ) |
Copies the non constraint, non variables part of the model.
We make sure we do not use the old variables field.
Definition at line 12380 of file cp_model_presolve.cc.
std::string operations_research::sat::CpModelStats | ( | const CpModelProto & | model_proto | ) |
Returns a string with some statistics on the given CpModelProto.
Public API.
We split the linear constraints into 3 buckets has it gives more insight on the type of problem we are facing.
For pure Boolean constraints, we also display the total number of literal involved as this gives a good idea of the problem size.
We always list Boolean first.
Definition at line 161 of file cp_model_solver.cc.
std::string operations_research::sat::CpSatSolverVersion | ( | ) |
Returns a string that describes the version of the solver.
Definition at line 124 of file cp_model_solver.cc.
std::string operations_research::sat::CpSolverResponseStats | ( | const CpSolverResponse & | response, |
bool | has_objective = true ) |
Returns a string with some statistics on the solver response.
If the second argument is false, we will just display NA for the objective value instead of zero. It is not really needed but it makes things a bit clearer to see that there is no objective.
Definition at line 567 of file cp_model_solver.cc.
CutGenerator operations_research::sat::CreateAllDifferentCutGenerator | ( | const std::vector< AffineExpression > & | exprs, |
Model * | model ) |
A cut generator for all_diff(xi). Let the united domain of all xi be D. Sum of any k-sized subset of xi need to be greater or equal to the sum of smallest k values in D and lesser or equal to the sum of largest k values in D. The cut generator first sorts the variables based on LP values and adds cuts of the form described above if they are violated by lp solution. Note that all the fixed variables are ignored while generating cuts.
These cuts work at all levels but the generator adds too many cuts on some instances and degrade the performance so we only use it at level
Other direction.
std::vector< Literal > operations_research::sat::CreateAlternativeLiteralsWithView | ( | int | num_literals, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Returns a vector of new literals in exactly one relationship. In addition, this create an IntegerView for all these literals and also add the exactly one to the LinearRelaxation.
This is not supposed to happen, but it is easy enough to cover, just in case. We might however want to use encoder->GetTrueLiteral().
Definition at line 446 of file linear_relaxation.cc.
CutGenerator operations_research::sat::CreateCliqueCutGenerator | ( | const std::vector< IntegerVariable > & | base_variables, |
Model * | model ) |
Extracts the variables that have a Literal view from base variables and create a generator that will returns constraint of the form "at_most_one" between such literals.
Filter base_variables to only keep the one with a literal view, and do the conversion.
We need to express such "at most one" in term of the initial variables, so we do not use the LinearConstraintBuilder::AddLiteralTerm() here.
Add 1 - X to the linear constraint.
CutGenerator operations_research::sat::CreateCumulativeCompletionTimeCutGenerator | ( | SchedulingConstraintHelper * | helper, |
SchedulingDemandHelper * | demands_helper, | ||
const AffineExpression & | capacity, | ||
Model * | model ) |
Completion time cuts for the cumulative constraint. It is a simple relaxation where we replace a cumulative task with demand k and duration d by a no_overlap task with duration d * k / capacity_max.
Definition at line 1470 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreateCumulativeEnergyCutGenerator | ( | SchedulingConstraintHelper * | helper, |
SchedulingDemandHelper * | demands_helper, | ||
const AffineExpression & | capacity, | ||
const std::optional< AffineExpression > & | makespan, | ||
Model * | model ) |
For a given set of intervals and demands, we compute the energy of each task and make sure their sum fits in the span of the intervals * its capacity.
If an interval is optional, it contributes min_demand * min_size * presence_literal amount of total energy.
If an interval is performed, we use the linear energy formulation (if defined, that is if different from a constant -1), or the McCormick relaxation of the product size * demand if not defined.
The maximum energy is capacity * span of intervals at level 0.
We can always skip events.
Definition at line 582 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreateCumulativePrecedenceCutGenerator | ( | SchedulingConstraintHelper * | helper, |
SchedulingDemandHelper * | demands_helper, | ||
const AffineExpression & | capacity, | ||
Model * | model ) |
For a given set of intervals in a cumulative constraint, we detect violated mandatory precedences and create a cut for these.
Definition at line 945 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreateCumulativeTimeTableCutGenerator | ( | SchedulingConstraintHelper * | helper, |
SchedulingDemandHelper * | demands_helper, | ||
const AffineExpression & | capacity, | ||
Model * | model ) |
For a given set of intervals and demands, we first compute the mandatory part of the interval as [start_max , end_min]. We use this to calculate mandatory demands for each start_max time points for eligible intervals. Since the sum of these mandatory demands must be smaller or equal to the capacity, we create a cut representing that.
If an interval is optional, it contributes min_demand * presence_literal amount of demand to the mandatory demands sum. So the final cut is generated as follows: sum(demands of always present intervals)
Iterate through the intervals. If start_max < end_min, the demand is mandatory.
Ignore the interval if the linearized demand fails.
Sort events by time. It is also important that all positive event with the same time as negative events appear after for the correctness of the algo below.
Reset positive event added. We do not want to create cuts for each negative event in sequence.
Create cut.
The i-th event, which is a negative event, follows a positive event. We must ignore it in our cut generation.
The demand_lp was added in case of a positive event. We need to remove it for a negative event.
Definition at line 692 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreateCVRPCutGenerator | ( | int | num_nodes, |
std::vector< int > | tails, | ||
std::vector< int > | heads, | ||
std::vector< Literal > | literals, | ||
std::vector< int64_t > | demands, | ||
int64_t | capacity, | ||
Model * | model ) |
Almost the same as CreateStronglyConnectedGraphCutGenerator() but for each components, computes the demand needed to serves it, and depending on whether it contains the depot (node zero) or not, compute the minimum number of vehicle that needs to cross the component border.
Definition at line 776 of file routing_cuts.cc.
CutGenerator operations_research::sat::CreateFlowCutGenerator | ( | int | num_nodes, |
const std::vector< int > & | tails, | ||
const std::vector< int > & | heads, | ||
const std::vector< AffineExpression > & | arc_capacities, | ||
std::function< void(const std::vector< bool > &in_subset, IntegerValue *min_incoming_flow, IntegerValue *min_outgoing_flow)> | get_flows, | ||
Model * | model ) |
Try to find a subset where the current LP capacity of the outgoing or incoming arc is not enough to satisfy the demands.
We support the special value -1 for tail or head that means that the arc comes from (or is going to) outside the nodes in [0, num_nodes). Such arc must still have a capacity assigned to it.
(user): Support general linear expression for capacities.
(user): Some model applies the same capacity to both an arc and its reverse. Also support this case.
Definition at line 938 of file routing_cuts.cc.
CutGenerator operations_research::sat::CreateLinMaxCutGenerator | ( | IntegerVariable | target, |
const std::vector< LinearExpression > & | exprs, | ||
const std::vector< IntegerVariable > & | z_vars, | ||
Model * | model ) |
Consider the Lin Max constraint with d expressions and n variables in the form: target = max {exprs[k] = Sum (wki * xi + bk)}. k in {1,..,d}. Li = lower bound of xi Ui = upper bound of xi. Let zk be in {0,1} for all k in {1,..,d}. The target = exprs[k] when zk = 1.
The following is a valid linearization for Lin Max. target >= exprs[k], for all k in {1,..,d} target <= Sum (wli * xi) + Sum((Nlk + bk) * zk), for all l in {1,..,d} Where Nlk is a large number defined as: Nlk = Sum (max((wki - wli)*Li, (wki - wli)*Ui)) = Sum (max corner difference for variable i, target expr l, max expr k)
Consider a partition of variables xi into set {1,..,d} as I. i.e. I(i) = j means xi is mapped to jth index. The following inequality is valid and sharp cut for the lin max constraint described above.
target <= Sum(i=1..n)(wI(i)i * xi + Sum(k=1..d)(MPlusCoefficient_ki * zk))
For detailed proof of validity, refer Reference: "Strong mixed-integer programming formulations for trained neural networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).
In the cut generator, we compute the most violated partition I by computing the rhs value (wI(i)i * lp_value(xi) + Sum(k=1..d)(MPlusCoefficient_ki * zk)) for each variable for each partition index. We choose the partition index that gives lowest rhs value for a given variable.
All expressions should only contain positive variables.
CutGenerator operations_research::sat::CreateMaxAffineCutGenerator | ( | LinearExpression | target, |
IntegerVariable | var, | ||
std::vector< std::pair< IntegerValue, IntegerValue > > | affines, | ||
std::string | cut_name, | ||
Model * | model ) |
By definition, the Max of affine functions is convex. The linear polytope is bounded by all affine functions on the bottom, and by a single hyperplane that join the two points at the extreme of the var domain, and their y-values of the max of the affine functions.
CutGenerator operations_research::sat::CreateNoOverlap2dCompletionTimeCutGenerator | ( | SchedulingConstraintHelper * | x_helper, |
SchedulingConstraintHelper * | y_helper, | ||
Model * | model ) |
Completion time cuts for the no_overlap_2d constraint. It actually generates the completion time cumulative cuts in both axis.
Definition at line 562 of file diffn_cuts.cc.
CutGenerator operations_research::sat::CreateNoOverlap2dEnergyCutGenerator | ( | SchedulingConstraintHelper * | x_helper, |
SchedulingConstraintHelper * | y_helper, | ||
SchedulingDemandHelper * | x_demands_helper, | ||
SchedulingDemandHelper * | y_demands_helper, | ||
const std::vector< std::vector< LiteralValueValue > > & | energies, | ||
Model * | model ) |
Energetic cuts for the no_overlap_2d constraint.
For a given set of rectangles, we compute the area of each rectangle and make sure their sum is less than the area of the bounding interval.
If an interval is optional, it contributes min_size_x * min_size_y * presence_literal amount of total area.
If an interval is performed, we use the linear area formulation (if possible), or the McCormick relaxation of the size_x * size_y.
The maximum area is the area of the bounding rectangle of each intervals at level 0.
We do not consider rectangles controlled by 2 different unassigned enforcement literals.
Forward pass. No need to do a backward pass.
Definition at line 309 of file diffn_cuts.cc.
CutGenerator operations_research::sat::CreateNoOverlapCompletionTimeCutGenerator | ( | SchedulingConstraintHelper * | helper, |
Model * | model ) |
For a given set of intervals in a no_overlap constraint, we detect violated area based cuts from Queyranne 93 [see note in the code] and create a cut for these.
Definition at line 1424 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreateNoOverlapEnergyCutGenerator | ( | SchedulingConstraintHelper * | helper, |
const std::optional< AffineExpression > & | makespan, | ||
Model * | model ) |
For a given set of intervals, we first compute the min and max of all intervals. Then we create a cut that indicates that all intervals must fit in that span.
If an interval is optional, it contributes min_size * presence_literal amount of demand to the mandatory demands sum. So the final cut is generated as follows: sum(sizes of always present intervals)
We can always skip events.
Definition at line 643 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreateNoOverlapPrecedenceCutGenerator | ( | SchedulingConstraintHelper * | helper, |
Model * | model ) |
For a given set of intervals in a no_overlap constraint, we detect violated mandatory precedences and create a cut for these.
Definition at line 977 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreatePositiveMultiplicationCutGenerator | ( | AffineExpression | z, |
AffineExpression | x, | ||
AffineExpression | y, | ||
int | linearization_level, | ||
Model * | model ) |
A cut generator for z = x * y (x and y >= 0).
if x or y are fixed, the McCormick equations are exact.
Check for overflow with the product of expression bounds and the product of one expression bound times the constant part of the other expression.
Cut -z + x_coeff * x + y_coeff* y <= rhs
Cut -z + x_coeff * x + y_coeff* y >= rhs
McCormick relaxation of bilinear constraints. These 4 cuts are the exact facets of the x * y polyhedron for a bounded x and y.
Each cut correspond to plane that contains two of the line (x=x_lb), (x=x_ub), (y=y_lb), (y=y_ub). The easiest to understand them is to draw the x*y curves and see the 4 planes that correspond to the convex hull of the graph.
CutGenerator operations_research::sat::CreateSquareCutGenerator | ( | AffineExpression | y, |
AffineExpression | x, | ||
int | linearization_level, | ||
Model * | model ) |
CutGenerator operations_research::sat::CreateStronglyConnectedGraphCutGenerator | ( | int | num_nodes, |
std::vector< int > | tails, | ||
std::vector< int > | heads, | ||
std::vector< Literal > | literals, | ||
Model * | model ) |
We use a basic algorithm to detect components that are not connected to the rest of the graph in the LP solution, and add cuts to force some arcs to enter and leave this component from outside.
Cut generator for the circuit constraint, where in any feasible solution, the arcs that are present (variable at 1) must form a circuit through all the nodes of the graph. Self arc are forbidden in this case.
In more generality, this currently enforce the resulting graph to be strongly connected. Note that we already assume basic constraint to be in the lp, so we do not add any cuts for components of size 1.
Definition at line 762 of file routing_cuts.cc.
std::function< void(Model *)> operations_research::sat::Cumulative | ( | const std::vector< IntervalVariable > & | vars, |
const std::vector< AffineExpression > & | demands, | ||
AffineExpression | capacity, | ||
SchedulingConstraintHelper * | helper = nullptr ) |
Adds a cumulative constraint on the given intervals, the associated demands and the capacity expressions.
Each interval represents a task to be scheduled in time such that the task consumes the resource during the time range [lb, ub) where lb and ub respectively represent the lower and upper bounds of the corresponding interval variable. The amount of resource consumed by the task is the value of its associated demand variable.
The cumulative constraint forces the set of task to be scheduled such that the sum of the demands of all the tasks that overlap any time point cannot exceed the capacity of the resource.
This constraint assumes that an interval can be optional or have a size of zero. The demands and the capacity can be any non-negative number.
Optimization: If one already have an helper constructed from the interval variable, it can be passed as last argument.
Redundant constraints to ensure that the resource capacity is high enough for each task. Also ensure that no task consumes more resource than what is available. This is useful because the subsequent propagators do not filter the capacity variable very well.
If the interval can be of size zero, it currently do not count towards the capacity.
Detect a subset of intervals that needs to be in disjunction and add a Disjunctive() constraint over them.
Liftable? We might be able to add one more interval!
Add a disjunctive constraint on the intervals in in_disjunction. Do not create the cumulative at all when all intervals must be in disjunction.
For each variables that is after a subset of task ends (i.e. like a makespan objective), we detect it and add a special constraint to propagate it.
The CumulativeIsAfterSubsetConstraint() always reset the helper to the forward time direction, so it is important to also precompute the precedence relation using the same direction! This is needed in case the helper has already been used and set in the other direction.
We have var >= end_exp.var + offset, so var >= (end_exp.var + end_exp.cte) + (offset - end_exp.cte) var >= task end + new_offset.
Propagator responsible for applying Timetabling filtering rule. It increases the minimum of the start variables, decrease the maximum of the end variables, and increase the minimum of the capacity variable.
Propagator responsible for applying the Overload Checking filtering rule. It increases the minimum of the capacity variable.
Since we use the potential DFF conflict on demands to apply the heuristic, only do so if any demand is greater than 1.
Propagator responsible for applying the Timetable Edge finding filtering rule. It increases the minimum of the start variables and decreases the maximum of the end variables,
Definition at line 42 of file cumulative.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::CumulativePrecedenceSearchHeuristic | ( | Model * | model | ) |
The algo goes as follow:
We use a similar algo as in BuildProfile() in timetable.cc
Start and height of the currently built profile rectangle.
Remove added task ending there. Set their demand to zero.
Corner case if task is of duration zero.
Add new task starting here. If the task cannot be added we have a candidate for precedence.
We should have everything needed here to add a new precedence.
If packing everything to the left is feasible, continue.
We will use a bunch of heuristic to add a new precedence. All the task in open_tasks cannot share a time point since they exceed the capacity. Moreover if we pack all to the left, they have an intersecting point. So we should be able to make two of them disjoint
Can we add s <= t ? All the considered tasks are intersecting if on the left.
skip if we already have a literal created and assigned to false.
It shouldn't be able to be true here otherwise we will have s and t disjoint.
This should always be true in normal usage after SAT search has fixed all literal, but if it is not, we can just return this decision.
Make sure s could be before t.
It shouldn't be able to fail since s can be before t.
Branch on that precedence.
If no precedence can be created, and all precedence are assigned to false we have a conflict since all these interval must intersect but cannot fit in the capacity!
Definition at line 759 of file integer_search.cc.
std::function< void(Model *)> operations_research::sat::CumulativeTimeDecomposition | ( | const std::vector< IntervalVariable > & | vars, |
const std::vector< AffineExpression > & | demands, | ||
AffineExpression | capacity, | ||
SchedulingConstraintHelper * | helper = nullptr ) |
Adds a simple cumulative constraint. See the comment of Cumulative() above for a definition of the constraint. This is only used for testing.
This constraint assumes that task demands and the resource capacity are fixed to non-negative number.
Compute time range.
Task t consumes the resource at time if consume_condition is true.
Task t consumes the resource at time if it is present.
Task t overlaps time.
this is needed because we currently can't create a boolean variable if the model is unsat.
The profile cannot exceed the capacity at time.
Abort if UNSAT.
Definition at line 283 of file cumulative.cc.
std::function< void(Model *)> operations_research::sat::CumulativeUsingReservoir | ( | const std::vector< IntervalVariable > & | vars, |
const std::vector< AffineExpression > & | demands, | ||
AffineExpression | capacity, | ||
SchedulingConstraintHelper * | helper ) |
Another testing code, same assumptions as the CumulativeTimeDecomposition().
Definition at line 365 of file cumulative.cc.
operations_research::sat::DEFINE_STRONG_INDEX_TYPE | ( | BooleanVariable | ) |
Index of a variable (>= 0).
operations_research::sat::DEFINE_STRONG_INDEX_TYPE | ( | ClauseIndex | ) |
Index of a clause (>= 0).
operations_research::sat::DEFINE_STRONG_INDEX_TYPE | ( | EnforcementId | ) |
operations_research::sat::DEFINE_STRONG_INDEX_TYPE | ( | IntegerVariable | ) |
Index of an IntegerVariable.
Each time we create an IntegerVariable we also create its negation. This is done like that so internally we only stores and deal with lower bound. The upper bound being the lower bound of the negated variable.
operations_research::sat::DEFINE_STRONG_INDEX_TYPE | ( | IntervalVariable | ) |
operations_research::sat::DEFINE_STRONG_INDEX_TYPE | ( | LiteralIndex | ) |
Index of a literal (>= 0), see Literal below.
operations_research::sat::DEFINE_STRONG_INDEX_TYPE | ( | PositiveOnlyIndex | ) |
Special type for storing only one thing for var and NegationOf(var).
operations_research::sat::DEFINE_STRONG_INT64_TYPE | ( | Coefficient | ) |
The type of the integer coefficients in a pseudo-Boolean constraint. This is also used for the current value of a constraint or its bounds.
operations_research::sat::DEFINE_STRONG_INT64_TYPE | ( | IntegerValue | ) |
Value type of an integer variable. An integer variable is always bounded on both sides, and this type is also used to store the bounds [lb, ub] of the range of each integer variable.
void operations_research::sat::DetectAndAddSymmetryToProto | ( | const SatParameters & | params, |
CpModelProto * | proto, | ||
SolverLogger * | logger ) |
Detects symmetries and fill the symmetry field.
Definition at line 742 of file cp_model_symmetries.cc.
bool operations_research::sat::DetectAndExploitSymmetriesInPresolve | ( | PresolveContext * | context | ) |
Basic implementation of some symmetry breaking during presolve.
Currently this just try to fix variables by detecting symmetries between Booleans in bool_and, at_most_one or exactly_one constraints.
We need to make sure the proto is up to date before computing symmetries!
Tricky: the equivalence relation are not part of the proto. We thus add them temporarily to compute the symmetry.
Remove temporary affine relation.
Collect the at most ones.
Note(user): This relies on the fact that the pointers remain stable when we adds new constraints. It should be the case, but it is a bit unsafe. On the other hand it is annoying to deal with both cases below.
We have a few heuristics. The first only look at the global orbits under the symmetry group and try to infer Boolean variable fixing via symmetry breaking. Note that nothing is fixed yet, we will decide later if we fix these Booleans or not.
Get the global orbits and their size.
Log orbit info.
First heuristic based on propagation, see the function comment.
If an at most one intersect with one or more orbit, in each intersection, we can fix all but one variable to zero. For now we only test positive literal, and maximize the number of fixing.
Compute how many variables we can fix with this at most one.
We count all but the first one in each orbit.
Redo a pass to copy the intersection.
We push all but the first one in each orbit.
Sparse clean up.
Orbitope approach.
This is basically the same as the generic approach, but because of the extra structure, computing the orbit of any stabilizer subgroup is easy. We look for orbits intersecting at most one constraints, so we can break symmetry by fixing variables.
HACK for flatzinc wordpress* problem.
If we have a large orbitope, with one objective term by column, we break the symmetry by ordering the objective terms. This usually increase drastically the objective lower bounds we can discover.
Supper simple heuristic to use the orbitope or not.
In an orbitope with an at most one on each row, we can fix the upper right triangle. We could use a formula, but the loop is fast enough.
Moreover, we can add the implication that in the orbit of distinguished_var, either everything is false, or var is at one.
This will always be kept all zero after usage.
Using the orbitope orbits and intersecting at most ones, we will be able in some case to derive a property of the literals of one row of the orbitope. Namely that:
See the comment below for how we can infer this.
Because in the orbitope case, we have a full symmetry group of the columns, we can infer more than just using the orbits under a general permutation group. If an at most one contains two variables from the row, we can infer: 1/ If the two variables appear positively, then there is an at most one on the full row, and we can set n - 1 variables to zero to break the symmetry. 2/ If the two variables appear negatively, then the opposite situation arise and there is at most one zero on the row, we can set n - 1 variables to one. 3/ If two literals of opposite sign appear, then the only possibility for the row are all at one or all at zero, thus we can mark all variables as equivalent.
These property comes from the fact that when we permute a line of the orbitope in any way, then the position than ends up in the at most one must never be both at one.
Note(user): On the miplib, only 1/ and 2/ happens currently. Not sure with LNS though.
An at most one touching two positions in an orbitope row can be extended to include the full row.
Note(user): I am not sure we care about that here. By symmetry, if we have an at most one touching two positions, then we should have others touching all pair of positions. And the at most one expansion would already have extended it. So this is more FYI.
List the row in "at most one" by score. We will be able to fix a "triangle" of literals in order to break some of the symmetry.
Mark all the equivalence or fixed rows.
If we have both property, it means we have
We have [1, 0] or [0, 1].
No solution.
Here we proved that the row is either all ones or all zeros. This was because we had: at_most_one = [x, ~y, ...] orbitope = [x, y, ...] and by symmetry we have at_most_one = [~x, y, ...] This for all pairs of positions in that row.
We use as the score the number of constraint in which variables from this row participate.
Break the symmetry by fixing at each step all but one literal to true or false. Note that each time we do that for a row, we need to exclude the non-fixed column from the rest of the row processing. We thus fix a "triangle" of literals.
This is the same as ordering the columns in some lexicographic order and using the at_most_ones to fix known position. Note that we can still add lexicographic symmetry breaking inequality on the columns as long as we do that in the same order as these fixing.
For correctness of the code below, reduce the orbitope.
Remove the first num_processed_rows.
For each of them remove the first num_processed_rows entries.
If we are left with a set of variable than can all be permuted, lets break the symmetry by ordering them.
Add orbitope[0][i] >= orbitope[0][i+1].
Definition at line 900 of file cp_model_symmetries.cc.
std::vector< double > operations_research::sat::DetectImpliedIntegers | ( | MPModelProto * | mp_model, |
SolverLogger * | logger ) |
This will mark implied integer as such. Note that it can also discover variable of the form coeff * Integer + offset, and will change the model so that these are marked as integer. It is why we return both a scaling and an offset to transform the solution back to its original domain.
We will process all equality constraints with exactly one non-integer.
Scale the variable right away and mark it as implied integer.
Update the queue of constraints with a single non-integer.
The non integer variable was already made integer by one other constraint.
Ignore non-equality here.
This will be set to the unique non-integer term of this constraint.
We are looking for a "multiplier" so that the unique non-integer term in this constraint (i.e. var * var_coeff) times this multiplier is an integer.
If this is set to zero or becomes too large, we fail to detect a new implied integer and ignore this constraint.
This actually compute the smallest multiplier to make all other terms in the constraint integer.
These "rhs" fail could be handled by shifting the variable.
We want to multiply the variable so that it is integer. We know that coeff * multiplier is an integer, so we just multiply by that.
But if a variable appear in more than one equality, we want to find the smallest integrality factor! See diameterc-msts-v40a100d5i.mps for an instance of this.
Ignore non-equality here.
Process continuous variables that only appear as the unique non integer in a set of non-equality constraints.
This should be presolved and not happen.
The situation is a bit tricky here, we have a bunch of coeffs c_i, and we know that X * c_i can take integer value without changing the constraint i meaning.
For now we take the min, and scale only if all c_i / min are integer.
Tricky, we also need the bound of the scaled variable to be integer.
Definition at line 482 of file lp_utils.cc.
std::optional< int > operations_research::sat::DetectMakespan | ( | const std::vector< IntervalVariable > & | intervals, |
const std::vector< AffineExpression > & | demands, | ||
const AffineExpression & | capacity, | ||
Model * | model ) |
Scan the intervals of a cumulative/no_overlap constraint, and its capacity (1 for the no_overlap). It returns the index of the makespan interval if found, or std::nullopt otherwise.
Currently, this requires the capacity to be fixed in order to scan for a makespan interval.
The makespan interval has the following property:
These property ensures that all other intervals ends before the start of the makespan interval.
Detect the horizon (max of all end max of all intervals).
Definition at line 630 of file linear_relaxation.cc.
void operations_research::sat::DetectOptionalVariables | ( | const CpModelProto & | model_proto, |
Model * | m ) |
Automatically detect optional variables.
The variables from the objective cannot be marked as optional!
Compute for each variables the intersection of the enforcement literals of the constraints in which they appear.
Take the intersection.
Auto-detect optional variables.
Definition at line 908 of file cp_model_loader.cc.
void operations_research::sat::DeterministicLoop | ( | std::vector< std::unique_ptr< SubSolver > > & | subsolvers, |
int | num_threads, | ||
int | batch_size, | ||
int | max_num_batches = 0 ) |
Similar to NonDeterministicLoop() except this should result in a deterministic solver provided that all SubSolver respect the Synchronize() contract.
Executes the following loop: 1/ Synchronize all in given order. 2/ generate and schedule up to batch_size tasks using an heuristic to select which one to run. 3/ wait for all task to finish. 4/ repeat until no task can be generated in step 2.
If max_num_batches is > 0, stop after that many batches.
We abort the loop after the last synchronize to properly reports final status in case max_num_batches is used.
We first generate all task to run in this batch.
Schedule each task.
Wait for all tasks of this batch to be done before scheduling another batch.
Update times.
Definition at line 120 of file subsolver.cc.
LiteralIndex operations_research::sat::DifferAtGivenLiteral | ( | const std::vector< Literal > & | a, |
const std::vector< Literal > & | b, | ||
Literal | l ) |
Visible for testing. Returns kNoLiteralIndex except if:
A literal of a is not in b, it must be l.
A literal of b is not in a, save it. We abort if this happen twice.
Check the corner case of the difference at the end.
Definition at line 993 of file simplification.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::DisjunctivePrecedenceSearchHeuristic | ( | Model * | model | ) |
The algo goes as follow:
Compared to SchedulingSearchHeuristic() this one take decision on precedences between tasks. Lazily creating a precedence Boolean for the task in disjunction.
Swap (a,b) if they have the same start_min.
Corner case in case b can fit before a (size zero)
Definition at line 690 of file integer_search.cc.
void operations_research::sat::DivideByGCD | ( | LinearConstraint * | constraint | ) |
Computes the GCD of the constraint coefficient, and divide them by it. This also tighten the constraint bounds assumming all the variables are integer.
Definition at line 261 of file linear_constraint.cc.
void operations_research::sat::DivideLinearExpression | ( | int64_t | divisor, |
LinearExpressionProto * | expr ) |
Divide the expression in place by 'divisor'. It will DCHECK that 'divisor' divides all constants.
Definition at line 59 of file cp_model_utils.cc.
|
inline |
Adds the constraint: num / denom = div. (denom > 0).
Definition at line 809 of file integer_expr.h.
bool operations_research::sat::DomainInProtoContains | ( | const ProtoWithDomain & | proto, |
int64_t | value ) |
Returns true if a proto.domain() contain the given value. The domain is expected to be encoded as a sorted disjoint interval list.
Definition at line 113 of file cp_model_utils.h.
|
inline |
enforcement_literals => clause.
Definition at line 973 of file sat_solver.h.
|
inline |
Definition at line 51 of file cp_model_utils.h.
|
inline |
a == b.
Definition at line 637 of file precedences.h.
|
inline |
a == b.
Definition at line 949 of file sat_solver.h.
|
inline |
a + offset == b.
Definition at line 646 of file precedences.h.
|
inline |
Definition at line 905 of file sat_solver.h.
std::function< void(Model *)> operations_research::sat::ExactlyOnePerRowAndPerColumn | ( | const std::vector< std::vector< Literal > > & | graph | ) |
Definition at line 628 of file circuit.cc.
|
inline |
This can be used to enumerate all the solutions. After each SAT call to Solve(), calling this will reset the solver and exclude the current solution so that the next call to Solve() will give a new solution or UNSAT is there is no more new solutions.
Definition at line 1038 of file sat_solver.h.
void operations_research::sat::ExpandCpModel | ( | PresolveContext * | context | ) |
Expands a given CpModelProto by rewriting complex constraints into simpler constraints. This is different from PresolveCpModel() as there are no reduction or simplification of the model. Furthermore, this expansion is mandatory.
None of the function here need to be run twice. This is because we never create constraint that need to be expanded during presolve.
Make sure all domains are initialized.
Clear the precedence cache.
First pass: we look at constraints that may fully encode variables.
If we only do expansion, we do that as part of the main loop. This way we don't need to call FinalExpansionForLinearConstraint().
Update variable-constraint graph.
Early exit if the model is unsat.
Second pass. We may decide to expand constraints if all their variables are fully encoded.
Cache for variable scanning.
Update variable-constraint graph.
Early exit if the model is unsat.
The precedence cache can become invalid during presolve as it does not handle variable substitution. It is safer just to clear it at the end of the expansion phase.
Make sure the context is consistent.
Update any changed domain from the context.
Definition at line 2483 of file cp_model_expand.cc.
bool operations_research::sat::ExploitDominanceRelations | ( | const VarDomination & | var_domination, |
PresolveContext * | context ) |
Once detected, exploit the dominance relations that appear in the same constraint. This does a full scan of the model.
Return false if the problem is infeasible.
Abort early if there is nothing to do.
Strenghtening via domination. When a variable is dominated by a bunch of other, either we can do (var–, dom++) or if we can't (i.e all dominated variable at their upper bound) then maybe all constraint are satisfied if var is high enough and we can also decrease it.
Temporary data that we fill/clear for each linear constraint.
Temporary data used for boolean constraints.
If (a–, b–) is valid, we can always set a to false.
If (b++, a++) is valid, then we can always set b to true.
Precompute.
Returns the change magnitude in min-activity (resp. max-activity) if all the given variables are fixed to their upper bound.
Tricky: For now we skip complex domain as we are not sure they can be moved correctly.
Look for dominated var.
For strenghtening using domination, just consider >= constraint.
Always transform to coeff_magnitude * current_ref + ... >=
When all dominated var are at their upper bound, we miss 'slack' to make the constraint trivially satisfiable.
Any increase such that coeff * delta >= slack make the constraint trivial.
Note(user): It look like even if any of the upper bound of the dominating var decrease, this should still be valid. Here we only decrease such a bound due to a dominance relation, so the slack when all dominating variable are at their bound should not really decrease.
Compute the delta in min-activity if all dominating var moves to their other bound.
We need to update the precomputed quantities.
Tricky: If there are holes, we can't just reduce the domain to new_ub if it is not a valid value, so we need to compute the Min() of the intersection.
We need to update the precomputed quantities.
Restore.
For any dominance relation still left (i.e. between non-fixed vars), if the variable are Boolean and X is dominated by Y, we can add (X = 1) => (Y = 1). But, as soon as we do that, we break some symmetry and cannot add any incompatible relations.
EX: It is possible that X dominate Y and Y dominate X if they are both appearing in exactly the same constraint with the same coefficient.
Increase the count for variable in the objective to account for the kObjectiveConstraint in their VarToConstraints() list.
We need to account for domain with hole, hence the ValueAtOrAfter().
We have a candidate, however, we need to make sure the dominating variable upper bound didn't change.
The rest of the loop only care about Booleans. And if this was boolean, we would have fixed it. If it became Boolean, we wait for the next call.
dom– or var++ are now forbidden.
Definition at line 1418 of file var_domination.cc.
bool operations_research::sat::ExpressionContainsSingleRef | ( | const LinearExpressionProto & | expr | ) |
Returns true if a linear expression can be reduced to a single ref.
Definition at line 569 of file cp_model_utils.cc.
bool operations_research::sat::ExpressionIsAffine | ( | const LinearExpressionProto & | expr | ) |
Checks if the expression is affine or constant.
Definition at line 574 of file cp_model_utils.cc.
bool operations_research::sat::ExpressionsContainsOnlyOneVar | ( | const ExpressionList & | exprs | ) |
Returns true if there exactly one variable appearing in all the expressions.
Definition at line 229 of file cp_model_utils.h.
|
inline |
void operations_research::sat::ExtractAllSubsetsFromForest | ( | const std::vector< int > & | parent, |
std::vector< int > * | subset_data, | ||
std::vector< absl::Span< const int > > * | subsets, | ||
int | node_limit = std::numeric_limits< int >::max() ) |
Given a set of rooted tree on n nodes represented by the parent vector, returns the n sets of nodes corresponding to all the possible subtree. Note that the output memory is just n as all subset will point into the same vector.
This assumes no cycles, otherwise it will not crash but the result will not be correct.
In the TSP context, if the tree is a Gomory-Hu cut tree, this will returns a set of "min-cut" that contains a min-cut for all node pairs.
To not reallocate memory since we need the span to point inside this vector, we resize subset_data right away.
Starts by creating the corresponding graph and find the root.
Perform a dfs on the rooted tree. The subset_data will just be the node in post-order.
The node was already explored, output its subtree and pop it.
Explore.
Definition at line 464 of file routing_cuts.cc.
void operations_research::sat::ExtractAssignment | ( | const LinearBooleanProblem & | problem, |
const SatSolver & | solver, | ||
std::vector< bool > * | assignment ) |
Copies the assignment from the solver into the given Boolean vector. Note that variables with a greater index that the given num_variables are ignored.
Definition at line 63 of file boolean_problem.cc.
std::vector< Literal > operations_research::sat::ExtractAssumptions | ( | Coefficient | stratified_lower_bound, |
const std::vector< EncodingNode * > & | nodes, | ||
SatSolver * | solver ) |
Extract the assumptions from the nodes.
Definition at line 547 of file encoding.cc.
void operations_research::sat::ExtractElementEncoding | ( | const CpModelProto & | model_proto, |
Model * | m ) |
Extract element encodings from exactly_one constraints and lit => var == value constraints. This function must be called after ExtractEncoding() has been called.
Scan all exactly_one constraints and look for literal => var == value to detect element encodings.
Project the implied values onto each integer variable.
Used for logging only.
Search for variable fully covered by the literals of the exactly_one.
We use the order of literals of the exactly_one.
Encode the holes propagation (but we don't create extra literal if they are not already there). If there are non-encoded values we also add the direct min/max propagation.
Lets not create var >= value or var <= value if they do not exist.
We do not create an extra literal if it doesn't exist.
If all literal supporting a value are false, then the value must be false. Note that such a clause is only useful if there are more than one literal supporting the value, otherwise we should already have detected the equivalence.
And the <= side.
Definition at line 681 of file cp_model_loader.cc.
void operations_research::sat::ExtractEncoding | ( | const CpModelProto & | model_proto, |
Model * | m ) |
The logic assumes that the linear constraints have been presolved, so that equality with a domain bound have been converted to <= or >= and so that we never have any trivial inequalities.
Extract the encodings (IntegerVariable <-> Booleans) present in the model. This effectively load some linear constraints of size 1 that will be marked as already loaded.
Detection of literal equivalent to (i_var == value). We collect all the half-reified constraint lit => equality or lit => inequality for a given variable, and we will later sort them to detect equivalence.
Detection of literal equivalent to (i_var >= bound). We also collect all the half-refied part and we will sort the vector for detection of the equivalence.
Loop over all constraints and fill var_to_equalities and inequalities.
ct is a linear constraint with one term and one enforcement literal.
Detect enforcement_literal => (var >= value or var <= value).
Detect implied bounds. The test is less strict than the above test.
Detect enforcement_literal => (var == value or var != value).
Detect Literal <=> X >= value
Encode the half-inequalities.
Detect Literal <=> X == value and associate them in the IntegerEncoder.
Encode the half-equalities.
If we have just an half-equality, lets not create the <=> literal but just add two implications. If we don't create hole, we don't really need the reverse literal. This way it is also possible for the ExtractElementEncoding() to detect later that actually this literal is <=> to var == value, and this way we create one less Boolean for the same result.
Update stats.
Definition at line 396 of file cp_model_loader.cc.
void operations_research::sat::ExtractSubproblem | ( | const LinearBooleanProblem & | problem, |
const std::vector< int > & | constraint_indices, | ||
LinearBooleanProblem * | subproblem ) |
Constructs a sub-problem formed by the constraints with given indices.
Definition at line 499 of file boolean_problem.cc.
std::string operations_research::sat::ExtractSubSolverName | ( | const std::string & | improvement_info | ) |
We assume the subsolver name is always first.
Definition at line 776 of file synchronization.cc.
bool operations_research::sat::FailedLiteralProbingRound | ( | ProbingOptions | options, |
Model * | model ) |
Similar to ProbeBooleanVariables() but different :-)
First, this do not consider integer variable. It doesn't do any disjunctive reasoning (i.e. changing the domain of an integer variable by intersecting it with the union of what happen when x is fixed and not(x) is fixed).
However this should be more efficient and just work better for pure Boolean problems. On integer problems, we might also want to run this one first, and then do just one quick pass of ProbeBooleanVariables().
This can fix a lot of literals via failed literal detection, that is when we detect that x => not(x) via propagation after taking x as a decision. It also use the strongly connected component algorithm to detect equivalent literals.
It will add any detected binary clause (via hyper binary resolution) to the implication graph. See the option comments for more details.
Reset the solver in case it was already used.
When called from Inprocessing, the implication graph should already be a DAG, so these two calls should return right away. But we do need them to get the topological order if this is used in isolation.
This is only needed when options.use_queue is true.
This is only needed when options use_queue is false;
We delay fixing of already assigned literal once we go back to level zero.
Depending on the options. we do not use the same order. With tree look, it is better to start with "leaf" first since we try to reuse propagation as much as possible. This is also interesting to do when extracting binary clauses since we will need to propagate everyone anyway, and this should result in less clauses that can be removed later by transitive reduction.
However, without tree-look and without the need to extract all binary clauses, it is better to just probe the root of the binary implication graph. This is exactly what happen when we probe using the topological order.
We only use this for the queue version.
We only enqueue literal at level zero if we don't use "tree look".
Probe a literal that implies previous decision.
This is a backtrack marker, go back one level.
Fix any delayed fixed literal.
Probe an unexplored node.
The pass is finished.
Probe a literal that implies previous decision.
candidate => previous => not(candidate), so we can fix it.
This shouldn't happen if extract_binary_clauses is false. We have an equivalence.
Sync the queue with the new level.
Fix next_decision
to false
if not already done.
Even if we fixed something at level zero, next_decision might not be fixed! But we can fix it. It can happen because when we propagate with clauses, we might have a => b
but not not(b) => not(a)
. Like a => b
and clause (not(a), not(b), c)
, propagating a
will set c
, but propagating not(c)
will not do anything.
We "delay" the fixing if we are not at level zero so that we can still reuse the current propagation work via tree look.
Inspect the newly propagated literals. Depending on the options, try to extract binary clauses via hyper binary resolution and/or mark the literals on the trail so that they do not need to be probed later.
If we can extract a binary clause that subsume the reason clause, we do add the binary and remove the subsumed clause.
We need to change the reason now that the clause is cleared.
Anything not propagated by the BinaryImplicationGraph is a "new" binary clause. This is because the BinaryImplicationGraph has the highest priority of all propagators.
Note(user): This is not 100% true, since when we launch the clause propagation for one literal we do finish it before calling again the binary propagation.
If we don't extract binary, we don't need to explore any of these literal until more variables are fixed.
Inspect the watcher list for last_decision, If we have a blocking literal at true (implied by last decision), then we have subsumptions.
The intuition behind this is that if a binary clause (a,b) subsume a clause, and we watch a.Negated() for this clause with a blocking literal b, then this watch entry will never change because we always propagate binary clauses first and the blocking literal will always be true. So after many propagations, we hope to have such configuration which is quite cheap to test here.
Tricky: If we have many "decision" and we do not extract the binary clause, then the fact that last_decision => literal might not be currently encoded in the problem clause, so if we use that relation to subsume, we should make sure it is added.
Add the binary clause if needed. Note that we change the reason to a binary one so that we never add the same clause twice.
Tricky: while last_decision would be a valid reason, we need a reason that was assigned before this literal, so we use the decision at the level where this literal was assigned which is an even better reason. Maybe it is just better to change all the reason above to a binary one so we don't have an issue here.
If the variable was true at level zero, there is no point adding the clause.
Display stats.
Definition at line 498 of file probing.cc.
void operations_research::sat::FillDomainInProto | ( | const Domain & | domain, |
ProtoWithDomain * | proto ) |
Serializes a Domain into the domain field of a proto.
Definition at line 122 of file cp_model_utils.h.
void operations_research::sat::FillSolveStatsInResponse | ( | Model * | model, |
CpSolverResponse * | response ) |
Get the solve statistics from the associated model classes and fills the response with them.
Definition at line 145 of file synchronization.cc.
void operations_research::sat::FillTightenedDomainInResponse | ( | const CpModelProto & | original_model, |
const CpModelProto & | mapping_proto, | ||
const std::vector< int > & | postsolve_mapping, | ||
const std::vector< Domain > & | search_domains, | ||
CpSolverResponse * | response, | ||
SolverLogger * | logger ) |
Try to postsolve with a "best-effort" the reduced domain from the presolved model to the user given model. See the documentation of the CpSolverResponse tightened_variables field for more information on the caveats.
The [0, num_vars) part will contain the tightened domains.
Start with the domain from the mapping proto. Note that by construction this should be tighter than the original variable domains.
The first test is for the corner case of presolve closing the problem, in which case there is no more info to process.
Currently no mapping should mean all variables are in common. This happen when presolve is disabled, but we might still have more variables due to expansion for instance.
There is also the corner case of presolve closing the problem,
This is the normal presolve case. Intersect the domain of the variables in common.
Look for affine relation, and do more intersection.
We can reduce the domain of v1 by using the affine relation and the domain of v2. We have c1 * v2 + c2 * v2 = offset;
Copy the names and replace domains.
Some stats.
Definition at line 410 of file cp_model_postsolve.cc.
void operations_research::sat::FilterAssignedLiteral | ( | const VariablesAssignment & | assignment, |
std::vector< Literal > * | core ) |
A core cannot be all true.
Remove fixed literals from the core.
Definition at line 201 of file optimization.cc.
absl::Span< int > operations_research::sat::FilterBoxesAndRandomize | ( | absl::Span< const Rectangle > | cached_rectangles, |
absl::Span< int > | boxes, | ||
IntegerValue | threshold_x, | ||
IntegerValue | threshold_y, | ||
absl::BitGenRef | random ) |
Removes boxes with a size above the thresholds. Also randomize the order. Because we rely on various heuristic, this allow to change the order from one call to the next.
Definition at line 378 of file diffn_util.cc.
absl::Span< int > operations_research::sat::FilterBoxesThatAreTooLarge | ( | absl::Span< const Rectangle > | cached_rectangles, |
absl::Span< const IntegerValue > | energies, | ||
absl::Span< int > | boxes ) |
Given the total energy of all rectangles (sum of energies[box]) we know that any box with an area greater than that cannot participate in any "bounding box" conflict. As we remove this box, the total energy decrease, so we might remove more. This works in O(n log n).
Sort the boxes by increasing area.
Remove all the large boxes until we have one with area smaller than the energy of the boxes below.
Definition at line 394 of file diffn_util.cc.
void operations_research::sat::FinalExpansionForLinearConstraint | ( | PresolveContext * | context | ) |
Linear constraint with a complex rhs need to be expanded at the end of the presolve. We do that at the end, because the presolve is allowed to simplify such constraints by updating the rhs. Also the extra variable we create are only linked by a few constraints to the rest of the model and should not be presolvable.
Definition at line 2631 of file cp_model_expand.cc.
double operations_research::sat::FindBestScalingAndComputeErrors | ( | const std::vector< double > & | coefficients, |
absl::Span< const double > | lower_bounds, | ||
absl::Span< const double > | upper_bounds, | ||
int64_t | max_absolute_activity, | ||
double | wanted_absolute_activity_precision, | ||
double * | relative_coeff_error, | ||
double * | scaled_sum_error ) |
Given a linear expression Sum_i c_i * X_i with each X_i in [lb_i, ub_i], this returns a scaling factor f such that 1/ the rounded expression cannot overflow given the domains of the X_i: Sum |std::round(f * c_i) * X_i| <= max_absolute_activity 2/ the error is bounded: | Sum_i (std::round(f * c_i) - f * c_i) | < f * wanted_absolute_activity_precision
This also fills the exact errors made by using the returned scaling factor. The heuristics try to minimize the magnitude of the scaled expression while satisfying the requested precision.
Returns 0.0 if no scaling factor can be found under the condition 1/. Note that we try really hard to satisfy 2/ but we still return our best shot even when 2/ is not satisfied. One can check this by comparing the returned scaled_sum_error / f with wanted_absolute_activity_precision.
(user): unit test this and move to fp_utils.
(user): Ideally the lower/upper should be int64_t so that we can have an exact definition for the max_absolute_activity allowed.
Starts by computing the highest possible factor.
Returns the smallest factor of the form 2^i that gives us a relative sum error of wanted_absolute_activity_precision and still make sure we will have no integer overflow.
Important: the loop is written in such a way that ComputeScalingErrors() is called on the last factor.
This could happen if we always have enough precision.
Because we deal with an approximate input, scaling with a power of 2 might not be the best choice. It is also possible user used rational coeff and then converted them to double (1/2, 1/3, 4/5, etc...). This scaling will recover such rational input and might result in a smaller overall coefficient which is good.
Definition at line 872 of file lp_utils.cc.
void operations_research::sat::FindCpModelSymmetries | ( | const SatParameters & | params, |
const CpModelProto & | problem, | ||
std::vector< std::unique_ptr< SparsePermutation > > * | generators, | ||
double | deterministic_limit, | ||
SolverLogger * | logger ) |
Returns a list of generators of the symmetry group of the given problem. Each generator is a permutation of the integer range [0, n) where n is the number of variables of the problem. They are permutations of the (index representation of the) problem variables.
Remove from the permutations the part not concerning the variables.
Because variable nodes are in a separate equivalence class than any other node, a cycle can either contain only variable nodes or none, so we just need to check one element of the cycle.
Verify that the cycle's entire support does not touch any variable.
Definition at line 644 of file cp_model_symmetries.cc.
std::vector< std::pair< int, int > > operations_research::sat::FindDuplicateConstraints | ( | const CpModelProto & | model_proto, |
bool | ignore_enforcement = false ) |
Returns the index of duplicate constraints in the given proto in the first element of each pair. The second element of each pair is the "representative" that is the first constraint in the proto in a set of duplicate constraints.
Empty constraints are ignored. We also do a bit more:
If ignore_enforcement is true, we ignore enforcement literal, but do not do the linear domain or objective special cases. This allow to cover some other cases like:
Visible here for testing. This is meant to be called at the end of the presolve where constraints have been canonicalized.
We use a map hash that uses the underlying constraint to compute the hash and the equality for the indices.
Create a special representative for the linear objective.
Nothing we will presolve in this case.
Already present!
Definition at line 13312 of file cp_model_presolve.cc.
std::vector< Rectangle > operations_research::sat::FindEmptySpaces | ( | const Rectangle & | bounding_box, |
std::vector< Rectangle > | ocupied_rectangles ) |
Given a bounding box and a list of rectangles inside that bounding box, returns a list of rectangles partitioning the empty area inside the bounding box.
Sorting is not necessary for correctness but makes it faster.
Definition at line 1568 of file diffn_util.cc.
void operations_research::sat::FindLinearBooleanProblemSymmetries | ( | const LinearBooleanProblem & | problem, |
std::vector< std::unique_ptr< SparsePermutation > > * | generators ) |
Returns a list of generators of the symmetry group of the given problem. Each generator is a permutation of the integer range [0, 2n) where n is the number of variables of the problem. They are permutations of the (index representation of the) problem literals.
Remap the graph nodes to sort them by equivalence classes.
Remove from the permutations the part not concerning the literals.
Verify that the cycle's entire support does not touch any variable.
Definition at line 683 of file boolean_problem.cc.
int64_t operations_research::sat::FindRationalFactor | ( | double | x, |
int64_t | limit, | ||
double | tolerance ) |
This uses the best rational approximation of x via continuous fractions. It is probably not the best implementation, but according to the unit test, it seems to do the job.
Returns the smallest factor f such that f * abs(x) is integer modulo the given tolerance relative to f (we use f * tolerance). It is only looking for f smaller than the given limit. Returns zero if no such factor exist below the limit.
The complexity is a lot less than O(limit), but it is possible that we might miss the smallest such factor if the tolerance used is too low. This is because we only rely on the best rational approximations of x with increasing denominator.
Definition at line 133 of file lp_utils.cc.
FindRectanglesResult operations_research::sat::FindRectanglesWithEnergyConflictMC | ( | const std::vector< RectangleInRange > & | intervals, |
absl::BitGenRef | random, | ||
double | temperature, | ||
double | candidate_energy_usage_factor ) |
Pick a change with a probability proportional to exp(- delta_E / Temp)
Definition at line 1483 of file diffn_util.cc.
bool operations_research::sat::FindSingleLinearDifference | ( | const LinearConstraintProto & | lin1, |
const LinearConstraintProto & | lin2, | ||
int * | var1, | ||
int64_t * | coeff1, | ||
int * | var2, | ||
int64_t * | coeff2 ) |
Same as LinearsDifferAtOneTerm() below but also fills the differing terms.
Same term, continue.
We have a diff. term i not in lin2.
term j not in lin1.
Coeff differ. Returns if we had a diff previously.
Definition at line 688 of file presolve_util.cc.
uint64_t operations_research::sat::FingerprintExpression | ( | const LinearExpressionProto & | lin, |
uint64_t | seed ) |
Returns a stable fingerprint of a linear expression.
Definition at line 636 of file cp_model_utils.cc.
uint64_t operations_research::sat::FingerprintModel | ( | const CpModelProto & | model, |
uint64_t | seed ) |
Returns a stable fingerprint of a model.
Fingerprint the objective.
Definition at line 647 of file cp_model_utils.cc.
|
inline |
Definition at line 248 of file cp_model_utils.h.
|
inline |
Definition at line 256 of file cp_model_utils.h.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::FirstUnassignedVarAtItsMinHeuristic | ( | const std::vector< IntegerVariable > & | vars, |
Model * | model ) |
Decision heuristic for SolveIntegerProblemWithLazyEncoding(). Returns a function that will return the literal corresponding to the fact that the first currently non-fixed variable value is <= its min. The function will return kNoLiteralIndex if all the given variables are fixed.
Definition at line 169 of file integer_search.cc.
|
inline |
Adds the constraint: a / b = c where b is a constant.
Definition at line 828 of file integer_expr.h.
|
inline |
Adds the constraint: a % b = c where b is a constant.
Definition at line 842 of file integer_expr.h.
|
inline |
Weighted sum == constant.
Definition at line 458 of file integer_expr.h.
operations_research::sat::floor | ( | |P|/ | 2 | ) |
Reduces v modulo the elements_to_consider first elements of the (normal form) basis. The leading coeff of a basis element is the last one. In other terms, basis has the form:
IntType operations_research::sat::FloorOfRatio | ( | IntType | numerator, |
IntType | denominator ) |
|
inline |
int64_t operations_research::sat::FloorSquareRoot | ( | int64_t | a | ) |
std::function< BooleanOrIntegerLiteral()> operations_research::sat::FollowHint | ( | const std::vector< BooleanOrIntegerVariable > & | vars, |
const std::vector< IntegerValue > & | values, | ||
Model * | model ) |
This is not ideal as we reserve an int for the full duration of the model even if we use this FollowHint() function just for a while. But it is an easy solution to not have reference to deleted memory in the RevIntRepository(). Note that once we backtrack, these reference will disappear.
If we retake a decision at this level, we will restart from i.
If we retake a decision at this level, we will restart from i.
If the value is outside the current possible domain, we skip it.
Definition at line 1110 of file integer_search.cc.
std::string operations_research::sat::FormatCounter | ( | int64_t | num | ) |
|
inline |
std::string operations_research::sat::FormatTable | ( | std::vector< std::vector< std::string > > & | table, |
int | spacing = 2 ) |
EncodingNode operations_research::sat::FullMerge | ( | Coefficient | upper_bound, |
EncodingNode * | a, | ||
EncodingNode * | b, | ||
SatSolver * | solver ) |
Merges the two given EncodingNode by creating a new node that corresponds to the sum of the two given ones. The given upper_bound is interpreted as a bound on this sum, and allows creating fewer binary variables.
Fix the variable to false because of the given upper_bound.
Fix the variable to false because of the given upper_bound.
if x <= ia and y <= ib, then x + y <= ia + ib.
if x > ia and y > ib, then x + y > ia + ib + 1.
Definition at line 388 of file encoding.cc.
std::vector< std::vector< absl::InlinedVector< int64_t, 2 > > > operations_research::sat::FullyCompressTuples | ( | absl::Span< const int64_t > | domain_sizes, |
std::vector< std::vector< int64_t > > * | tuples ) |
Similar to CompressTuples() but produces a final table where each cell is a set of value. This should result in a table that can still be encoded efficiently in SAT but with less tuples and thus less extra Booleans. Note that if a set of value is empty, it is interpreted at "any" so we can gain some space.
The passed tuples vector is used as temporary memory and is detroyed. We interpret kTableAnyValue as an "any" tuple.
|
inline |
Calling model.Add(FullyEncodeVariable(var)) will create one literal per value in the domain of var (if not already done), and wire everything correctly. This also returns the full encoding, see the FullDomainEncoding() method of the IntegerEncoder class.
void operations_research::sat::GenerateCompletionTimeCutsWithEnergy | ( | absl::string_view | cut_name, |
std::vector< CtEvent > | events, | ||
IntegerValue | capacity_max, | ||
bool | skip_low_sizes, | ||
Model * | model, | ||
LinearConstraintManager * | manager ) |
We generate the cut from the Smith's rule from: M. Queyranne, Structure of a simple scheduling polyhedron, Mathematical Programming 58 (1993), 263–285
The original cut is: sum(end_min_i * duration_min_i) >= (sum(duration_min_i^2) + sum(duration_min_i)^2) / 2 We strengthen this cuts by noticing that if all tasks starts after S, then replacing end_min_i by (end_min_i - S) is still valid.
A second difference is that we look at a set of intervals starting after a given start_min, sorted by relative (end_lp - start_min).
Sort by start min to bucketize by start_min.
Skip to the next start_min value.
We look at event that start before sequence_start_min, but are forced to cross this time point. In that case, we replace this event by a truncated event starting at sequence_start_min. To do this, we reduce the size_min, align the start_min with the sequence_start_min, and scale the energy down accordingly.
Build the vector of energies as the vector of sizes.
This is competing with the brute force approach. Skip cases covered by the other code.
We compute the cuts like if it was a disjunctive cut with all the duration actually equal to energy / capacity. But to keep the computation in the integer domain, we multiply by capacity everywhere instead.
We compute the efficacity in the unscaled domain where the l2 norm of the cuts is exactly the sqrt of the sum of squared duration.
Definition at line 1271 of file scheduling_cuts.cc.
void operations_research::sat::GenerateCumulativeEnergeticCuts | ( | const std::string & | cut_name, |
const util_intops::StrongVector< IntegerVariable, double > & | lp_values, | ||
std::vector< EnergyEvent > | events, | ||
const AffineExpression & | capacity, | ||
TimeLimit * | time_limit, | ||
Model * | model, | ||
LinearConstraintManager * | manager ) |
Currently, we look at all the possible time windows, and will push all cuts in the TopNCuts object. From our observations, this generator creates only a few cuts for a given run.
The complexity of this loop is n^3. if we follow the latest research, we could implement this in n log^2(n). Still, this is not visible in the profile as we only this method at the root node,
Compute relevant time points.
Checks the time limit if the problem is too big.
After max_end_min, all tasks can fit before window_start.
Compute the max energy available for the tasks.
Add all contributions.
Definition at line 481 of file scheduling_cuts.cc.
void operations_research::sat::GenerateCumulativeEnergeticCutsWithMakespanAndFixedCapacity | ( | absl::string_view | cut_name, |
const util_intops::StrongVector< IntegerVariable, double > & | lp_values, | ||
std::vector< EnergyEvent > | events, | ||
IntegerValue | capacity, | ||
AffineExpression | makespan, | ||
TimeLimit * | time_limit, | ||
Model * | model, | ||
LinearConstraintManager * | manager ) |
This cumulative energetic cut generator will split the cumulative span in 2 regions.
In the region before the min of the makespan, we will compute a more precise reachable profile and have a better estimation of the energy available between two time point. the improvement can come from two sources:
In the region after the min of the makespan, we will use fixed_capacity * (makespan - makespan_min) as the available energy.
Checks the precondition of the code.
Currently, we look at all the possible time windows, and will push all cuts in the TopNCuts object. From our observations, this generator creates only a few cuts for a given run.
The complexity of this loop is n^3. if we follow the latest research, we could implement this in n log^2(n). Still, this is not visible in the profile as we only this method at the root node,
Compute relevant time points.
In practice, it stops the DP as the upper bound is reached.
Checks the time limit if the problem is too big.
After max_end_min, all tasks can fit before window_start.
Update states for the name of the generated cut.
We prefer using the makespan as the cut will tighten itself when the objective value is improved.
We reuse the min cut violation to allow some slack in the comparison between the two computed energy values.
Add contributions from all events.
Definition at line 274 of file scheduling_cuts.cc.
void operations_research::sat::GenerateCutsBetweenPairOfNonOverlappingTasks | ( | absl::string_view | cut_name, |
const util_intops::StrongVector< IntegerVariable, double > & | lp_values, | ||
std::vector< CachedIntervalData > | events, | ||
IntegerValue | capacity_max, | ||
Model * | model, | ||
LinearConstraintManager * | manager ) |
Balas disjunctive cuts on 2 tasks a and b: start_1 * (duration_1 + start_min_1 - start_min_2) + start_2 * (duration_2 + start_min_2 - start_min_1) >= duration_1 * duration_2 + start_min_1 * duration_2 + start_min_2 * duration_1 From: David L. Applegate, William J. Cook: A Computational Study of the Job-Shop Scheduling Problem. 149-156 INFORMS Journal on Computing, Volume 3, Number 1, Winter 1991
Checks hypothesis from the cut.
Encode only the interesting pairs.
interval_1.end <= interval_2.start
interval_2.end <= interval_1.start
Definition at line 849 of file scheduling_cuts.cc.
Graph * operations_research::sat::GenerateGraphForSymmetryDetection | ( | const LinearBooleanProblem & | problem, |
std::vector< int > * | initial_equivalence_classes ) |
Returns a graph whose automorphisms can be mapped back to the symmetries of the given LinearBooleanProblem.
Any permutation of the graph that respects the initial_equivalence_classes output can be mapped to a symmetry of the given problem simply by taking its restriction on the first 2 * num_variables nodes and interpreting its index as a literal index. In a sense, a node with a low enough index i is in one-to-one correspondence with a literals i (using the index representation of literal).
The format of the initial_equivalence_classes is the same as the one described in GraphSymmetryFinder::FindSymmetries(). The classes must be dense in [0, num_classes) and any symmetry will only map nodes with the same class between each other.
First, we convert the problem to its canonical representation.
We will construct a graph with 3 different types of node that must be in different equivalent classes.
First, we need one node per literal with an edge between each literal and its negation.
We have two nodes for each variable.
We use 0 for their initial equivalence class, but that may be modified with the objective coefficient (see below).
Literals with different objective coeffs shouldn't be in the same class.
We need to canonicalize the objective to regroup literals corresponding to the same variables. Note that we don't care about the offset or optimization direction here, we just care about literals with the same canonical coefficient.
Then, for each constraint, we will have one or more nodes.
First we have a node for the constraint with an equivalence class depending on the rhs.
This node will also be connected to all literals of the constraint with a coefficient of 1. Literals with new coefficients will be grouped under a new node connected to the constraint_node_index.
Connect this node to the constraint node. Note that we don't technically need the arcs in both directions, but that may help a bit the algorithm to find symmetries.
Connect this node to the associated term.literal node. Note that we don't technically need the arcs in both directions, but that may help a bit the algorithm to find symmetries.
Definition at line 545 of file boolean_problem.cc.
void operations_research::sat::GenerateInterestingSubsets | ( | int | num_nodes, |
const std::vector< std::pair< int, int > > & | arcs, | ||
int | stop_at_num_components, | ||
std::vector< int > * | subset_data, | ||
std::vector< absl::Span< const int > > * | subsets ) |
Given a graph with nodes in [0, num_nodes) and a set of arcs (the order is important), this will:
This is an heuristic to generate interesting cuts for TSP or other graph based constraints. We roughly follow the algorithm described in section 6 of "The Traveling Salesman Problem, A computational Study", David L. Applegate, Robert E. Bixby, Vasek Chvatal, William J. Cook.
We will do a union-find by adding one by one the arc of the lp solution in the order above. Every intermediate set during this construction will be a candidate for a cut.
In parallel to the union-find, to efficiently reconstruct these sets (at most num_nodes), we construct a "decomposition forest" of the different connected components. Note that we don't exploit any asymmetric nature of the graph here. This is exactly the algo 6.3 in the book above.
Update the decomposition forest, note that the number of nodes is growing.
It is important that the union-find representative is the same node.
For each node in the decomposition forest, try to add a cut for the set formed by the nodes and its children. To do that efficiently, we first order the nodes so that for each node in a tree, the set of children forms a consecutive span in the subset_data vector. This vector just lists the nodes in the "pre-order" graph traversal order. The Spans will point inside the subset_data vector, it is why we initialize it once and for all.
Definition at line 404 of file routing_cuts.cc.
std::vector< ItemForPairwiseRestriction > operations_research::sat::GenerateItemsRectanglesWithNoPairwiseConflict | ( | const std::vector< Rectangle > & | rectangles, |
double | slack_factor, | ||
absl::BitGenRef | random ) |
Definition at line 106 of file 2d_orthogonal_packing_testing.cc.
std::vector< ItemForPairwiseRestriction > operations_research::sat::GenerateItemsRectanglesWithNoPairwisePropagation | ( | int | num_rectangles, |
double | slack_factor, | ||
absl::BitGenRef | random ) |
Now run the propagator until there is no more pairwise conditions.
Remove the slack we added
Definition at line 129 of file 2d_orthogonal_packing_testing.cc.
std::vector< Rectangle > operations_research::sat::GenerateNonConflictingRectangles | ( | int | num_rectangles, |
absl::BitGenRef | random ) |
Definition at line 30 of file 2d_orthogonal_packing_testing.cc.
void operations_research::sat::GenerateNoOvelap2dCompletionTimeCutsWithEnergy | ( | absl::string_view | cut_name, |
std::vector< DiffnCtEvent > | events, | ||
bool | use_lifting, | ||
bool | skip_low_sizes, | ||
Model * | model, | ||
LinearConstraintManager * | manager ) |
We generate the cut from the Smith's rule from: M. Queyranne, Structure of a simple scheduling polyhedron, Mathematical Programming 58 (1993), 263–285
The original cut is: sum(end_min_i * duration_min_i) >= (sum(duration_min_i^2) + sum(duration_min_i)^2) / 2 We strengthen this cuts by noticing that if all tasks starts after S, then replacing end_min_i by (end_min_i - S) is still valid.
A second difference is that we look at a set of intervals starting after a given start_min, sorted by relative (end_lp - start_min).
Sort by start min to bucketize by start_min.
Skip to the next start_min value.
We look at event that start before sequence_start_min, but are forced to cross this time point. In that case, we replace this event by a truncated event starting at sequence_start_min. To do this, we reduce the size_min, align the start_min with the sequence_start_min, and scale the energy down accordingly.
Build the vector of energies as the vector of sizes.
This is competing with the brute force approach. Skip cases covered by the other code.
For the capacity, we use the worse |y_max - y_min| and if all the tasks so far have a fixed demand with a gcd > 1, we can round it down.
We compute the cuts like if it was a disjunctive cut with all the duration actually equal to energy / capacity. But to keep the computation in the integer domain, we multiply by capacity everywhere instead.
We compute the efficacity in the unscaled domain where the l2 norm of the cuts is exactly the sqrt of the sum of squared duration.
Definition at line 404 of file diffn_cuts.cc.
void operations_research::sat::GenerateNoOverlap2dEnergyCut | ( | absl::Span< const std::vector< LiteralValueValue > > | energies, |
absl::Span< int > | rectangles, | ||
absl::string_view | cut_name, | ||
Model * | model, | ||
LinearConstraintManager * | manager, | ||
SchedulingConstraintHelper * | x_helper, | ||
SchedulingConstraintHelper * | y_helper, | ||
SchedulingDemandHelper * | y_demands_helper ) |
We can always skip events.
Compute y_spread.
The sum of all energies can be used to stop iterating early.
For each start time, we will keep the most violated cut generated while scanning the residual intervals.
Accumulate intervals, areas, energies and check for potential cuts.
We sort all tasks (x_start_min(task) >= x_start_min(start_index) by increasing end max.
Let's process residual tasks and evaluate the violation of the cut at each step. We follow the same structure as the cut creation code below.
Dominance rule. If the next interval also fits in [window_min, window_max]*[y_min, y_max], the cut will be stronger with the next interval/rectangle.
Checks the current area vs the sum of all energies. The area is capacity_profile.GetBoundingArea(). We can compare it to the bounding box area: (window_max - window_min) * (y_max - y_min).
Compute the violation of the potential cut.
A maximal violated cut has been found. Build it and add it to the pool.
Definition at line 138 of file diffn_cuts.cc.
Neighborhood operations_research::sat::GenerateSchedulingNeighborhoodFromIntervalPrecedences | ( | absl::Span< const std::pair< int, int > > | precedences, |
const CpSolverResponse & | initial_solution, | ||
const NeighborhoodGeneratorHelper & | helper ) |
Helper method for the scheduling neighborhood generators. Returns a full neighborhood enriched with the set or precedences passed to the generate method.
Collect seen intervals.
Fix the presence/absence of unseen intervals.
If the interval is not enforced, we just relax it. If it belongs to an exactly one constraint, and the enforced interval is not relaxed, then propagation will force this interval to stay not enforced. Otherwise, LNS will be able to change which interval will be enforced among all alternatives.
Fix the value.
Set the current solution as a hint.
Definition at line 1863 of file cp_model_lns.cc.
Neighborhood operations_research::sat::GenerateSchedulingNeighborhoodFromRelaxedIntervals | ( | absl::Span< const int > | intervals_to_relax, |
absl::Span< const int > | variables_to_fix, | ||
const CpSolverResponse & | initial_solution, | ||
absl::BitGenRef | random, | ||
const NeighborhoodGeneratorHelper & | helper ) |
Helper method for the scheduling neighborhood generators. Returns a neighborhood defined from the given set of intervals to relax. For each scheduling constraint, it adds strict relation order between the non-relaxed intervals.
We will extend the set with some interval that we cannot fix.
Fix the presence/absence of non-relaxed intervals.
If the interval is not enforced, we just relax it. If it belongs to an exactly one constraint, and the enforced interval is not relaxed, then propagation will force this interval to stay not enforced. Otherwise, LNS will be able to change which interval will be enforced among all alternatives.
Fix the value.
We differ from the ICAPS05 paper as we do not consider ignored intervals when generating the precedence graph, instead of building the full graph, then removing intervals, and reconstructing the precedence graph heuristically after that.
fix the extra variables passed as parameters.
Set the current solution as a hint.
Definition at line 1927 of file cp_model_lns.cc.
void operations_research::sat::GenerateShortCompletionTimeCutsWithExactBound | ( | const std::string & | cut_name, |
std::vector< CtEvent > | events, | ||
IntegerValue | capacity_max, | ||
Model * | model, | ||
LinearConstraintManager * | manager ) |
Sort by start min to bucketize by start_min.
Skip to the next start_min value.
We look at event that start before sequence_start_min, but are forced to cross this time point. In that case, we replace this event by a truncated event starting at sequence_start_min. To do this, we reduce the size_min, and align the start_min with the sequence_start_min.
Both cases with 1 or 2 tasks are trivial and independent of the order. Also, if capacity is not exceeded, pushing all ends left is a valid LP assignment.
We re-index the elements, so we will start enumerating the permutation from there. Note that if the previous i caused an abort because of the threshold, we might abort right away again!
Unweighted cuts.
Weighted cuts.
Definition at line 1138 of file scheduling_cuts.cc.
IntegerValue operations_research::sat::GetCoefficient | ( | IntegerVariable | var, |
const LinearExpression & | expr ) |
Returns the coefficient of the variable in the expression. Works in linear time.
Definition at line 446 of file linear_constraint.cc.
IntegerValue operations_research::sat::GetCoefficientOfPositiveVar | ( | const IntegerVariable | var, |
const LinearExpression & | expr ) |
Definition at line 458 of file linear_constraint.cc.
IntegerValue operations_research::sat::GetFactorT | ( | IntegerValue | rhs_remainder, |
IntegerValue | divisor, | ||
IntegerValue | max_magnitude ) |
Compute the larger t <= max_t such that t * rhs_remainder >= divisor / 2.
This is just a separate function as it is slightly faster to compute the result only once.
Visible for testing. Returns a function f on integers such that:
Preconditions:
This is used in IntegerRoundingCut() and is responsible for "strengthening" the cut. Just taking f(x) = x / divisor result in the non-strengthened cut and using any function that stricly dominate this one is better.
Algorithm:
Make sure that when we multiply the rhs or the coefficient by a factor t, we do not have an integer overflow. Note that the rhs should be counted in max_magnitude since we will apply f() on it.
std::vector< SatParameters > operations_research::sat::GetFirstSolutionBaseParams | ( | const SatParameters & | base_params | ) |
Returns a vector of base parameters to specify solvers specialized to find a initial solution. This is meant to be used with RepeatParameters() and FilterParameters().
Add one feasibility jump.
Random search.
Add a second feasibility jump.
Random quick restart.
Add a linear feasibility jump. This one seems to perform worse, so we add only 1 for 2 normal LS, and we add this late.
Definition at line 924 of file cp_model_search.cc.
std::vector< SatParameters > operations_research::sat::GetFullWorkerParameters | ( | const SatParameters & | base_params, |
const CpModelProto & | cp_model, | ||
int | num_already_present, | ||
SubsolverNameFilter * | filter ) |
Things to try:
Defines a set of named strategies so it is easier to read in one place the one that are used. See below.
We only use a "fixed search" worker if some strategy is specified or if we have a scheduling model.
Our current set of strategies
Starts by adding user specified ones.
We use the default if empty.
Hack for flatzinc. At the time of parameter setting, the objective is not expanded. So we do not know if core is applicable or not.
Remove the names that should be ignored.
Creates the diverse set of parameters with names and seed.
Do some filtering.
In the corner case of empty variable, lets not schedule the probing as it currently just loop forever instead of returning right away.
Disable core search if there is only 1 term in the objective.
Disable subsolvers that do not implement the deterministic mode.
Remove subsolvers that require an objective.
Add this strategy.
In interleaved mode, we run all of them.
Apply the logic for how many we keep.
Derive some automatic number to leave room for LS/LNS and other strategies not taken into account here.
Definition at line 754 of file cp_model_search.cc.
std::vector< int > operations_research::sat::GetIntervalArticulationPoints | ( | std::vector< IndexedInterval > * | intervals | ) |
Similar to GetOverlappingIntervalComponents(), but returns the indices of all intervals whose removal would create one more connected component in the interval graph. Those are sorted by start. See: https://en.wikipedia.org/wiki/Glossary_of_graph_theory#articulation_point.
New connected component.
Still the same connected component. Was the previous "max" an articulation point ?
We might be re-inserting the same articulation point: guard against it.
Update the max end.
Convert articulation point indices to IndexedInterval.index.
Definition at line 503 of file diffn_util.cc.
absl::flat_hash_map< std::string, SatParameters > operations_research::sat::GetNamedParameters | ( | SatParameters | base_params | ) |
Returns all the named set of parameters known to the solver. This include our default strategies like "max_lp", "core", etc... It is visible here so that this can be reused by parameter validation.
Usually, named strategies just override a few field from the base_params.
By default we disable the logging when we generate a set of parameter. It is possible to force it by setting it in the corresponding named parameter via the subsolver_params field.
The "default" name can be used for the base_params unchanged.
Lp variations only.
Core. Note that we disable the lp here because it is faster on the minizinc benchmark.
It can be interesting to try core and lp.
We do not want to change the objective_var lb from outside as it gives better result to only use locally derived reason in that algo.
We want to spend more time on the LP here.
We want to spend more time on the LP here.
Search variation.
Quick restart.
Less encoding.
Base parameters for shared tree worker.
These settings don't make sense with shared tree search, turn them off as they can break things.
Base parameters for LNS worker.
We disable costly presolve/inprocessing.
Add user defined ones.
Merge the named parameters with the base parameters to create the new parameters.
Fix names (we don't set them above).
Definition at line 478 of file cp_model_search.cc.
std::vector< int > operations_research::sat::GetOrbitopeOrbits | ( | int | n, |
absl::Span< const std::vector< int > > | orbitope ) |
Returns the orbits under the given orbitope action. Same results format as in GetOrbits(). Note that here, the orbit index is simply the row index of an element in the orbitope matrix.
Definition at line 185 of file symmetry_util.cc.
std::vector< int > operations_research::sat::GetOrbits | ( | int | n, |
absl::Span< const std::unique_ptr< SparsePermutation > > | generators ) |
Returns a vector of size n such that
orbits[i] = orbit_index, where orbits are numbered from 0 to num_orbits - 1
Definition at line 153 of file symmetry_util.cc.
void operations_research::sat::GetOverlappingIntervalComponents | ( | std::vector< IndexedInterval > * | intervals, |
std::vector< std::vector< int > > * | components ) |
Given n intervals, returns the set of connected components (using the overlap relation between 2 intervals). Components are sorted by their start, and inside a component, the intervals are also sorted by start. intervals
is only sorted (by start), and not modified otherwise.
For correctness, ComparatorByStart is enough, but in unit tests we want to verify this function against another implementation, and fully defined sorting with tie-breaking makes that much easier. If that becomes a performance bottleneck:
Definition at line 470 of file diffn_util.cc.
std::vector< absl::Span< int > > operations_research::sat::GetOverlappingRectangleComponents | ( | absl::Span< const Rectangle > | rectangles, |
absl::Span< int > | active_rectangles ) |
Creates a graph when two nodes are connected iff their rectangles overlap. Then partition into connected components.
This method removes all singleton components. It will modify the active_rectangle span in place.
Find the component of active_rectangles[start].
Definition at line 102 of file diffn_util.cc.
|
inline |
IndexReferences operations_research::sat::GetReferencesUsedByConstraint | ( | const ConstraintProto & | ct | ) |
Definition at line 81 of file cp_model_utils.cc.
void operations_research::sat::GetReferencesUsedByConstraint | ( | const ConstraintProto & | ct, |
std::vector< int > * | variables, | ||
std::vector< int > * | literals ) |
Definition at line 87 of file cp_model_utils.cc.
ReducedDomainNeighborhood operations_research::sat::GetRinsRensNeighborhood | ( | const SharedResponseManager * | response_manager, |
const SharedLPSolutionRepository * | lp_solutions, | ||
SharedIncompleteSolutionManager * | incomplete_solutions, | ||
double | difficulty, | ||
absl::BitGenRef | random ) |
Helper method to create a RINS neighborhood by fixing variables with same values in relaxation solution and the current best solution in the response_manager. Prioritizes repositories in following order to get a neighborhood.
If response_manager has no solution, this generates a RENS neighborhood by ignoring the solutions and using the relaxation values. The domain of the variables are reduced to integer values around relaxation values. If the relaxation value is integer, then we fix the domain of the variable to that value.
Using a partial LP relaxation computed by feasibility_pump, and a full lp relaxation periodically dumped by linearization=2 workers is equiprobable.
int operations_research::sat::GetSingleRefFromExpression | ( | const LinearExpressionProto & | expr | ) |
Returns the reference the expression can be reduced to. It will DCHECK that ExpressionContainsSingleRef(expr) is true.
Definition at line 580 of file cp_model_utils.cc.
std::vector< int64_t > operations_research::sat::GetSolutionValues | ( | const CpModelProto & | model_proto, |
const Model & | model ) |
For ignored or not fully instantiated variable, we just use the lower bound.
Just use the lower bound if the variable is not fully instantiated.
Definition at line 286 of file cp_model_solver_helpers.cc.
std::function< IntegerValue(IntegerValue)> operations_research::sat::GetSuperAdditiveRoundingFunction | ( | IntegerValue | rhs_remainder, |
IntegerValue | divisor, | ||
IntegerValue | t, | ||
IntegerValue | max_scaling ) |
Adjust after the multiplication by t.
Make sure we don't have an integer overflow below. Note that we assume that divisor and the maximum coeff magnitude are not too different (maybe a factor 1000 at most) so that the final result will never overflow.
Because of our max_t limitation, the rhs_remainder might stay small.
If it is "too small" we cannot use the code below because it will not be valid. So we just divide divisor into max_scaling bucket. The rhs_remainder will be in the bucket 0.
Note(user): This seems the same as just increasing t, modulo integer overflows. Maybe we should just always do the computation like this so that we can use larger t even if coeff is close to kint64max.
We divide (size = divisor - rhs_remainder) into (max_scaling - 1) buckets and increase the function by 1 / max_scaling for each of them.
Another interesting fact, is that if we want to compute the maximum alpha for a constraint with 2 terms like: divisor * Y + (ratio * divisor + remainder) * X <= rhs_ratio * divisor + rhs_remainder so that we have the cut: Y + (ratio + alpha) * X <= rhs_ratio This is the same as computing the maximum alpha such that for all integer X > 0 we have CeilRatio(alpha * divisor * X, divisor) <= CeilRatio(remainder * X - rhs_remainder, divisor). We can prove that this alpha is of the form (n - 1) / n, and it will be reached by such function for a max_scaling of n.
std::function< IntegerValue(IntegerValue)> operations_research::sat::GetSuperAdditiveStrengtheningFunction | ( | IntegerValue | positive_rhs, |
IntegerValue | min_magnitude ) |
If we have an equation sum ci.Xi >= rhs with everything positive, and all ci are >= min_magnitude then any ci >= rhs can be set to rhs. Also if some ci are in [rhs - min, rhs) then they can be strenghtened to rhs - min.
If we apply this to the negated equation (sum -ci.Xi + sum cj.Xj <= -rhs) with potentially positive terms, this reduce to apply a super-additive function:
Plot look like: x=-rhs x=0 | | y=0 : | ------------------------------— | — | / |— y=-rhs ----—
The transformation only work if 2 * second_threshold >= positive_rhs.
This should actually never happen by the definition of min_magnitude. But with it, the function is supper-additive even if min_magnitude is not correct.
std::function< IntegerValue(IntegerValue)> operations_research::sat::GetSuperAdditiveStrengtheningMirFunction | ( | IntegerValue | positive_rhs, |
IntegerValue | scaling ) |
|
inline |
a >= b.
Definition at line 629 of file precedences.h.
|
inline |
IntegerLiteral operations_research::sat::GreaterOrEqualToMiddleValue | ( | IntegerVariable | var, |
IntegerTrail * | integer_trail ) |
Returns decision corresponding to var >= lb + max(1, (ub - lb) / 2). It also CHECKs that the variable is not fixed.
Definition at line 76 of file integer_search.cc.
|
inline |
Definition at line 138 of file cp_constraints.h.
std::vector< int > operations_research::sat::GreedyFastDecreasingGcd | ( | absl::Span< const int64_t > | coeffs | ) |
Returns an ordering of the indices of coefficients such that the GCD of its initial segments decreases fast. As the product of the 15 smallest prime numbers is the biggest fitting in an int64_t, it is guaranteed that the GCD becomes stationary after at most 15 steps. Returns an empty vector if the GCD is equal to the absolute value of one of the coefficients.
initial_count is very small (proven <= 15, usually much smaller).
Definition at line 66 of file diophantine.cc.
|
inline |
Small utility functions to deal with half-reified constraints.
Definition at line 48 of file cp_model_utils.h.
|
inline |
Always true! nothing to do.
Always false.
a => b.
Definition at line 942 of file sat_solver.h.
bool operations_research::sat::ImportModelAndDomainsWithBasicPresolveIntoContext | ( | const CpModelProto & | in_model, |
const std::vector< Domain > & | domains, | ||
std::function< bool(int)> | active_constraints, | ||
PresolveContext * | context ) |
Same as ImportModelWithBasicPresolveIntoContext() except that variable domains are read from domains.
Definition at line 12365 of file cp_model_presolve.cc.
bool operations_research::sat::ImportModelWithBasicPresolveIntoContext | ( | const CpModelProto & | in_model, |
PresolveContext * | context ) |
Copy in_model to the model in the presolve context. It performs on the fly simplification, and returns false if the model is proved infeasible. If reads the parameters 'ignore_names' and keeps or deletes variables and constraints names accordingly.
This should only be called on the first copy of the user given model.
Definition at line 12353 of file cp_model_presolve.cc.
operations_research::sat::InclusionDetector | ( | const Storage & | storage | ) | -> InclusionDetector< Storage > |
Deduction guide.
void operations_research::sat::IncreaseNodeSize | ( | EncodingNode * | node, |
SatSolver * | solver ) |
Increases the size of the given node by one. To keep all the needed relations with its children, we also need to increase their size by one, and so on recursively. Also adds all the necessary clauses linking the newly added literals.
Only one side of the constraint is mandatory (the one propagating the ones to the top of the encoding tree), and it seems more efficient not to encode the other side.
Integer leaf node.
Add a literal to a if needed. That is, now that the node n can go up to it new current_ub, if we need to increase the current_ub of a.
Add a literal to b if needed.
Wire the new literal of n correctly with its two children.
if x <= ia and y <= ib then x + y <= ia + ib.
if x > ia and y > ib - 1 then x + y > ia + ib.
Case ia = a->lb() - 1; a->GreaterThan(ia) always true.
case ia == a->ub; a->GreaterThan(ia) always false.
Definition at line 289 of file encoding.cc.
void operations_research::sat::InitializeDebugSolution | ( | const CpModelProto & | model_proto, |
Model * | model ) |
This both copy the "main" DebugSolution to a local_model and also cache the value of the integer variables in that solution.
Copy the proto values.
Fill the values by integer variable.
If the solution is fully boolean (there is no integer variable), and we have a decision problem (so no new boolean should be created), we load it in the sat solver for debugging too.
The objective variable is usually not part of the proto, but it is still nice to have it, so we recompute it here.
We also register a DEBUG callback to check our reasons.
First case, this Boolean is mapped.
Second case, it is associated to IntVar >= value. We can use any of them, so if one is false, we use this one.
Note the sign is inversed, we cannot have all literal false and all integer literal true.
Definition at line 142 of file cp_model_solver_helpers.cc.
void operations_research::sat::InsertVariablesFromConstraint | ( | const CpModelProto & | model_proto, |
int | index, | ||
Set & | output ) |
Insert variables in a constraint into a set.
Definition at line 104 of file cp_model_utils.h.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::InstrumentSearchStrategy | ( | const CpModelProto & | cp_model_proto, |
const std::vector< IntegerVariable > & | variable_mapping, | ||
std::function< BooleanOrIntegerLiteral()> | instrumented_strategy, | ||
Model * | model ) |
For debugging fixed-search: display information about the named variables domain before taking each decision. Note that we copy the instrumented strategy so it doesn't have to outlive the returned functions like the other arguments.
Definition at line 421 of file cp_model_search.cc.
|
inline |
|
constexpr |
The minimal value of an envelope, for instance the envelope of the empty set.
The Theta-Lambda tree can be used to implement several scheduling algorithms.
This template class is instantiated only for IntegerValue and int64_t.
The tree structure itself is a binary tree coded in a vector, where node 0 is unused, node 1 is the root, node 2 is the left child of the root, node 3 its right child, etc.
The API gives access to rightmost events that realize a given envelope.
See: _ (0) Petr Vilim's PhD thesis "Global Constraints in Scheduling". _ (1) Petr Vilim "Edge Finding Filtering Algorithm for Discrete Cumulative Resources in O(kn log n)" _ (2) Petr Vilim "Max energy filtering algorithm for discrete cumulative resources". _ (3) Wolf & Schrader "O(n log n) Overload Checking for the Cumulative Constraint and Its Application". _ (4) Kameugne & Fotso "A cumulative not-first/not-last filtering algorithm in O(n^2 log n)". _ (5) Ouellet & Quimper "Time-table extended-edge-finding for the cumulative constraint".
Instead of providing one declination of the theta-tree per possible filtering algorithm, this generalization intends to provide a data structure that can fit several algorithms. This tree is based around the notion of events. It has events at its leaves that can be present or absent, and present events come with an initial_envelope, a minimal and a maximal energy. All nodes maintain values on the set of present events under them: _ sum_energy_min(node) = sum_{leaf \in leaves(node)} energy_min(leaf) _ envelope(node) = max_{leaf \in leaves(node)} initial_envelope(leaf) + sum_{leaf' \in leaves(node), leaf' >= leaf} energy_min(leaf').
Thus, the envelope of a leaf representing an event, when present, is initial_envelope(event) + sum_energy_min(event).
We also maintain envelope_opt with is the maximum envelope a node could take if at most one of the events were at its maximum energy. _ energy_delta(leaf) = energy_max(leaf) - energy_min(leaf) _ max_energy_delta(node) = max_{leaf \in leaves(node)} energy_delta(leaf) _ envelope_opt(node) = max_{leaf \in leaves(node)} initial_envelope(leaf) + sum_{leaf' \in leaves(node), leaf' >= leaf} energy_min(leaf') + max_{leaf' \in leaves(node), leaf' >= leaf} energy_delta(leaf');
Most articles using theta-tree variants hack Vilim's original theta tree for the disjunctive resource constraint by manipulating envelope and energy: _ in (0), initial_envelope = start_min, energy = duration _ in (3), initial_envelope = C * start_min, energy = demand * duration _ in (5), there are several trees in parallel: initial_envelope = C * start_min or (C - h) * start_min energy = demand * duration, h * (Horizon - start_min), or h * (end_min). _ in (2), same as (3), but putting the max energy instead of min in lambda. _ in OscaR's TimeTableOverloadChecker, initial_envelope = C * start_min - energy of mandatory profile before start_min, energy = demand * duration
There is hope to unify the variants of these algorithms by abstracting the tasks away to reason only on events.
Definition at line 95 of file theta_tree.h.
|
constexpr |
Definition at line 99 of file theta_tree.h.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::IntegerValueSelectionHeuristic | ( | std::function< BooleanOrIntegerLiteral()> | var_selection_heuristic, |
Model * | model ) |
Changes the value of the given decision by 'var_selection_heuristic' according to various value selection heuristics. Looks at the code to know exactly what heuristic we use.
LP based value.
Solution based value.
Objective based value.
Definition at line 363 of file integer_search.cc.
bool operations_research::sat::IntervalIsVariable | ( | const IntervalVariable | interval, |
IntervalsRepository * | intervals_repository ) |
Ignore absent rectangles.
Checks non-present intervals.
Checks variable sized intervals.
Definition at line 1590 of file linear_relaxation.cc.
|
inline |
bool operations_research::sat::IsAssignmentValid | ( | const LinearBooleanProblem & | problem, |
const std::vector< bool > & | assignment ) |
Checks that an assignment is valid for the given BooleanProblem.
Check that all constraints are satisfied.
Definition at line 373 of file boolean_problem.cc.
|
inline |
Expresses the fact that an existing integer variable is equal to the maximum of other integer variables.
Definition at line 758 of file integer_expr.h.
|
inline |
Expresses the fact that an existing integer variable is equal to the minimum of linear expressions. Assumes Canonical expressions (all positive coefficients).
Create a new variable if the expression is not just a single variable.
min_var = min_expr
Definition at line 717 of file integer_expr.h.
|
inline |
Expresses the fact that an existing integer variable is equal to the minimum of other integer variables.
Definition at line 700 of file integer_expr.h.
|
inline |
|
inline |
std::function< void(Model *)> operations_research::sat::IsOneOf | ( | IntegerVariable | var, |
const std::vector< Literal > & | selectors, | ||
const std::vector< IntegerValue > & | values ) |
Expresses the fact that an existing integer variable is equal to one of the given values, each selected by a given literal.
Definition at line 1656 of file integer_expr.cc.
|
inline |
Definition at line 952 of file intervals.h.
|
inline |
Definition at line 958 of file intervals.h.
const Coefficient operations_research::sat::kCoefficientMax | ( | std::numeric_limits< Coefficient::ValueType > | ::max() | ) |
IMPORTANT: We can't use numeric_limits<Coefficient>::max() which will compile but just returns zero!!
const LiteralIndex operations_research::sat::kFalseLiteralIndex | ( | - | 3 | ) |
|
constexpr |
The max range of an integer variable is [kMinIntegerValue, kMaxIntegerValue].
It is symmetric so the set of possible ranges stays the same when we take the negation of a variable. Moreover, we need some IntegerValue that fall outside this range on both side so that we can usually take care of integer overflow by simply doing "saturated arithmetic" and if one of the bound overflow, the two bounds will "cross" each others and we will get an empty range.
|
constexpr |
const BooleanVariable operations_research::sat::kNoBooleanVariable | ( | - | 1 | ) |
const ClauseIndex operations_research::sat::kNoClauseIndex | ( | - | 1 | ) |
const IntegerVariable operations_research::sat::kNoIntegerVariable | ( | - | 1 | ) |
const IntervalVariable operations_research::sat::kNoIntervalVariable | ( | - | 1 | ) |
const LiteralIndex operations_research::sat::kNoLiteralIndex | ( | - | 1 | ) |
const LiteralIndex operations_research::sat::kTrueLiteralIndex | ( | - | 2 | ) |
Special values used in some API to indicate a literal that is always true or always false.
EncodingNode operations_research::sat::LazyMerge | ( | EncodingNode * | a, |
EncodingNode * | b, | ||
SatSolver * | solver ) |
Merges the two given EncodingNodes by creating a new node that corresponds to the sum of the two given ones. Only the left-most binary variable is created for the parent node, the other ones will be created later when needed.
Definition at line 279 of file encoding.cc.
EncodingNode * operations_research::sat::LazyMergeAllNodeWithPQAndIncreaseLb | ( | Coefficient | weight, |
const std::vector< EncodingNode * > & | nodes, | ||
SatSolver * | solver, | ||
std::deque< EncodingNode > * | repository ) |
Same as MergeAllNodesWithDeque() but use a priority queue to merge in priority nodes with smaller sizes. This also enforce that the sum of nodes is greater than its lower bound.
Definition at line 461 of file encoding.cc.
std::string operations_research::sat::LinearBooleanProblemToCnfString | ( | const LinearBooleanProblem & | problem | ) |
Note(user): This function makes a few assumptions about the format of the given LinearBooleanProblem. All constraint coefficients must be 1 (and of the form >= 1) and all objective weights must be strictly positive.
Converts a LinearBooleanProblem to the cnf file format.
Hack: We know that all the variables with index greater than this have been created "artificially" in order to encode a max-sat problem into our format. Each extra variable appear only once, and was used as a slack to reify a soft clause.
This will contains the objective.
This will be the weight of the "hard" clauses in the wcnf format. It must be greater than the sum of the weight of all the soft clauses, so we will just set it to this sum + 1.
There is no direct support for an objective offset in the wcnf format. So this is not a perfect translation of the objective. It is however possible to achieve the same effect by adding a new variable x, and two soft clauses: x with weight offset, and -x with weight offset.
Output the rest of the objective as singleton constraints.
Since it is falsifying this clause that cost "weigtht", we need to take its negation.
Definition at line 403 of file boolean_problem.cc.
int64_t operations_research::sat::LinearExpressionGcd | ( | const LinearExpressionProto & | expr, |
int64_t | gcd = 0 ) |
Returns the gcd of the given LinearExpressionProto. Specifying the second argument will take the gcd with it.
Definition at line 51 of file cp_model_utils.cc.
bool operations_research::sat::LinearExpressionProtosAreEqual | ( | const LinearExpressionProto & | a, |
const LinearExpressionProto & | b, | ||
int64_t | b_scaling ) |
Returns true iff a == b * b_scaling.
Definition at line 619 of file cp_model_utils.cc.
bool operations_research::sat::LinearInequalityCanBeReducedWithClosestMultiple | ( | int64_t | base, |
absl::Span< const int64_t > | coeffs, | ||
absl::Span< const int64_t > | lbs, | ||
absl::Span< const int64_t > | ubs, | ||
int64_t | rhs, | ||
int64_t * | new_rhs ) |
Given a linear equation "sum coeff_i * X_i <= rhs. We can rewrite it using ClosestMultiple() as "base * new_terms + error <= rhs" where error can be bounded using the provided bounds on each variables. This will return true if the error can be ignored and this equation is completely equivalent to new_terms <= new_rhs.
This is useful for cases like 9'999 X + 10'0001 Y <= 155'000 where we have weird coefficient (maybe due to scaling). With a base of 10K, this is equivalent to X + Y <= 15.
Preconditions: All coeffs are assumed to be positive. You can easily negate all the negative coeffs and corresponding bounds before calling this.
Precompute some bounds for the equation base * X + error <= rhs.
The constraint is trivially true.
This is the max error assuming that activity > rhs.
We have old solution valid => base * X + error <= rhs base * X <= rhs - error base * X <= rhs - min_error X <= new_rhs
And we have old solution invalid => base * X + error >= rhs + 1 base * X >= rhs + 1 - max_error_if_invalid X >= infeasibility_bound
If the two bounds can be separated, we have an equivalence !
bool operations_research::sat::LinearizedPartIsLarge | ( | Model * | model | ) |
Returns true if the number of variables in the linearized part represent a large enough proportion of all the problem variables.
Definition at line 347 of file integer_search.cc.
|
inline |
Returns true iff the two linear constraint only differ at a single term.
Preconditions: Constraint should be sorted by variable and of same size.
Definition at line 352 of file presolve_util.h.
|
inline |
Only used for testing to use the classical SAT notation for a literal. This allows to write Literals({+1, -4, +3}) for the clause with BooleanVariable 0 and 2 appearing positively and 3 negatively.
Definition at line 146 of file sat_base.h.
std::function< void(Model *)> operations_research::sat::LiteralTableConstraint | ( | const std::vector< std::vector< Literal > > & | literal_tuples, |
const std::vector< Literal > & | line_literals ) |
Enforces that exactly one literal in line_literals is true, and that all literals in the corresponding line of the literal_tuples matrix are true. This constraint assumes that exactly one literal per column of the literal_tuples matrix is true.
line_literals[i] == true => literal_tuples[i][j] == true. literal_tuples[i][j] == false => line_literals[i] == false.
Exactly one selected literal is true.
If all selected literals of the lines containing a literal are false, then the literal is false.
|
inline |
Enforces the XOR of a set of literals to be equal to the given value.
Definition at line 126 of file cp_constraints.h.
void operations_research::sat::LoadAllDiffConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1512 of file cp_model_loader.cc.
bool operations_research::sat::LoadAndConsumeBooleanProblem | ( | LinearBooleanProblem * | problem, |
SatSolver * | solver ) |
Same as LoadBooleanProblem() but also free the memory used by the problem during the loading. This allows to use less peak memory. Note that this function clear all the constraints of the given problem (not the objective though).
We will process the constraints backward so we can free the memory used by each constraint just after processing it. Because of that, we initially reverse all the constraints to add them in the same order.
Definition at line 272 of file boolean_problem.cc.
void operations_research::sat::LoadAndSolveCpModelForTest | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Definition at line 2597 of file cp_model_solver.cc.
void operations_research::sat::LoadAtMostOneConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1037 of file cp_model_loader.cc.
void operations_research::sat::LoadBaseModel | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Simple function for the few places where we do "return unsat()".
We will add them all at once after model_proto is loaded.
Check the model is still feasible before continuing.
Fully encode variables as needed by the search strategy.
Reserve space for the precedence relations.
Load the constraints.
We propagate after each new Boolean constraint but not the integer ones. So we call FinishPropagation() manually here.
Definition at line 916 of file cp_model_solver_helpers.cc.
void operations_research::sat::LoadBoolAndConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1023 of file cp_model_loader.cc.
bool operations_research::sat::LoadBooleanProblem | ( | const LinearBooleanProblem & | problem, |
SatSolver * | solver ) |
Loads a BooleanProblem into a given SatSolver instance.
Definition at line 232 of file boolean_problem.cc.
void operations_research::sat::LoadBooleanSymmetries | ( | const CpModelProto & | model_proto, |
Model * | m ) |
Experimental. Loads the symmetry form the proto symmetry field, as long as they only involve Booleans.
We currently can only use symmetry that touch a subset of variables.
First, we currently only support loading symmetry between Booleans.
Tricky: Moreover, some constraint will causes extra Boolean to be created and linked with the Boolean in the constraints. We can't use any of the symmetry that touch these since we potentially miss the component that will map these extra Booleans between each other.
A linear with a complex domain might need extra Booleans to be loaded.
Convert the variable symmetry to a "literal" one.
Definition at line 306 of file cp_model_loader.cc.
void operations_research::sat::LoadBoolOrConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Constraint loading functions.
Definition at line 1010 of file cp_model_loader.cc.
void operations_research::sat::LoadBoolXorConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1053 of file cp_model_loader.cc.
void operations_research::sat::LoadCircuitConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1650 of file cp_model_loader.cc.
void operations_research::sat::LoadCircuitCoveringConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
|
inline |
LinearConstraint version.
The enforcement literals cannot be all at true.
Definition at line 616 of file integer_expr.h.
bool operations_research::sat::LoadConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Calls one of the functions below. Returns false if we do not know how to load the given constraints.
Already dealt with.
Definition at line 1675 of file cp_model_loader.cc.
void operations_research::sat::LoadCpModel | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Loads a CpModelProto inside the given model. This should only be called once on a given 'Model' class.
We want to load the debug solution before the initial propag. But at this point the objective is not loaded yet, so we will not have a value for the objective integer variable, so we do it again later.
Simple function for the few places where we do "return unsat()".
Auto detect "at least one of" constraints in the PrecedencesPropagator.
Compute decomposed energies on demands helper.
We need to know beforehand if the objective var can just be >= terms or needs to be == terms.
Create an objective variable and its associated linear constraint if needed.
Linearize some part of the problem and register LP constraint(s).
We do not care about the <= obj for core, we only need the other side to enforce a restriction of the objective lower bound.
Create the objective definition inside the Model so that it can be accessed by the heuristics than needs it.
Fill the objective heuristics data.
Register an objective special propagator.
Intersect the objective domain with the given one if any.
Report the initial objective variable bounds.
Watch improved objective best bounds.
Import objective bounds.
Initialize the search strategies.
Create the CoreBasedOptimizer class if needed.
Definition at line 1063 of file cp_model_solver_helpers.cc.
void operations_research::sat::LoadCumulativeConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1619 of file cp_model_loader.cc.
void operations_research::sat::LoadDebugSolution | ( | const CpModelProto & | model_proto, |
Model * | model ) |
This should be called on the presolved model. It will read the file specified by –cp_model_load_debug_solution and properly fill the model->Get<DebugSolution>() proto vector.
Make sure we load a solution with the same number of variable has in the presolved model.
Definition at line 121 of file cp_model_solver_helpers.cc.
void operations_research::sat::LoadExactlyOneConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1043 of file cp_model_loader.cc.
void operations_research::sat::LoadFeasibilityPump | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Add linear constraints to Feasibility Pump.
Definition at line 1031 of file cp_model_solver_helpers.cc.
void operations_research::sat::LoadIntDivConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1554 of file cp_model_loader.cc.
void operations_research::sat::LoadIntMaxConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
void operations_research::sat::LoadIntMinConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
void operations_research::sat::LoadIntModConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1574 of file cp_model_loader.cc.
void operations_research::sat::LoadIntProdConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1519 of file cp_model_loader.cc.
void operations_research::sat::LoadLinearConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Compute the min/max to relax the bounds if needed.
Load conditional precedences.
To avoid overflow in the code below, we tighten the bounds.
Load precedences.
To avoid overflow in the code below, we tighten the bounds.
magnitude * v1 <= magnitude * v2 + rhs_max.
magnitude * v1 >= magnitude * v2 + rhs_min.
Make the terms magnitude * v1 - magnitude * v2 ...
magnitude * v1 + other_lb <= magnitude * v2 + rhs_max
magnitude * v1 + other_ub >= magnitude * v2 + rhs_min
We have a linear with a complex Domain, we need to create extra Booleans.
In this case, we can create just one Boolean instead of two since one is the negation of the other.
For enforcement => var \in domain, we can potentially reuse the encoding literal directly rather than creating new ones.
Make sure all booleans are tights when enumerating all solutions.
Definition at line 1215 of file cp_model_loader.cc.
|
inline |
Definition at line 648 of file integer_expr.h.
void operations_research::sat::LoadLinMaxConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1586 of file cp_model_loader.cc.
bool operations_research::sat::LoadModelForProbing | ( | PresolveContext * | context, |
Model * | local_model ) |
Load the constraints in a local model.
Utility function to load the current problem into a in-memory representation that will be used for probing. Returns false if UNSAT.
Update the domain in the current CpModelProto.
Adapt some of the parameters during this probing phase.
Important: Because the model_proto do not contains affine relation or the objective, we cannot call DetectOptionalVariables() ! This might wrongly detect optionality and derive bad conclusion.
Definition at line 2291 of file presolve_context.cc.
void operations_research::sat::LoadNoOverlap2dConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1609 of file cp_model_loader.cc.
void operations_research::sat::LoadNoOverlapConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1604 of file cp_model_loader.cc.
void operations_research::sat::LoadReservoirConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1629 of file cp_model_loader.cc.
void operations_research::sat::LoadRoutesConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1662 of file cp_model_loader.cc.
void operations_research::sat::LoadSubcircuitConstraint | ( | int | num_nodes, |
const std::vector< int > & | tails, | ||
const std::vector< int > & | heads, | ||
const std::vector< Literal > & | literals, | ||
Model * | model, | ||
bool | multiple_subcircuit_through_zero = false ) |
Model based functions. This just wraps CircuitPropagator. See the comment there to see what this does. Note that any nodes with no outgoing or no incoming arc will cause the problem to be UNSAT. One can call ReindexArcs() first to ignore such nodes.
If a node has no outgoing or no incoming arc, the model will be unsat as soon as we add the corresponding ExactlyOneConstraint().
Definition at line 647 of file circuit.cc.
void operations_research::sat::LoadVariables | ( | const CpModelProto & | model_proto, |
bool | view_all_booleans_as_integers, | ||
Model * | m ) |
Extracts all the used variables in the CpModelProto and creates a sat::Model representation for them. More precisely
Note(user): We could create IntegerVariable on the fly as they are needed, but that loose the original variable order which might be useful in heuristics later.
All [0, 1] variables always have a corresponding Boolean, even if it is fixed to 0 (domain == [0,0]) or fixed to 1 (domain == [1,1]).
Compute the list of positive variable reference for which we need to create an IntegerVariable.
Compute the integer variable references used by the model.
We always add a linear relaxation for circuit/route except for linearization level zero.
Add the objectives variables that needs to be referenceable as integer even if they are only used as Booleans.
Make sure any unused variable, that is not already a Boolean is considered "used".
We want the variable in the problem order.
It is important for memory usage to reserve tight vector has we have many indexed by IntegerVariable. Unfortunately, we create intermediate IntegerVariable while loading large linear constraint, or when we have disjoint LP component. So this is a best effort at a tight upper bound.
Link any variable that has both views.
Associate with corresponding integer variable.
Create the interval variables.
Definition at line 126 of file cp_model_loader.cc.
bool operations_research::sat::LookForTrivialSatSolution | ( | double | deterministic_time_limit, |
Model * | model, | ||
SolverLogger * | logger ) |
Try to randomly tweak the search and stop at the first conflict each time. This can sometimes find feasible solution, but more importantly, it is a form of probing that can sometimes find small and interesting conflicts or fix variables. This seems to work well on the SAT14/app/rook-* problems and do fix more variables if run before probing.
If a feasible SAT solution is found (i.e. all Boolean assigned), then this abort and leave the solver with the full solution assigned.
Returns false iff the problem is UNSAT.
Hack to not have empty logger.
Reset the solver in case it was already used.
SetParameters() reset the deterministic time to zero inside time_limit.
We randomize at the end so that the default params is executed at least once.
Restore the initial parameters.
Definition at line 418 of file probing.cc.
|
inline |
|
inline |
|
inline |
|
inline |
a + offset <= b.
Definition at line 577 of file precedences.h.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::LpPseudoCostHeuristic | ( | Model * | model | ) |
When not reliable, we skip integer.
We delay to subsequent heuristic if the score is 0.0.
This direction works better than the inverse in the benchs. But always branching up seems even better.
Definition at line 234 of file integer_search.cc.
void operations_research::sat::MakeAllCoefficientsPositive | ( | LinearConstraint * | constraint | ) |
Makes all coefficients positive by transforming a variable to its negation.
Definition at line 290 of file linear_constraint.cc.
void operations_research::sat::MakeAllLiteralsPositive | ( | LinearBooleanProblem * | problem | ) |
Modifies the given LinearBooleanProblem so that all the literals appearing inside are positive.
Objective.
Constraints.
Definition at line 648 of file boolean_problem.cc.
void operations_research::sat::MakeAllVariablesPositive | ( | LinearConstraint * | constraint | ) |
Makes all variables "positive" by transforming a variable to its negation.
Definition at line 301 of file linear_constraint.cc.
bool operations_research::sat::MakeBoundsOfIntegerVariablesInteger | ( | const SatParameters & | params, |
MPModelProto * | mp_model, | ||
SolverLogger * | logger ) |
This simple step helps and should be done first. Returns false if the model is trivially infeasible because of crossing bounds.
Definition at line 204 of file lp_utils.cc.
std::vector< RectangleInRange > operations_research::sat::MakeItemsFromRectangles | ( | absl::Span< const Rectangle > | rectangles, |
double | slack_factor, | ||
absl::BitGenRef | random ) |
Definition at line 74 of file 2d_orthogonal_packing_testing.cc.
Coefficient operations_research::sat::MaxNodeWeightSmallerThan | ( | const std::vector< EncodingNode * > & | nodes, |
Coefficient | upper_bound ) |
Returns the maximum node weight under the given upper_bound. Returns zero if no such weight exist (note that a node weight is strictly positive, so this make sense).
Definition at line 574 of file encoding.cc.
|
inline |
Definition at line 946 of file intervals.h.
EncodingNode * operations_research::sat::MergeAllNodesWithDeque | ( | Coefficient | upper_bound, |
const std::vector< EncodingNode * > & | nodes, | ||
SatSolver * | solver, | ||
std::deque< EncodingNode > * | repository ) |
Merges all the given nodes two by two until there is only one left. Returns the final node which encodes the sum of all the given nodes.
Definition at line 439 of file encoding.cc.
Tries to minimize the given UNSAT core with a really simple heuristic. The idea is to remove literals that are consequences of others in the core. We already know that in the initial order, no literal is propagated by the one before it, so we just look for propagation in the reverse order.
Important: The given SatSolver must be the one that just produced the given core.
Definition at line 2781 of file sat_solver.cc.
void operations_research::sat::MinimizeCoreWithPropagation | ( | TimeLimit * | limit, |
SatSolver * | solver, | ||
std::vector< Literal > * | core ) |
Like MinimizeCore() with a slower but strictly better heuristic. This algorithm should produce a minimal core with respect to propagation. We put each literal of the initial core "last" at least once, so if such literal can be inferred by propagation by any subset of the other literal, it will be removed.
We want each literal in candidate to appear last once in our propagation order. We want to do that while maximizing the reutilization of the current assignment prefix, that is minimizing the number of decision/progagation we need to perform.
This is a "weird" API to get the subset of decisions that caused this literal to be false with reason analysis.
We want to preserve the order of literal in the response.
Definition at line 62 of file optimization.cc.
void operations_research::sat::MinimizeCoreWithSearch | ( | TimeLimit * | limit, |
SatSolver * | solver, | ||
std::vector< Literal > * | core ) |
Find a not yet removed literal to remove. We prefer to remove high indices since these are more likely to be of high depth.
Definition at line 119 of file optimization.cc.
SatSolver::Status operations_research::sat::MinimizeIntegerVariableWithLinearScanAndLazyEncoding | ( | IntegerVariable | objective_var, |
const std::function< void()> & | feasible_solution_observer, | ||
Model * | model ) |
Model-based API to minimize a given IntegerVariable by solving a sequence of decision problem. Each problem is solved using SolveIntegerProblem(). Returns the status of the last solved decision problem.
The feasible_solution_observer function will be called each time a new feasible solution is found.
Simple linear scan algorithm to find the optimal.
The objective is the current lower bound of the objective_var.
We have a solution!
Restrict the objective.
Definition at line 216 of file optimization.cc.
void operations_research::sat::MinimizeL1DistanceWithHint | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Solve a model with a different objective consisting of minimizing the L1 distance with the provided hint. Note that this method creates an in-memory copy of the model and loads a local Model object from the copied model.
Forward some shared class.
Change the parameters.
Update the model to introduce penalties to go away from hinted values.
Add a new var to represent the difference between var and value.
new_var = var - value.
abs_var = abs(new_var).
Solve optimization problem.
Definition at line 1539 of file cp_model_solver_helpers.cc.
|
inline |
Model based functions.
Definition at line 940 of file intervals.h.
int64_t operations_research::sat::ModularInverse | ( | int64_t | x, |
int64_t | m ) |
Using the extended Euclidian algo, we find a and b such that a x + b m = gcd(x, m) https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
Returns a in [0, m) such that a * x = 1 modulo m. If gcd(x, m) != 1, there is no inverse, and it returns 0.
This DCHECK that x is in [0, m). This is integer overflow safe.
Note(user): I didn't find this in a easily usable standard library.
We only keep the last two terms of the sequences with the "^1" trick:
q = r[i-2] / r[i-1] r[i] = r[i-2] % r[i-1] t[i] = t[i-2] - t[i-1] * q
We always have:
If the gcd is not one, there is no inverse, we returns 0.
Correct the result so that it is in [0, m). Note that abs(t[i]) is known to be less than or equal to x / 2, and we have thorough unit-tests.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::MostFractionalHeuristic | ( | Model * | model | ) |
Choose the variable with most fractional LP value.
This choose <= value if possible.
Definition at line 181 of file integer_search.cc.
int operations_research::sat::MoveOneUnprocessedLiteralLast | ( | const absl::btree_set< LiteralIndex > & | processed, |
int | relevant_prefix_size, | ||
std::vector< Literal > * | literals ) |
Context: this function is not really generic, but required to be unit-tested. It is used in a clause minimization algorithm when we try to detect if any of the clause literals can be propagated by a subset of the other literal being false. For that, we want to enqueue in the solver all the subset of size n-1.
This moves one of the unprocessed literal from literals to the last position. The function tries to do that while preserving the longest possible prefix of literals "amortized" through the calls assuming that we want to move each literal to the last position once.
For a vector of size n, if we want to call this n times so that each literal is last at least once, the sum of the size of the changed suffixes will be O(n log n). If we were to use a simpler algorithm (like moving the last unprocessed literal to the last position), this sum would be O(n^2).
Returns the size of the common prefix of literals before and after the move, or -1 if all the literals are already processed. The argument relevant_prefix_size is used as a hint when keeping more that this prefix size do not matter. The returned value will always be lower or equal to relevant_prefix_size.
To get O(n log n) size of suffixes, we will first process the last n/2 literals, we then move all of them first and process the n/2 literals left. We use the same algorithm recursively. The sum of the suffixes' size S(n) is thus S(n/2) + n + S(n/2). That gives us the correct complexity. The code below simulates one step of this algorithm and is made to be "robust" when from one call to the next, some literals have been removed (but the order of literals is preserved).
Once a prefix size has been decided, it is always better to enqueue the literal already processed first.
bool operations_research::sat::MPModelProtoValidationBeforeConversion | ( | const SatParameters & | params, |
const MPModelProto & | mp_model, | ||
SolverLogger * | logger ) |
Performs some extra tests on the given MPModelProto and returns false if one is not satisfied. These are needed before trying to convert it to the native CP-SAT format.
Abort if there is constraint type we don't currently support.
Abort if finite variable bounds or objective is too large.
Abort if finite constraint bounds or coefficients are too large.
Definition at line 418 of file lp_utils.cc.
|
inline |
Small utility functions to deal with negative variable/literal references.
Definition at line 43 of file cp_model_utils.h.
LinearExpression operations_research::sat::NegationOf | ( | const LinearExpression & | expr | ) |
Preserves canonicality.
Definition at line 423 of file linear_constraint.cc.
std::vector< IntegerVariable > operations_research::sat::NegationOf | ( | const std::vector< IntegerVariable > & | vars | ) |
Returns the vector of the negated variables.
Definition at line 51 of file integer.cc.
|
inline |
std::function< void(Model *)> operations_research::sat::NewBestBoundCallback | ( | const std::function< void(double)> & | callback | ) |
Creates a callbacks that will be called on each new best objective bound found.
Note that this function is called before the update takes place.
Definition at line 1990 of file cp_model_solver.cc.
|
inline |
std::function< void(Model *)> operations_research::sat::NewFeasibleSolutionLogCallback | ( | const std::function< std::string(const CpSolverResponse &response)> & | callback | ) |
Creates a callbacks that will append a string to the search log when reporting a new solution.
The given function will be called on each improving feasible solution found during the search. For a non-optimization problem, if the option to find all solution was set, then this will be called on each new solution.
Definition at line 1982 of file cp_model_solver.cc.
std::function< void(Model *)> operations_research::sat::NewFeasibleSolutionObserver | ( | const std::function< void(const CpSolverResponse &response)> & | callback | ) |
Creates a solution observer with the model with model.Add(NewFeasibleSolutionObserver([](response){...}));
The given function will be called on each improving feasible solution found during the search. For a non-optimization problem, if the option to find all solution was set, then this will be called on each new solution.
WARNING: Except when enumerate_all_solution() is true, one shouldn't rely on this to get a set of "diverse" solutions since any future change to the solver might completely kill any diversity in the set of solutions observed.
Valid usage of this includes implementing features like:
Definition at line 1975 of file cp_model_solver.cc.
|
inline |
|
inline |
|
inline |
Definition at line 965 of file intervals.h.
|
inline |
Definition at line 980 of file intervals.h.
|
inline |
Definition at line 988 of file intervals.h.
|
inline |
To not have too many solutions during enumeration, we force the start at its min value for absent interval.
Definition at line 1000 of file intervals.h.
|
inline |
Definition at line 1021 of file intervals.h.
|
inline |
Definition at line 1031 of file intervals.h.
std::function< SatParameters(Model *)> operations_research::sat::NewSatParameters | ( | const sat::SatParameters & | parameters | ) |
Tricky: It is important to initialize the model parameters before any of the solver object are created, so that by default they use the given parameters.
Definition at line 2010 of file cp_model_solver.cc.
std::function< SatParameters(Model *)> operations_research::sat::NewSatParameters | ( | const SatParameters & | parameters | ) |
std::function< SatParameters(Model *)> operations_research::sat::NewSatParameters | ( | const std::string & | params | ) |
Creates parameters for the solver, which you can add to the model with
before calling SolveCpModel()
.
Definition at line 1999 of file cp_model_solver.cc.
|
inline |
Model-based function to create an IntegerVariable that corresponds to the given weighted sum of other IntegerVariables.
To avoid overflow in the FixedWeightedSum() constraint, we need to compute the basic bounds on the sum.
Definition at line 669 of file integer_expr.h.
bool operations_research::sat::NoDuplicateVariable | ( | const LinearConstraint & | ct | ) |
Returns false if duplicate variables are found in ct.
Definition at line 367 of file linear_constraint.cc.
void operations_research::sat::NonDeterministicLoop | ( | std::vector< std::unique_ptr< SubSolver > > & | subsolvers, |
int | num_threads ) |
Executes the following loop: 1/ Synchronize all in given order. 2/ generate and schedule one task from the current "best" subsolver. 3/ repeat until no extra task can be generated and all tasks are done.
The complexity of each selection is in O(num_subsolvers), but that should be okay given that we don't expect more than 100 such subsolvers.
The mutex guards num_in_flight and num_in_flight_per_subsolvers. This is used to detect when the search is done.
Predicate to be used with absl::Condition to detect that num_in_flight < num_threads. Must only be called while locking mutex
.
The lambda below are using little space, but there is no reason to create millions of them, so we use the blocking nature of pool.Schedule() when the queue capacity is set.
Set to true if no task is pending right now.
Wait if num_in_flight == num_threads.
To support some "advanced" cancelation of subsolve, we still call synchronize every 0.1 seconds even if there is no worker available.
The stopping condition is that we do not have anything else to generate once all the task are done and synchronized.
We need to do that while holding the lock since substask below might be currently updating the time via AddTaskDuration().
It is hard to know when new info will allows for more task to be scheduled, so for now we just sleep for a bit. Note that in practice We will never reach here except at the end of the search because we can always schedule LNS threads.
Schedule next task.
Definition at line 187 of file subsolver.cc.
int64_t operations_research::sat::NoOverlapMinRepairDistance | ( | const ConstraintProto & | interval1, |
const ConstraintProto & | interval2, | ||
absl::Span< const int64_t > | solution ) |
Definition at line 1212 of file constraint_violation.cc.
A convenient wrapper so we can write Not(x) instead of x.Not() which is sometimes clearer.
Definition at line 87 of file cp_model.cc.
|
inline |
Definition at line 1318 of file cp_model.h.
|
inline |
Definition at line 1313 of file cp_model.h.
|
inline |
Definition at line 1232 of file cp_model.h.
|
inline |
Definition at line 1228 of file cp_model.h.
|
inline |
Definition at line 1244 of file cp_model.h.
|
inline |
Definition at line 1255 of file cp_model.h.
|
inline |
Definition at line 1186 of file cp_model.h.
|
inline |
Definition at line 1195 of file cp_model.h.
|
inline |
Definition at line 1275 of file cp_model.h.
|
inline |
Definition at line 1250 of file cp_model.h.
|
inline |
Definition at line 1260 of file cp_model.h.
|
inline |
Definition at line 1271 of file cp_model.h.
|
inline |
Definition at line 1191 of file cp_model.h.
|
inline |
Definition at line 1199 of file cp_model.h.
|
inline |
Definition at line 1280 of file cp_model.h.
|
inline |
Definition at line 1291 of file cp_model.h.
|
inline |
Definition at line 1209 of file cp_model.h.
|
inline |
Definition at line 1218 of file cp_model.h.
|
inline |
Definition at line 1307 of file cp_model.h.
|
inline |
Definition at line 1286 of file cp_model.h.
|
inline |
Definition at line 1297 of file cp_model.h.
|
inline |
Definition at line 1303 of file cp_model.h.
|
inline |
For DoubleLinearExpr.
Definition at line 1239 of file cp_model.h.
|
inline |
Definition at line 1214 of file cp_model.h.
|
inline |
Definition at line 1223 of file cp_model.h.
|
inline |
Minimal support for "natural" API to create LinearExpr.
Note(user): This might be optimized further by optimizing LinearExpr for holding one term, or introducing an LinearTerm class, but these should mainly be used to construct small expressions. Revisit if we run into performance issues. Note that if perf become a bottleneck for a client, then probably directly writing the proto will be even faster.
Definition at line 1184 of file cp_model.h.
|
inline |
|
inline |
Definition at line 127 of file sat_base.h.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | os, |
const BoolVar & | var ) |
Definition at line 89 of file cp_model.cc.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | os, |
const DoubleLinearExpr & | e ) |
Definition at line 488 of file cp_model.cc.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | os, |
const EnforcementStatus & | e ) |
Definition at line 52 of file linear_propagation.cc.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | os, |
const IntervalVar & | var ) |
Definition at line 641 of file cp_model.cc.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | os, |
const IntVar & | var ) |
Definition at line 171 of file cp_model.cc.
|
inline |
Definition at line 124 of file linear_constraint.h.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | os, |
const LinearExpr & | e ) |
Definition at line 318 of file cp_model.cc.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | os, |
const ValueLiteralPair & | p ) |
Definition at line 65 of file integer.cc.
|
inline |
|
inline |
Definition at line 117 of file sat_base.h.
|
inline |
Definition at line 70 of file pb_constraint.h.
|
inline |
Definition at line 1058 of file sat_solver.h.
std::ostream & operations_research::sat::operator<< | ( | std::ostream & | out, |
const IndexedInterval & | interval ) |
Definition at line 416 of file diffn_util.cc.
|
inline |
hashing support.
Currently limited to a few inner types of ConstraintProto.
Definition at line 310 of file cp_model_utils.h.
|
inline |
Definition at line 331 of file cp_model_utils.h.
int64_t operations_research::sat::OverlapOfTwoIntervals | ( | const ConstraintProto & | interval1, |
const ConstraintProto & | interval2, | ||
absl::Span< const int64_t > | solution ) |
--— CompiledNoOverlap2dConstraint --—
We force a min cost of 1 to cover the case where a interval of size 0 is in the middle of another interval.
Definition at line 1187 of file constraint_violation.cc.
|
inline |
The target variable is equal to exactly one of the candidate variable. The equality is controlled by the given "selector" literals.
Note(user): This only propagate from the min/max of still possible candidates to the min/max of the target variable. The full constraint also requires to deal with the case when one of the literal is true.
Note(user): If there is just one or two candidates, this doesn't add anything.
Propagate the min.
Propagate the max.
Definition at line 165 of file cp_constraints.h.
int64_t operations_research::sat::PositiveMod | ( | int64_t | x, |
int64_t | m ) |
|
inline |
Definition at line 44 of file cp_model_utils.h.
|
inline |
Returns dividend - FloorRatio(dividend, divisor) * divisor;
This function is around the same speed than the computation above, but it never causes integer overflow. Note also that when calling FloorRatio() then PositiveRemainder(), the compiler should optimize the modulo away and just reuse the one from the first integer division.
LinearExpression operations_research::sat::PositiveVarExpr | ( | const LinearExpression & | expr | ) |
Returns the same expression with positive variables.
Definition at line 431 of file linear_constraint.cc.
|
inline |
bool operations_research::sat::PossibleIntegerOverflow | ( | const CpModelProto & | model, |
absl::Span< const int > | vars, | ||
absl::Span< const int64_t > | coeffs, | ||
int64_t | offset = 0 ) |
Check if a given linear expression can create overflow. It is exposed to test new constraints created during the presolve.
In addition to computing the min/max possible sum, we also often compare it with the constraint bounds, so we do not want max - min to overflow. We might also create an intermediate variable to represent the sum.
Definition at line 890 of file cp_model_checker.cc.
bool operations_research::sat::PossibleOverflow | ( | const IntegerTrail & | integer_trail, |
const LinearConstraint & | constraint ) |
Tests for possible overflow in the given linear constraint used for the linear relaxation. This is a bit relaxed compared to what we require for generic linear constraint that are used in our CP propagators.
If this check pass, our constraint should be safe to use in our simplication code, our cut computation, etc...
Definition at line 469 of file linear_constraint.cc.
void operations_research::sat::PostsolveClause | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
This postsolve is "special". If the clause is not satisfied, we fix the first literal in the clause to true (even if it was fixed to false). This allows to handle more complex presolve operations used by the SAT presolver.
Also, any "free" Boolean should be fixed to some value for the subsequent postsolve steps.
We still need to assign free variable. Any value should work.
Change the value of the first variable (which was chosen at presolve).
Definition at line 38 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveElement | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
We only support 3 cases in the presolve currently.
Deal with non-fixed target and non-fixed index. This only happen if whatever the value of the index and selected variable, we can choose a valid target, so we just fix the index to its min value in this case.
If the selected variable is not fixed, we also need to fix it.
Deal with fixed index.
Deal with fixed target (and constant vars).
Definition at line 235 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveExactlyOne | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
Fix one at true.
Fix any free variable left at false.
Definition at line 61 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveIntMod | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
We only support assigning to an affine target.
Definition at line 319 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveLinear | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
Here we simply assign all non-fixed variable to a feasible value. Which should always exists by construction.
Fast track for the most common case.
The postsolve code is a bit involved if there is more than one free variable, we have to postsolve them one by one.
Here we recompute the same domains as during the presolve. Everything is like if we where substiting the variable one by one: terms[i] + fixed_activity \in rhs_domains[i] In the reverse order.
Choose a value for free_vars[i] that fall into rhs_domains[i] - fixed_activity. This will crash if the intersection is empty, but it shouldn't be.
Definition at line 115 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveLinMax | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
Compute the max of each expression, and assign it to the target expr. We only support post-solving the case where whatever the value of all expression, there will be a valid target.
In most case all expression are fixed, except in the corner case where one of the expression refer to the target itself !
Definition at line 216 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveResponse | ( | int64_t | num_variables_in_original_model, |
const CpModelProto & | mapping_proto, | ||
const std::vector< int > & | postsolve_mapping, | ||
std::vector< int64_t > * | solution ) |
Postsolves the given response using information filled by our presolver.
This works as follow:
Read the initial variable domains, either from the fixed solution of the presolved problems or from the mapping model.
Process the constraints in reverse order.
We ignore constraint with an enforcement literal set to false. If the enforcement is still unclear, we still process this constraint.
This should never happen as we control what kind of constraint we add to the mapping_proto;
Fill the response. Maybe fix some still unfixed variable.
Definition at line 334 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveResponseWithFullSolver | ( | int | num_variables_in_original_model, |
CpModelProto | mapping_proto, | ||
const std::vector< int > & | postsolve_mapping, | ||
std::vector< int64_t > * | solution ) |
Fix the correct variable in the mapping_proto.
Postosolve parameters.
We only copy the solution from the postsolve_response to the response.
Definition at line 1649 of file cp_model_solver_helpers.cc.
void operations_research::sat::PostsolveResponseWrapper | ( | const SatParameters & | params, |
int | num_variable_in_original_model, | ||
const CpModelProto & | mapping_proto, | ||
const std::vector< int > & | postsolve_mapping, | ||
std::vector< int64_t > * | solution ) |
Definition at line 1693 of file cp_model_solver_helpers.cc.
bool operations_research::sat::Preprocess | ( | absl::Span< PermutableItem > & | items, |
std::pair< IntegerValue, IntegerValue > & | bounding_box_size, | ||
int | max_complexity ) |
Exposed for testing.
Try to find an equivalent smaller OPP problem by fixing large items. The API is a bit unusual: it takes a reference to a mutable Span of sizes and rectangles. When this function finds an item that can be fixed, it sets the position of the PermutableItem, reorders items
to put that item in the end of the span and then resizes the span so it contain only non-fixed items.
No point in optimizing obviously infeasible instance.
No item (not even the narrowest one) fit alongside the widest item. So we care only about fitting the remaining items in the remaining space.
Definition at line 567 of file 2d_packing_brute_force.cc.
void operations_research::sat::PresolveBooleanLinearExpression | ( | std::vector< Literal > * | literals, |
std::vector< Coefficient > * | coefficients, | ||
Coefficient * | offset ) |
Transforms the given linear expression so that:
Sorting by literal index regroup duplicate or negated literal together.
Merge terms if needed.
The term is coeff *( 1 - X).
Rebuild with positive coeff.
coeff * X = coeff - coeff * (1 - X).
Definition at line 855 of file optimization.cc.
CpSolverStatus operations_research::sat::PresolveCpModel | ( | PresolveContext * | context, |
std::vector< int > * | postsolve_mapping ) |
Convenient wrapper to call the full presolve.
Public API.
Definition at line 12596 of file cp_model_presolve.cc.
bool operations_research::sat::PresolveFixed2dRectangles | ( | absl::Span< const RectangleInRange > | non_fixed_boxes, |
std::vector< Rectangle > * | fixed_boxes ) |
Given a set of fixed boxes and a set of boxes that are not yet fixed (but attributed a range), look for a more optimal set of fixed boxes that are equivalent to the initial set of fixed boxes. This uses "equivalent" in the sense that a placement of the non-fixed boxes will be non-overlapping with all other boxes if and only if it was with the original set of fixed boxes too.
This implementation compiles a set of areas that cannot be occupied by any item, then calls ReduceNumberofBoxes() to use these areas to minimize fixed_boxes
.
Fixed items are only useful to constraint where the non-fixed items can be placed. This means in particular that any part of a fixed item outside the bounding box of the non-fixed items is useless. Clip them.
The whole rectangle was outside of the domain, remove it.
Add fake rectangles to build a frame around the bounding box. This allows to find more areas that must be empty. The frame is as follows: +************ +...........+ +...........+ +...........+ ************+
All items we added to optional_boxes
at this point are only to be used by the "gap between items" logic below. They are not actual optional boxes and should be removed right after the logic is applied.
Add a rectangle to optional_boxes
but respecting that rectangles must remain disjoint.
Now check if there is any space that cannot be occupied by any non-fixed item.
Now look for gaps between objects that are too small to place anything.
Definition at line 34 of file 2d_rectangle_presolve.cc.
bool operations_research::sat::PrintClauses | ( | const std::string & | file_path, |
SatFormat | format, | ||
absl::Span< const std::vector< Literal > > | clauses, | ||
int | num_variables ) |
Prints the given clauses in the file at the given path, using the given file format. Returns true iff the file was successfully written.
Definition at line 606 of file drat_checker.cc.
void operations_research::sat::ProbeAndFindEquivalentLiteral | ( | SatSolver * | solver, |
SatPostsolver * | postsolver, | ||
DratProofHandler * | drat_proof_handler, | ||
util_intops::StrongVector< LiteralIndex, LiteralIndex > * | mapping, | ||
SolverLogger * | = nullptr ) |
Presolver that does literals probing and finds equivalent literals by computing the strongly connected components of the graph: literal l -> literals propagated by l.
Clears the mapping if there are no equivalent literals. Otherwise, mapping[l] is the representative of the equivalent class of l. Note that mapping[l] may be equal to l.
The postsolver will be updated so it can recover a solution of the mapped problem. Note that this works on any problem the SatSolver can handle, not only pure SAT problem, but the returned mapping do need to be applied to all constraints.
We have no guarantee that the cycle of x and not(x) touch the same variables. This is because we may have more info for the literal probed later or the propagation may go only in one direction. For instance if we have two clauses (not(x1) v x2) and (not(x1) v not(x2) v x3) then x1 implies x2 and x3 but not(x3) doesn't imply anything by unit propagation.
Because of this, we "merge" the cycles.
We rely on the fact that the representative of a literal x and the one of its negation are the same variable.
If a variable in a cycle is fixed. We want to fix all of them.
We first fix all representative if one variable of the cycle is fixed. In a second pass we fix all the variable of a cycle whose representative is fixed.
Definition at line 1145 of file simplification.cc.
void operations_research::sat::ProbeAndSimplifyProblem | ( | SatPostsolver * | postsolver, |
LinearBooleanProblem * | problem ) |
A simple preprocessing step that does basic probing and removes the equivalent literals.
A simple preprocessing step that does basic probing and removes the fixed and equivalent variables. Note that the variable indices will also be remapped in order to be dense. The given postsolver will be updated with the information needed during postsolve.
We can abort if no information is learned.
Fix fixed variables in the equivalence map and in the postsolver.
Remap the variables into a dense set. All the variables for which the equiv_map is not the identity are no longer needed.
Apply the variable mapping.
Definition at line 837 of file boolean_problem.cc.
Definition at line 173 of file optimization.cc.
|
inline |
|
inline |
Adds the constraint: a * b = p.
Definition at line 786 of file integer_expr.h.
int64_t operations_research::sat::ProductWithModularInverse | ( | int64_t | coeff, |
int64_t | mod, | ||
int64_t | rhs ) |
If we know that X * coeff % mod = rhs % mod, this returns c such that PositiveMod(X, mod) = c.
This requires coeff != 0, mod !=0 and gcd(coeff, mod) == 1. The result will be in [0, mod) but there is no other condition on the sign or magnitude of a and b.
This is overflow safe, and when rhs == 0 or abs(mod) == 1, it returns 0.
Make both in [0, mod).
From X * coeff % mod = rhs We deduce that X % mod = rhs * inverse % mod
We make the operation in 128 bits to be sure not to have any overflow here.
void operations_research::sat::PropagateAutomaton | ( | const AutomatonConstraintProto & | proto, |
const PresolveContext & | context, | ||
std::vector< absl::flat_hash_set< int64_t > > * | states, | ||
std::vector< absl::flat_hash_set< int64_t > > * | labels ) |
Fills and propagates the set of reachable states/labels.
Forward pass.
Backward pass.
Definition at line 51 of file cp_model_expand.cc.
void operations_research::sat::PropagateEncodingFromEquivalenceRelations | ( | const CpModelProto & | model_proto, |
Model * | m ) |
Process all affine relations of the form a*X + b*Y == cte. For each literals associated to (X >= bound) or (X == value) associate it to its corresponding relation on Y. Also do the other side.
Loop over all constraints and find affine ones.
Make sure the coefficient are positive.
We first map the >= literals. It is important to do that first, since otherwise mapping a == literal might creates the underlying >= and <= literals.
Same for the == literals.
Using this function deals properly with UNSAT.
Definition at line 822 of file cp_model_loader.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::PseudoCost | ( | Model * | model | ) |
Gets the branching variable using pseudo costs and combines it with a value for branching.
Definition at line 445 of file integer_search.cc.
void operations_research::sat::QuickSolveWithHint | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Try to find a solution by following the hint and using a low conflict limit. The CpModelProto must already be loaded in the Model.
Temporarily change the parameters.
If the model was loaded with "optimize_with_core" then the objective variable is not linked to its linear expression. Because of that, we can return a solution that does not satisfy the objective domain.
Solve decision problem.
Restrict the objective.
This code is here to debug bad presolve during LNS that corrupt the hint.
Tricky: We can only test that if we don't already have a feasible solution like we do if the hint is complete.
Definition at line 1454 of file cp_model_solver_helpers.cc.
void operations_research::sat::RandomizeDecisionHeuristic | ( | absl::BitGenRef | random, |
SatParameters * | parameters ) |
std::function< BooleanOrIntegerLiteral()> operations_research::sat::RandomizeOnRestartHeuristic | ( | bool | lns_mode, |
Model * | model ) |
Add sat search + fixed_search (to complete the search).
Adds user defined search if present.
Always add heuristic search.
The higher weight for the sat policy is because this policy actually contains a lot of variation as we randomize the sat parameters.
Value selection.
LP Based value.
Solution based value.
Min value.
Special case: Don't change the decision value.
Set some assignment preference.
Use Boolean objective as assignment preference.
Because this is a minimization problem, we prefer to assign a Boolean variable to its "low" objective value. So if a literal has a positive weight when true, we want to set it to false.
Select the variable selection heuristic.
Select the value selection heuristic.
Get the current decision.
Special case: Don't override the decision value.
Decode the decision and get the variable.
Try the selected policy.
Selected policy failed. Revert back to original decision.
Definition at line 955 of file integer_search.cc.
Domain operations_research::sat::ReadDomainFromProto | ( | const ProtoWithDomain & | proto | ) |
Reads a Domain from the domain field of a proto.
Definition at line 133 of file cp_model_utils.h.
void operations_research::sat::RecordLPRelaxationValues | ( | Model * | model | ) |
Adds the current LP solution to the pool.
We only loop over the positive variables.
void operations_research::sat::ReduceModuloBasis | ( | absl::Span< const std::vector< absl::int128 > > | basis, |
const int | elements_to_consider, | ||
std::vector< absl::int128 > & | v ) |
Definition at line 45 of file diophantine.cc.
void operations_research::sat::ReduceNodes | ( | Coefficient | upper_bound, |
Coefficient * | lower_bound, | ||
std::vector< EncodingNode * > * | nodes, | ||
SatSolver * | solver ) |
Reduces the nodes using the now fixed literals, update the lower-bound, and returns the set of assumptions for the next round of the core-based algorithm. Returns an empty set of assumptions if everything is fixed.
Remove the left-most variables fixed to one from each node. Also update the lower_bound. Note that Reduce() needs the solver to be at the root node in order to work.
Fix the nodes right-most variables that are above the gap. If we closed the problem, we abort and return and empty vector.
Remove the empty nodes.
Sort the nodes.
Definition at line 501 of file encoding.cc.
bool operations_research::sat::ReduceNumberofBoxes | ( | std::vector< Rectangle > * | mandatory_rectangles, |
std::vector< Rectangle > * | optional_rectangles ) |
The current implementation just greedly merge rectangles that shares an edge. This is far from optimal, and it exists a polynomial optimal algorithm (see page 3 of [1]) for this problem at least for the case where optional_rectangles is empty.
[1] Eppstein, David. "Graph-theoretic solutions to computational geometry problems." International Workshop on Graph-Theoretic Concepts in Computer Science. Berlin, Heidelberg: Springer Berlin Heidelberg, 2009.
bool for is_optional
Merge two rectangles!
Definition at line 272 of file 2d_rectangle_presolve.cc.
|
inline |
Definition at line 45 of file cp_model_utils.h.
void operations_research::sat::RegisterAndTransferOwnership | ( | Model * | model, |
T * | ct ) |
Definition at line 781 of file integer_expr.h.
void operations_research::sat::RegisterClausesExport | ( | int | id, |
SharedClausesManager * | shared_clauses_manager, | ||
Model * | model ) |
Registers a callback that will export good clauses discovered during search.
Definition at line 811 of file cp_model_solver_helpers.cc.
int operations_research::sat::RegisterClausesLevelZeroImport | ( | int | id, |
SharedClausesManager * | shared_clauses_manager, | ||
Model * | model ) |
Registers a callback to import new clauses stored in the shared_clausess_manager. These clauses are imported at level 0 of the search in the linear scan minimize function. it returns the id of the worker in the shared clause manager.
Registers a callback to import new clauses stored in the shared_clausess_manager. These clauses are imported at level 0 of the search in the linear scan minimize function. it returns the id of the worker in the shared clause manager.
Check this clause was not already learned by this worker. We can delete the fingerprint because we should not learn an identical clause, and the global stream will not emit the same clause while any worker hasn't consumed this clause (and thus also shouldn't relearn the clause).
Definition at line 863 of file cp_model_solver_helpers.cc.
void operations_research::sat::RegisterObjectiveBestBoundExport | ( | IntegerVariable | objective_var, |
SharedResponseManager * | shared_response_manager, | ||
Model * | model ) |
Registers a callback that will report improving objective best bound. It will be called each time new objective bound are propagated at level zero.
If we are not in interleave_search we synchronize right away.
Definition at line 729 of file cp_model_solver_helpers.cc.
void operations_research::sat::RegisterObjectiveBoundsImport | ( | SharedResponseManager * | shared_response_manager, |
Model * | model ) |
Registers a callback to import new objective bounds. It will be called each time the search main loop is back to level zero. Note that it the presence of assumptions, this will not happen until the set of assumptions is changed.
Definition at line 758 of file cp_model_solver_helpers.cc.
void operations_research::sat::RegisterVariableBoundsLevelZeroExport | ( | const CpModelProto & | , |
SharedBoundsManager * | shared_bounds_manager, | ||
Model * | model ) |
Registers a callback that will export variables bounds fixed at level 0 of the search. This should not be registered to a LNS search.
Inspect the modified IntegerVariables.
Inspect the newly modified Booleans.
Clear for next call.
If we are not in interleave_search we synchronize right away.
The callback will just be called on NEWLY modified var. So initially, we do want to read all variables.
Definition at line 543 of file cp_model_solver_helpers.cc.
void operations_research::sat::RegisterVariableBoundsLevelZeroImport | ( | const CpModelProto & | model_proto, |
SharedBoundsManager * | shared_bounds_manager, | ||
Model * | model ) |
Registers a callback to import new variables bounds stored in the shared_bounds_manager. These bounds are imported at level 0 of the search in the linear scan minimize function.
If this is a Boolean, fix it if not already done.
Deal with integer.
Definition at line 644 of file cp_model_solver_helpers.cc.
|
inline |
r <=> (all literals are true).
Note(user): we could have called ReifiedBoolOr() with everything negated.
All true => r true.
Definition at line 991 of file sat_solver.h.
|
inline |
r <=> (a <= b).
r <=> (a <= b) is the same as r <=> not(a=1 and b=0). So r <=> a=0 OR b=1.
Definition at line 1007 of file sat_solver.h.
|
inline |
r <=> (at least one literal is true). This is a reified clause.
All false => r false.
Definition at line 957 of file sat_solver.h.
int operations_research::sat::ReindexArcs | ( | IntContainer * | tails, |
IntContainer * | heads, | ||
absl::flat_hash_map< int, int > * | mapping_output = nullptr ) |
void operations_research::sat::RemoveNearZeroTerms | ( | const SatParameters & | params, |
MPModelProto * | mp_model, | ||
SolverLogger * | logger ) |
To satisfy our scaling requirements, any terms that is almost zero can just be set to zero. We need to do that before operations like DetectImpliedIntegers(), because really low coefficients can cause issues and might lead to less detection.
Having really low bounds or rhs can be problematic. We set them to zero.
Compute for each variable its current maximum magnitude. Note that we will only scale variable with a coefficient >= 1, so it is safe to use this bound.
We want the maximum absolute error while setting coefficients to zero to not exceed our mip wanted precision. So for a binary variable we might set to zero coefficient around 1e-7. But for large domain, we need lower coeff than that, around 1e-12 with the default params.mip_max_bound(). This also depends on the size of the constraint.
We also do the same for the objective coefficient.
Definition at line 308 of file lp_utils.cc.
void operations_research::sat::RemoveZeroTerms | ( | LinearConstraint * | constraint | ) |
Removes the entries with a coefficient of zero.
Definition at line 278 of file linear_constraint.cc.
std::string operations_research::sat::RenderDot | ( | std::optional< Rectangle > | bb, |
absl::Span< const Rectangle > | solution ) |
Render a packing solution as a Graphviz dot file. Only works in the "neato" or "fdp" Graphviz backends.
Definition at line 1543 of file diffn_util.cc.
std::vector< SatParameters > operations_research::sat::RepeatParameters | ( | absl::Span< const SatParameters > | base_params, |
int | num_params_to_generate ) |
Given a base set of parameter, if non-empty, this repeat them (round-robbin) until we get num_params_to_generate. Note that if we don't have a multiple, the first base parameters will be repeated more than the others.
Return if we are done.
Repeat parameters until we have enough.
Definition at line 996 of file cp_model_search.cc.
bool operations_research::sat::ReportEnergyConflict | ( | Rectangle | bounding_box, |
absl::Span< const int > | boxes, | ||
SchedulingConstraintHelper * | x, | ||
SchedulingConstraintHelper * | y ) |
Checks that there is indeed a conflict for the given bounding_box and report it. This returns false for convenience as we usually want to return false on a conflict.
We abort early if a subset of boxes is enough.
Definition at line 127 of file diffn_util.cc.
SatSolver::Status operations_research::sat::ResetAndSolveIntegerProblem | ( | const std::vector< Literal > & | assumptions, |
Model * | model ) |
Resets the solver to the given assumptions before calling SolveIntegerProblem().
Backtrack to level zero.
Sync bounds and maybe do some inprocessing. We reuse the BeforeTakingDecision() code
Add the assumptions if any and solve.
Definition at line 1566 of file integer_search.cc.
bool operations_research::sat::Resolve | ( | absl::Span< const Literal > | clause, |
absl::Span< const Literal > | other_clause, | ||
Literal | complementary_literal, | ||
VariablesAssignment * | assignment, | ||
std::vector< Literal > * | resolvent ) |
Returns true if 'complementary_literal' is the unique complementary literal in the two given clauses. If so the resolvent of these clauses (i.e. their union with 'complementary_literal' and its negation removed) is set in 'resolvent'. 'clause' must contain 'complementary_literal', while 'other_clause' must contain its negation. 'assignment' must have at least as many variables as each clause, and they must all be unassigned. They are still unassigned upon return.
Temporary assignment used to do the checks below in linear time.
Revert the temporary assignment done above.
Definition at line 478 of file drat_checker.cc.
std::function< bool()> operations_research::sat::RestartEveryKFailures | ( | int | k, |
SatSolver * | solver ) |
A restart policy that restarts every k failures.
Definition at line 1157 of file integer_search.cc.
void operations_research::sat::RestrictObjectiveDomainWithBinarySearch | ( | IntegerVariable | objective_var, |
const std::function< void()> & | feasible_solution_observer, | ||
Model * | model ) |
Use a low conflict limit and performs a binary search to try to restrict the domain of objective_var.
Set the requested conflict limit.
The assumption (objective <= value) for values in [unknown_min, unknown_max] reached the conflict limit.
We first refine the lower bound and then the upper bound.
Update the objective lower bound.
The objective is the current lower bound of the objective_var.
We have a solution, restrict the objective upper bound to only look for better ones now.
Definition at line 251 of file optimization.cc.
bool operations_research::sat::SafeAddLinearExpressionToLinearConstraint | ( | const LinearExpressionProto & | expr, |
int64_t | coefficient, | ||
LinearConstraintProto * | linear ) |
Same method, but returns if the addition was possible without overflowing.
Definition at line 600 of file cp_model_utils.cc.
|
inline |
Converts a double to int64_t and cap large magnitudes at kint64min/max. We also arbitrarily returns 0 for NaNs.
Note(user): This is similar to SaturatingFloatToInt(), but we use our own since we need to open source it and the code is simple enough.
Implementation.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::SatSolverHeuristic | ( | Model * | model | ) |
Returns the BooleanOrIntegerLiteral advised by the underlying SAT solver.
Definition at line 406 of file integer_search.cc.
std::function< bool()> operations_research::sat::SatSolverRestartPolicy | ( | Model * | model | ) |
A restart policy that uses the underlying sat solver's policy.
Definition at line 1171 of file integer_search.cc.
std::string operations_research::sat::SatStatusString | ( | SatSolver::Status | status | ) |
Returns a string representation of a SatSolver::Status.
Fallback. We don't use "default:" so the compiler will return an error if we forgot one enum case above.
Definition at line 2764 of file sat_solver.cc.
double operations_research::sat::ScalarProduct | ( | const LinearConstraint & | constraint1, |
const LinearConstraint & | constraint2 ) |
Returns the scalar product of given constraint coefficients. This method assumes that the constraint variables are in sorted order.
Definition at line 217 of file linear_constraint.cc.
bool operations_research::sat::ScaleAndSetObjective | ( | const SatParameters & | params, |
const std::vector< std::pair< int, double > > & | objective, | ||
double | objective_offset, | ||
bool | maximize, | ||
CpModelProto * | cp_model, | ||
SolverLogger * | logger ) |
Scales a double objective to its integer version and fills it in the proto. The variable listed in the objective must be already defined in the cp_model proto as this uses the variables bounds to compute a proper scaling.
This uses params.mip_wanted_tolerance() and params.mip_max_activity_exponent() to compute the scaling. Note however that if the wanted tolerance is not satisfied this still scale with best effort. You can see in the log the tolerance guaranteed by this automatic scaling.
This will almost always returns true except for really bad cases like having infinity in the objective.
Make sure the objective is currently empty.
We filter constant terms and compute some needed quantities.
These are the parameters used for scaling the objective.
Display the objective error/scaling.
Definition at line 1354 of file lp_utils.cc.
std::vector< double > operations_research::sat::ScaleContinuousVariables | ( | double | scaling, |
double | max_bound, | ||
MPModelProto * | mp_model ) |
Multiplies all continuous variable by the given scaling parameters and change the rest of the model accordingly. The returned vector contains the scaling of each variable (will always be 1.0 for integers) and can be used to recover a solution of the unscaled problem from one of the new scaled problems by dividing the variable values.
We usually scale a continuous variable by scaling, but if its domain is going to have larger values than max_bound, then we scale to have the max domain magnitude equal to max_bound.
Definition at line 110 of file lp_utils.cc.
|
inline |
Similar to ScaleObjectiveValue() but uses the integer version.
Definition at line 172 of file cp_model_utils.h.
|
inline |
Scales back a objective value to a double value from the original model.
Definition at line 159 of file cp_model_utils.h.
void operations_research::sat::ScanModelForDominanceDetection | ( | PresolveContext & | context, |
VarDomination * | var_domination ) |
Detects the variable dominance relations within the given model. Note that to avoid doing too much work, we might miss some relations.
Ignore variables that have been substituted already or are unused.
Deal with the affine relations that are not part of the proto. Those only need to be processed in the first pass.
First scan: update the partition.
We cannot infer anything if we don't know the constraint.
The objective is handled like a <= constraints, or an == constraint if there is a non-trivial domain.
Important: We need to write the objective first to make sure it is up to date.
do nothing for now.
Now do two more scan.
We process it like n clauses.
The objective is handled like a <= constraints, or an == constraint if there is a non-trivial domain.
Early abort if no possible relations can be found.
Some statistics.
Definition at line 1107 of file var_domination.cc.
void operations_research::sat::ScanModelForDualBoundStrengthening | ( | const PresolveContext & | context, |
DualBoundStrengthening * | dual_bound_strengthening ) |
Scan the model so that dual_bound_strengthening.Strenghten() works.
Ignore variables that have been substituted already or are unused.
Deal with the affine relations that are not part of the proto. Those only need to be processed in the first pass.
We cannot infer anything if we don't know the constraint.
The objective is handled like a <= constraints, or an == constraint if there is a non-trivial domain.
Definition at line 1313 of file var_domination.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::SchedulingSearchHeuristic | ( | Model * | model | ) |
A simple heuristic for scheduling models.
Simple scheduling heuristic that looks at all the no-overlap constraints and try to assign and perform the intervals that can be scheduled first.
To avoid to scan already fixed intervals, we use a simple reversible int.
Note(user): only the model is captured for no reason.
Variable to fix.
Information to select best.
We want to pack interval to the left. If two have the same start_min, we want to choose the one that will likely leave an easier problem for the other tasks.
Generating random noise can take time, so we use this function to delay it.
Save rev_fixed before we modify it.
For task whose presence is still unknown, our propagators should have propagated the minimum time as if it was present. So this should reflect the earliest time at which this interval can be scheduled.
Finish filling candidate.
For variable size, we compute the min size once the start is fixed to time. This is needed to never pick the "artificial" makespan interval at the end in priority compared to intervals that still need to be scheduled.
Do not replace if we have a strict inequality now.
Setup rev_is_in_dive to be true on the next call only if there was no backtrack since the previous call.
Use the next_decision_override to fix in turn all the variables from the selected interval.
We have been trying to fix this interval for a while. Do we miss some propagation? In any case, try to see if the heuristic above would select something else.
First make sure the interval is present.
We assume that start_min is propagated by now.
We assume that end_min is propagated by now.
Everything is fixed, detach the override.
Definition at line 467 of file integer_search.cc.
void operations_research::sat::SeparateFlowInequalities | ( | int | num_nodes, |
absl::Span< const int > | tails, | ||
absl::Span< const int > | heads, | ||
absl::Span< const AffineExpression > | arc_capacities, | ||
std::function< void(const std::vector< bool > &in_subset, IntegerValue *min_incoming_flow, IntegerValue *min_outgoing_flow)> | get_flows, | ||
const util_intops::StrongVector< IntegerVariable, double > & | lp_values, | ||
LinearConstraintManager * | manager, | ||
Model * | model ) |
This is really similar to SeparateSubtourInequalities, see the reference there.
We will collect only the arcs with a positive lp capacity value to speed up some computation below.
Often capacities have a coeff > 1. We currently exploit this if all coeff have a gcd > 1.
Sort the arcs by non-increasing lp_values.
Process each subsets and add any violated cut.
Initialize "in_subset" and the subset demands.
We will sum the offset of all incoming/outgoing arc capacities.
Compute the current flow in and out of the subset.
This can take a significant portion of the running time, it is why it is faster to do it only on arcs with non-zero lp values which should be in linear number rather than the total number of arc which can be quadratic.
If the gcd is greater than one, because all variables are integer we can round the flow lower bound to the next multiple of the gcd.
Sparse clean up.
Definition at line 794 of file routing_cuts.cc.
void operations_research::sat::SeparateSubtourInequalities | ( | int | num_nodes, |
const std::vector< int > & | tails, | ||
const std::vector< int > & | heads, | ||
const std::vector< Literal > & | literals, | ||
absl::Span< const int64_t > | demands, | ||
int64_t | capacity, | ||
LinearConstraintManager * | manager, | ||
Model * | model ) |
We roughly follow the algorithm described in section 6 of "The Traveling Salesman Problem, A computational Study", David L. Applegate, Robert E. Bixby, Vasek Chvatal, William J. Cook.
We will collect only the arcs with a positive lp_values to speed up some computation below.
Sort the arcs by non-increasing lp_values.
Add the depot so that we have a trivial bound on the number of vehicle.
Hack/optim: we exploit the tree structure of the subsets to not add a cut for a larger subset if we added a cut from one included in it.
Process each subsets and add any violated cut.
If there were no cut added by the heuristic above, we try exact separation.
With n-1 max_flow from a source to all destination, we can get the global min-cut. Here, we use a slightly more advanced algorithm that will find a min-cut for all possible pair of nodes. This is achieved by computing a Gomory-Hu tree, still with n-1 max flow call.
Note(user): Compared to any min-cut, these cut have some nice properties since they are "included" in each other. This might help with combining them within our generic IP cuts framework.
Try all interesting subset from the Gomory-Hu tree.
Exact separation of symmetric Blossom cut. We use the algorithm in the paper: "A Faster Exact Separation Algorithm for Blossom Inequalities", Adam N. Letchford, Gerhard Reinelt, Dirk Oliver Theis, 2004.
Definition at line 580 of file routing_cuts.cc.
void operations_research::sat::SequentialLoop | ( | std::vector< std::unique_ptr< SubSolver > > & | subsolvers | ) |
Same as above, but specialized implementation for the case num_threads=1. This avoids using a Threadpool altogether. It should have the same behavior than the functions above with num_threads=1 and batch_size=1. Note that an higher batch size will not behave in the same way, even if num_threads=1.
Definition at line 86 of file subsolver.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::SequentialSearch | ( | std::vector< std::function< BooleanOrIntegerLiteral()> > | heuristics | ) |
Combines search heuristics in order: if the i-th one returns kNoLiteralIndex, ask the (i+1)-th. If every heuristic returned kNoLiteralIndex, returns kNoLiteralIndex.
Definition at line 290 of file integer_search.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::SequentialValueSelection | ( | std::vector< std::function< IntegerLiteral(IntegerVariable)> > | value_selection_heuristics, |
std::function< BooleanOrIntegerLiteral()> | var_selection_heuristic, | ||
Model * | model ) |
Changes the value of the given decision by 'var_selection_heuristic'. We try to see if the decision is "associated" with an IntegerVariable, and if it is the case, we choose the new value by the first 'value_selection_heuristics' that is applicable. If none of the heuristics are applicable then the given decision by 'var_selection_heuristic' is returned.
Get the current decision.
When we are in the "stable" phase, we prefer to follow the SAT polarity heuristic.
IntegerLiteral case.
Boolean case. We try to decode the Boolean decision to see if it is associated with an integer variable.
Sequentially try the value selection heuristics.
Definition at line 301 of file integer_search.cc.
void operations_research::sat::SetEnforcementLiteralToFalse | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
For now we set the first unset enforcement literal to false. There must be one.
Definition at line 92 of file cp_model_postsolve.cc.
void operations_research::sat::SetToNegatedLinearExpression | ( | const LinearExpressionProto & | input_expr, |
LinearExpressionProto * | output_negated_expr ) |
Fills the target as negated ref.
Definition at line 71 of file cp_model_utils.cc.
void operations_research::sat::SetupTextFormatPrinter | ( | google::protobuf::TextFormat::Printer * | printer | ) |
We register a few custom printers to display variables and linear expression on one line. This is especially nice for variables where it is easy to recover their indices from the line number now.
ex:
variables { domain: [0, 1] } variables { domain: [0, 1] } variables { domain: [0, 1] }
constraints { linear { vars: [0, 1, 2] coeffs: [2, 4, 5 ] domain: [11, 11] } }
Definition at line 870 of file cp_model_utils.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ShaveObjectiveLb | ( | Model * | model | ) |
Definition at line 421 of file integer_search.cc.
void operations_research::sat::SimplifyCanonicalBooleanLinearConstraint | ( | std::vector< LiteralWithCoeff > * | cst, |
Coefficient * | rhs ) |
Given a Boolean linear constraint in canonical form, simplify its coefficients using simple heuristics.
Replace all coefficient >= rhs by rhs + 1 (these literal must actually be false). Note that the linear sum of literals remains canonical.
Definition at line 162 of file pb_constraint.cc.
bool operations_research::sat::SimplifyClause | ( | const std::vector< Literal > & | a, |
std::vector< Literal > * | b, | ||
LiteralIndex * | opposite_literal, | ||
int64_t * | num_inspected_literals = nullptr ) |
Visible for testing. Returns true iff:
If num_inspected_literals_ is not nullptr, the "complexity" of this function will be added to it in order to track the amount of work done.
Because we abort early when size_diff becomes negative, the second test in the while loop is not needed.
A literal of b is not in a, we can abort early by comparing the sizes left.
Definition at line 945 of file simplification.cc.
IntegerValue operations_research::sat::Smallest1DIntersection | ( | IntegerValue | range_min, |
IntegerValue | range_max, | ||
IntegerValue | size, | ||
IntegerValue | interval_min, | ||
IntegerValue | interval_max ) |
1D counterpart of RectangleInRange::GetMinimumIntersectionArea. Finds the minimum possible overlap of a interval of size size
that fits in [range_min, range_max] and a second interval [interval_min, interval_max].
If the item is on the left of the range, we get the intersection between [range_min, range_min + size] and [interval_min, interval_max].
If the item is on the right of the range, we get the intersection between [range_max - size, range_max] and [interval_min, interval_max].
Definition at line 759 of file diffn_util.cc.
bool operations_research::sat::SolutionBooleanValue | ( | const CpSolverResponse & | r, |
BoolVar | x ) |
Evaluates the value of a Boolean literal in a solver response.
Definition at line 1403 of file cp_model.cc.
int64_t operations_research::sat::SolutionIntegerValue | ( | const CpSolverResponse & | r, |
const LinearExpr & | expr ) |
Evaluates the value of an linear expression in a solver response.
Definition at line 1392 of file cp_model.cc.
bool operations_research::sat::SolutionIsFeasible | ( | const CpModelProto & | model, |
absl::Span< const int64_t > | variable_values, | ||
const CpModelProto * | mapping_proto = nullptr, | ||
const std::vector< int > * | postsolve_mapping = nullptr ) |
Verifies that the given variable assignment is a feasible solution of the given model. The values vector should be in one to one correspondence with the model.variables() list of variables.
The last two arguments are optional and help debugging a failing constraint due to presolve.
Check that all values fall in the variable domains.
Display a message to help debugging.
Check that the objective is within its domain.
Definition at line 1691 of file cp_model_checker.cc.
CpSolverResponse operations_research::sat::Solve | ( | const CpModelProto & | model_proto | ) |
Solves the given CpModelProto and returns an instance of CpSolverResponse.
Definition at line 2576 of file cp_model_solver.cc.
CpSolverResponse operations_research::sat::SolveCpModel | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Solves the given CpModelProto.
This advanced API accept a Model* which allows to access more advanced features by configuring some classes in the Model before solve.
For instance:
Dump initial model?
Override parameters?
Enable the logging component.
Always display the final response stats if requested. This also copy the logs to the response if requested.
Always add the timing information to a response. Note that it is important to add this after the log/dump postprocessor since we execute them in reverse order.
Validate parameters.
Initialize the time limit from the parameters.
Register SIGINT handler if requested by the parameters.
Internally we adapt the parameters so that things are disabled if they do not make sense.
Validate model_proto.
Presolve and expansions.
Checks for hints early in case they are forced to be hard constraints.
If the hint is complete, we can use the solution checker to do more validation. Note that after the model has been validated, we are sure there are do duplicate variables in the solution hint, so we can just check the size.
If the objective was a floating point one, do some postprocessing on the final response.
Compute the true objective of the best returned solution.
Also copy the scaled objective which must be in the mapping model. This can be useful for some client, like if they want to do multi-objective optimization in stages.
If requested, compute a correct lb from the one on the integer objective. We only do that if some error were introduced by the scaling algorithm.
To avoid small errors that can be confusing, we take the min/max with the objective value.
Check the absolute gap, and display warning if needed.
For the case where the assumptions are currently not supported, we just assume they are fixed, and will always report all of them in the UNSAT core if the problem turn out to be UNSAT.
If the mode is not degraded, we will hopefully report a small subset in case there is no feasible solution under these assumptions.
For now, just pass in all assumptions.
Clear them from the new proto.
Do the actual presolve.
Delete the context as soon a the presolve is done. Note that only postsolve_mapping and mapping_proto are needed for postsolve.
Collect the info we know about new_cp_model_proto bounds.
Intersect with the SharedBoundsManager if it exist.
Postsolve and fill the field.
Solution checking. We either check all solutions, or only the last one. Checking all solution might be expensive if we creates many.
We pass presolve data for more informative message in case the solution is not feasible.
Solution postsolving.
Map back the sufficient assumptions for infeasibility.
Truncate the solution in case model expansion added more variables.
Make sure everything stops when we have a first solution if requested.
If the model is convertible to a MIP, we dump it too.
If the model is convertible to a pure SAT one, we dump it too.
If specified, we load the initial objective domain right away in the response manager. Note that the presolve will always fill it with the trivial min/max value if the user left it empty. This avoids to display [-infinity, infinity] for the initial objective search space.
Start counting the primal integral from the current deterministic time and initial objective domain gap that we just filled.
Re-test a complete solution hint to see if it survived the presolve. If it is feasible, we load it right away.
Tricky: when we enumerate all solutions, we cannot properly exclude the current solution if we didn't find it via full propagation, so we don't load it in this case.
To avoid duplicating code, the single-thread version reuse most of the multi-thread architecture.
Definition at line 2026 of file cp_model_solver.cc.
DiophantineSolution operations_research::sat::SolveDiophantine | ( | absl::Span< const int64_t > | coeffs, |
int64_t | rhs, | ||
absl::Span< const int64_t > | var_lbs, | ||
absl::Span< const int64_t > | var_ubs ) |
x_i's Satisfying sum(x_i * coeffs[pivots[i]]) = current_gcd.
Z-basis of sum(x_i * arg.coeffs(pivots[i])) = 0.
Solves current_gcd * u + coeff * v = new_gcd. Copy the coefficients as the function below modifies them.
To compute the domains, we use the triangular shape of the basis. The first one is special as it is controlled by two columns of the basis. Note that we don't try to compute exact domains as we would need to multiply then making the number of interval explode. For i = 0, ..., replaced_variable_count - 1, uses identities x[i] = special_solution[i]
Identities 0 and 1 both bound the first element of the basis.
Definition at line 119 of file diophantine.cc.
bool operations_research::sat::SolveDiophantineEquationOfSizeTwo | ( | int64_t & | a, |
int64_t & | b, | ||
int64_t & | cte, | ||
int64_t & | x0, | ||
int64_t & | y0 ) |
Returns true if the equation a * X + b * Y = cte has some integer solutions. For now, we check that a and b are different from 0 and from int64_t min.
There is actually always a solution if cte % gcd(a
, b
) == 0. And because a, b and cte fit on an int64_t, if there is a solution, there is one with X and Y fitting on an int64_t.
We will divide everything by gcd(a, b) first, so it is why we take reference and the equation can change.
If there are solutions, we return one of them (x0, y0). From any such solution, the set of all solutions is given for Z integer by: X = x0 + b * Z; Y = y0 - a * Z;
Given a domain for X and Y, it is possible to compute the "exact" domain of Z with our Domain functions. Note however that this will only compute solution where both x-x0 and y-y0 do fit on an int64_t: DomainOf(x).SubtractionWith(x0).InverseMultiplicationBy(b).IntersectionWith( DomainOf(y).SubtractionWith(y0).InverseMultiplicationBy(-a))
The simple case where (0, 0) is a solution.
We solve a * X + b * Y = cte We take a valid x0 in [0, b) by considering the equation mod b.
We choose x0 of the same sign as cte.
By plugging X = x0 + b * Z We have a * (x0 + b * Z) + b * Y = cte so a * b * Z + b * Y = cte - a * x0; and y0 = (cte - a * x0) / b (with an exact division by construction).
Overflow-wise, there is two cases for cte > 0:
void operations_research::sat::SolveFzWithCpModelProto | ( | const fz::Model & | fz_model, |
const fz::FlatzincSatParameters & | p, | ||
const std::string & | sat_params, | ||
SolverLogger * | logger, | ||
SolverLogger * | solution_logger ) |
The translation is easy, we create one variable per flatzinc variable, plus eventually a bunch of constant variables that will be created lazily.
The CP-SAT solver checks that constraints cannot overflow during their propagation. Because of that, we trim undefined variable domains (i.e. int in minizinc) to something hopefully large enough.
Translate the constraints.
Fill the objective.
Fill the search order.
Enumerate all sat solutions.
Helps with challenge unit tests.
Computes the number of workers.
We don't support enumerating all solution in parallel for a SAT problem. But note that we do support it for an optimization problem since the meaning of p.all_solutions is not the same in this case.
Specifies single thread specific search modes.
Time limit.
The order is important, we want the flag parameters to overwrite anything set in m.parameters.
We only need an observer if 'p.display_all_solutions' or 'p.search_all_solutions' are true.
Setup logging.
Check the returned solution with the fz model checker.
Output the solution in the flatzinc official format.
Already printed otherwise.
Definition at line 1280 of file cp_model_fz_solver.cc.
SatSolver::Status operations_research::sat::SolveIntegerProblemWithLazyEncoding | ( | Model * | model | ) |
Only used in tests. Move to a test utility file.
This configures the model SearchHeuristics with a simple default heuristic and then call ResetAndSolveIntegerProblem() without any assumptions.
Definition at line 1584 of file integer_search.cc.
void operations_research::sat::SolveLoadedCpModel | ( | const CpModelProto & | model_proto, |
Model * | model ) |
Solves an already loaded cp_model_proto. The final CpSolverResponse must be read from the shared_response_manager.
Solves an already loaded cp_model_proto. The final CpSolverResponse must be read from the shared_response_manager.
Make sure we are not at a positive level.
Reconfigure search heuristic if it was changed.
Extract a good subset of assumptions and add it to the response.
Optimization problem.
The search is done in both case.
Definition at line 1322 of file cp_model_solver_helpers.cc.
CpSolverResponse operations_research::sat::SolveWithParameters | ( | const CpModelProto & | model_proto, |
const SatParameters & | params ) |
Solves the given CpModelProto with the given parameters.
Definition at line 2581 of file cp_model_solver.cc.
CpSolverResponse operations_research::sat::SolveWithParameters | ( | const CpModelProto & | model_proto, |
const std::string & | params ) |
Solves the given CpModelProto with the given sat parameters as string in JSon format, and returns an instance of CpSolverResponse.
Definition at line 2589 of file cp_model_solver.cc.
void operations_research::sat::SplitAndLoadIntermediateConstraints | ( | bool | lb_required, |
bool | ub_required, | ||
std::vector< IntegerVariable > * | vars, | ||
std::vector< int64_t > * | coeffs, | ||
Model * | m ) |
Part of LoadLinearConstraint() that we reuse to load the objective.
We split large constraints into a square root number of parts. This is to avoid a bad complexity while propagating them since our algorithm is not in O(num_changes).
If we enumerate all solutions, then we want intermediate variables to be tight independently of what side is required.
Everything should be exactly divisible!
We have sum bucket_var >= lb, so we need local_vars >= bucket_var.
Similarly, bucket_var <= ub, so we need local_vars <= bucket_var
Definition at line 1149 of file cp_model_loader.cc.
IntegerLiteral operations_research::sat::SplitAroundGivenValue | ( | IntegerVariable | var, |
IntegerValue | value, | ||
Model * | model ) |
This method first tries var <= value. If this does not reduce the domain it tries var >= value. If that also does not reduce the domain then returns an invalid literal.
Heuristic: Prefer the objective direction first. Reference: Conflict-Driven Heuristics for Mixed Integer Programming (2019) by Jakob Witzig and Ambros Gleixner.
Definition at line 87 of file integer_search.cc.
IntegerLiteral operations_research::sat::SplitAroundLpValue | ( | IntegerVariable | var, |
Model * | model ) |
Returns decision corresponding to var <= round(lp_value). If the variable does not appear in the LP, this method returns an invalid literal.
We only use this if the sub-lp has a solution, and depending on the value of exploit_all_lp_solution() if it is a pure-integer solution.
Because our lp solution might be from higher up in the tree, it is possible that value is now outside the domain of positive_var. In this case, this function will return an invalid literal.
Definition at line 115 of file integer_search.cc.
IntegerLiteral operations_research::sat::SplitDomainUsingBestSolutionValue | ( | IntegerVariable | var, |
Model * | model ) |
Returns decision corresponding to var <= best_solution[var]. If no solution has been found, this method returns a literal with kNoIntegerVariable. This was suggested in paper: "Solution-Based Phase Saving for CP" (2018) by Emir Demirovic, Geoffrey Chu, and Peter J. Stuckey.
IntegerLiteral operations_research::sat::SplitUsingBestSolutionValueInRepository | ( | IntegerVariable | var, |
const SharedSolutionRepository< int64_t > & | solution_repo, | ||
Model * | model ) |
Definition at line 144 of file integer_search.cc.
void operations_research::sat::StoreAssignment | ( | const VariablesAssignment & | assignment, |
BooleanAssignment * | output ) |
Store a variable assignment into the given BooleanAssignment proto.
Definition at line 488 of file boolean_problem.cc.
bool operations_research::sat::SubstituteVariable | ( | int | var, |
int64_t | var_coeff_in_definition, | ||
const ConstraintProto & | definition, | ||
ConstraintProto * | ct ) |
Replaces the variable var in ct using the definition constraint. Currently the coefficient in the definition must be 1 or -1.
This might return false and NOT modify ConstraintProto in case of overflow or other issue with the substitution.
Get the coefficient of var in the constraint. We assume positive reference here (it should always be the case now). If we don't find var, we abort.
If var appear multiple time, we add all its coefficients.
Definition at line 233 of file presolve_util.cc.
|
inline |
Returns the ith element of the strategy S^univ proposed by M. Luby et al. in Optimal Speedup of Las Vegas Algorithms, Information Processing Letters 1993. This is used to decide the number of conflicts allowed before the next restart. This method, used by most SAT solvers, is usually referenced as Luby. Returns 2^{k-1} when i == 2^k - 1 and SUniv(i - 2^{k-1} + 1) when 2^{k-1} <= i < 2^k - 1. The sequence is defined for i > 0 and starts with: {1, 1, 2, 1, 1, 2, 4, 1, 1, 2, 1, 1, 2, 4, 8, ...}
void operations_research::sat::SymmetrizeArcs | ( | std::vector< ArcWithLpValue > * | arcs | ) |
Regroups and sum the lp values on duplicate arcs or reversed arcs (tail->head) and (head->tail). As a side effect, we will always have tail <= head.
Definition at line 549 of file routing_cuts.cc.
|
inline |
|
inline |
Model based functions.
Definition at line 116 of file cp_constraints.h.
|
inline |
Given the generators for a permutation group of [0, n-1], update it to a set of generators of the group stabilizing the given element.
This is more or less what is described in "Symmetry Breaking Inequalities from the Schreier-Sims Table", Domenico Salvagnin, https://link.springer.com/chapter/10.1007/978-3-319-93031-2_37
Definition at line 79 of file symmetry_util.h.
void operations_research::sat::TryToLinearizeConstraint | ( | const CpModelProto & | , |
const ConstraintProto & | ct, | ||
int | linearization_level, | ||
Model * | model, | ||
LinearRelaxation * | relaxation, | ||
ActivityBoundHelper * | activity_helper ) |
Adds linearization of different types of constraints.
Add a static and a dynamic linear relaxation of the CP constraint to the set of linear constraints. The highest linearization_level is, the more types of constraint we encode. This method should be called only for linearization_level > 0. The static part is just called a relaxation and is called at the root node of the search. The dynamic part is implemented through a set of linear cut generators that will be called throughout the search.
(user): In full generality, we could encode all the constraint as an LP.
(user): Add unit tests for this method.
(user): Remove and merge with model loading.
No relaxation, just a cut generator .
Add cut generators.
Adds an energetic relaxation (sum of areas fits in bounding box).
Adds a completion time cut generator and an energetic cut generator.
Definition at line 1317 of file linear_relaxation.cc.
std::vector< LiteralValueValue > operations_research::sat::TryToReconcileEncodings | ( | const AffineExpression & | size2_affine, |
const AffineExpression & | affine, | ||
absl::Span< const ValueLiteralPair > | affine_var_encoding, | ||
bool | put_affine_left_in_result, | ||
IntegerEncoder * | integer_encoder ) |
If a variable has a size of 2, it is most likely reduced to an affine expression pointing to a variable with domain [0,1] or [-1,0]. If the original variable has been removed from the model, then there are no implied values from any exactly_one constraint to its domain. If we are lucky, one of the literal of the exactly_one constraints, and its negation are used to encode the Boolean variable of the affine.
This may fail if exactly_one(l0, l1, l2, l3); l0 and l1 imply x = 0, l2 and l3 imply x = 1. In that case, one must look at the binary implications to find the missing link.
Build the decomposition.
Definition at line 257 of file implied_bounds.cc.
std::vector< LiteralValueValue > operations_research::sat::TryToReconcileSize2Encodings | ( | const AffineExpression & | left, |
const AffineExpression & | right, | ||
IntegerEncoder * | integer_encoder ) |
Specialized case of encoding reconciliation when both variables have a domain of size of 2.
Definition at line 301 of file implied_bounds.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::UnassignedVarWithLowestMinAtItsMinHeuristic | ( | const std::vector< IntegerVariable > & | vars, |
Model * | model ) |
Decision heuristic for SolveIntegerProblemWithLazyEncoding(). Like FirstUnassignedVarAtItsMinHeuristic() but the function will return the literal corresponding to the fact that the currently non-assigned variable with the lowest min has a value <= this min.
Definition at line 271 of file integer_search.cc.
|
inline |
Removes the objective scaling and offset from the given value.
Definition at line 183 of file cp_model_utils.h.
|
inline |
std::vector< int > operations_research::sat::UsedIntervals | ( | const ConstraintProto & | ct | ) |
Returns the sorted list of interval used by a constraint.
Definition at line 496 of file cp_model_utils.cc.
std::vector< int > operations_research::sat::UsedVariables | ( | const ConstraintProto & | ct | ) |
Returns the sorted list of variables used by a constraint.
Definition at line 483 of file cp_model_utils.cc.
void operations_research::sat::UseObjectiveForSatAssignmentPreference | ( | const LinearBooleanProblem & | problem, |
SatSolver * | solver ) |
Uses the objective coefficient to drive the SAT search towards an heuristically better solution.
Because this is a minimization problem, we prefer to assign a Boolean variable to its "low" objective value. So if a literal has a positive weight when true, we want to set it to false.
Definition at line 320 of file boolean_problem.cc.
absl::Status operations_research::sat::ValidateBooleanProblem | ( | const LinearBooleanProblem & | problem | ) |
Tests the preconditions of the given problem (as described in the proto) and returns an error if they are not all satisfied.
Definition at line 144 of file boolean_problem.cc.
std::string operations_research::sat::ValidateCpModel | ( | const CpModelProto & | model, |
bool | after_presolve = false ) |
Verifies that the given model satisfies all the properties described in the proto comments. Returns an empty string if it is the case, otherwise fails at the first error and returns a human-readable description of the issue.
The extra parameter is internal and mainly for debugging. After the problem has been presolved, we have a stricter set of properties we want to enforce.
We require this precondition so that we can take any linear combination of variable with coefficient in int64_t and compute the activity on an int128 with no overflow. This is useful during cut computation.
We need to validate the intervals used first, so we add these constraints here so that we can validate them in a second pass.
By default, a constraint does not support enforcement literals except if explicitly stated by setting this to true below.
Other non-generic validations.
Because some client set fixed enforcement literal which are supported in the presolve for all constraints, we just check that there is no non-fixed enforcement.
Extra validation for constraint using intervals.
If any of these fields are set, the domain must be set.
Check that we can transform any value in the objective domain without overflow. We only check the bounds which is enough.
Definition at line 927 of file cp_model_checker.cc.
std::string operations_research::sat::ValidateInputCpModel | ( | const SatParameters & | params, |
const CpModelProto & | model ) |
Some validation (in particular the floating point objective) requires to read parameters.
Definition at line 1130 of file cp_model_checker.cc.
bool operations_research::sat::ValidateLinearConstraintForOverflow | ( | const LinearConstraint & | constraint, |
const IntegerTrail & | integer_trail ) |
Makes sure that any of our future computation on this constraint will not cause overflow. We use the level zero bounds and use the same definition as in PossibleIntegerOverflow() in the cp_model.proto checker.
Namely, the sum of positive terms, the sum of negative terms and their difference shouldn't overflow. Note that we don't validate the rhs, but if the bounds are properly relaxed, then this shouldn't cause any issues.
Note(user): We should avoid doing this test too often as it can be slow. At least do not do it more than once on each constraint.
Definition at line 397 of file linear_constraint.cc.
std::string operations_research::sat::ValidateParameters | ( | const SatParameters & | params | ) |
Verifies that the given parameters are correct. Returns an empty string if it is the case, or an human-readable error message otherwise.
Test that all floating point parameters are not NaN or +/- infinity.
Parallelism.
Feasibility jump.
Violation ls.
Test LP tolerances.
Definition at line 56 of file parameters_validation.cc.
|
inline |
This checks that the variable is fixed.
Definition at line 1026 of file sat_solver.h.
|
inline |
This checks that the variable is fixed.
Definition at line 1017 of file sat_solver.h.
std::string operations_research::sat::VarDebugString | ( | const CpModelProto & | proto, |
int | index ) |
Returns a more readable and compact DebugString() than proto.variables(index).DebugString(). This is used by IntVar::DebugString() but also allow to get the same string from a const proto.
Special case for constant variables without names.
Definition at line 143 of file cp_model.cc.
|
inline |
int operations_research::sat::WeightedPick | ( | absl::Span< const double > | input, |
absl::BitGenRef | random ) |
|
inline |
Weighted sum >= constant.
We just negate everything and use an <= constraints.
Definition at line 447 of file integer_expr.h.
|
inline |
bool operations_research::sat::WriteModelProtoToFile | ( | const M & | proto, |
absl::string_view | filename ) |
Definition at line 290 of file cp_model_utils.h.
Definition at line 100 of file diophantine.h.
for operations_research::sat::i = 0 ... k-2 |
Gives a parametric description of the solutions of the Diophantine equation with n variables: sum(coeffs[i] * x[i]) = rhs. var_lbs and var_ubs are bounds on desired values for variables x_i's.
It is known that, ignoring variable bounds, the set of solutions of such an equation is
The kernel of the equation as dimension n-1.
We assume we permute the variable by index_permutation, such that the first k k terms have a gcd equal to the gcd of all coefficient (it is possible to do this with k <= 15). Under this assumption, we can find:
Definition at line 100 of file diophantine.h.
|
constexpr |
Definition at line 49 of file presolve_context.h.
|
constexpr |
Definition at line 50 of file presolve_context.h.
|
constexpr |
Default seed for fingerprints.
Definition at line 245 of file cp_model_utils.h.
|
staticconstexpr |
Definition at line 35 of file 2d_packing_brute_force.cc.
|
constexpr |
We use some special constraint index in our variable <-> constraint graph.
Definition at line 48 of file presolve_context.h.
|
constexpr |
This method tries to compress a list of tuples by merging complementary tuples, that is a set of tuples that only differ on one variable, and that cover the domain of the variable. In that case, it will keep only one tuple, and replace the value for variable by any_value, the equivalent of '*' in regexps.
This method is exposed for testing purposes.
const int operations_research::sat::kUnsatTrailIndex = -1 |
A constant used by the EnqueueDecision*() API.
Definition at line 58 of file sat_solver.h.