![]() |
Google OR-Tools v9.12
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> |
typedef double | Fractional |
typedef double | Fractional |
typedef double | Fractional |
Enumerations | |
enum | EdgePosition { TOP = 0 , RIGHT = 1 , BOTTOM = 2 , LEFT = 3 } |
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 } |
enum | IntegerVariablesToAddMask { kStart = 1 << 0 , kEnd = 1 << 1 , kSize = 1 << 2 , kPresence = 1 << 3 } |
Cuts helpers. More... | |
enum class | ConstraintStatus |
Functions | |
void | ProcessFloatingPointOVariablesAndObjective (fz::Model *fz_model) |
void | SolveFzWithCpModelProto (const fz::Model &model, const fz::FlatzincSatParameters &p, const std::string &sat_params, SolverLogger *logger, SolverLogger *solution_logger) |
Solves the given flatzinc model using the CP-SAT solver. | |
void | CreateAndRegisterMandatoryOverlapPropagator (NoOverlap2DConstraintHelper *helper, Model *model, GenericLiteralWatcher *watcher, int priority) |
std::vector< Rectangle > | GenerateNonConflictingRectangles (int num_rectangles, absl::BitGenRef random) |
std::vector< Rectangle > | GenerateNonConflictingRectanglesWithPacking (std::pair< IntegerValue, IntegerValue > bb, int average_num_boxes, absl::BitGenRef random) |
std::vector< RectangleInRange > | MakeItemsFromRectangles (absl::Span< const Rectangle > rectangles, double slack_factor, absl::BitGenRef random) |
std::vector< ItemWithVariableSize > | GenerateItemsRectanglesWithNoPairwiseConflict (absl::Span< const Rectangle > rectangles, double slack_factor, absl::BitGenRef random) |
std::vector< ItemWithVariableSize > | 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 | ReduceNumberofBoxesGreedy (std::vector< Rectangle > *mandatory_rectangles, std::vector< Rectangle > *optional_rectangles) |
Neighbours | BuildNeighboursGraph (absl::Span< const Rectangle > rectangles) |
std::vector< std::vector< int > > | SplitInConnectedComponents (const Neighbours &neighbours) |
std::vector< SingleShape > | BoxesToShapes (absl::Span< const Rectangle > rectangles, const Neighbours &neighbours) |
std::vector< Rectangle > | CutShapeIntoRectangles (SingleShape shape) |
bool | ReduceNumberOfBoxesExactMandatory (std::vector< Rectangle > *mandatory_rectangles, std::vector< Rectangle > *optional_rectangles) |
Disjoint2dPackingResult | DetectDisjointRegionIn2dPacking (absl::Span< const RectangleInRange > non_fixed_boxes, absl::Span< const Rectangle > fixed_boxes, int max_num_components) |
template<typename Sink> | |
void | AbslStringify (Sink &sink, EdgePosition e) |
void | CreateAndRegisterTryEdgePropagator (NoOverlap2DConstraintHelper *helper, Model *model, GenericLiteralWatcher *watcher, int priority) |
std::function< void(Model *)> | AllDifferentBinary (absl::Span< const IntegerVariable > vars) |
std::function< void(Model *)> | AllDifferentOnBounds (const std::vector< AffineExpression > &expressions) |
std::function< void(Model *)> | AllDifferentOnBounds (absl::Span< const IntegerVariable > vars) |
std::function< void(Model *)> | AllDifferentAC (absl::Span< const 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. | |
void | SolveCpModelWithParameters (const void *creq, int creq_len, const void *cparams, int cparams_len, void **cres, int *cres_len) |
void * | SolveCpNewAtomicBool () |
void | SolveCpDestroyAtomicBool (void *const atomic_bool) |
void | SolveCpStopSolve (void *const atomic_bool) |
void | SolveCpInterruptible (void *const limit_reached, const void *creq, int creq_len, const void *cparams, int cparams_len, void **cres, int *cres_len) |
std::function< void(Model *)> | ExactlyOnePerRowAndPerColumn (absl::Span< const std::vector< Literal > > graph) |
void | LoadSubcircuitConstraint (int num_nodes, absl::Span< const int > tails, absl::Span< const int > heads, absl::Span< const Literal > literals, Model *model, bool multiple_subcircuit_through_zero) |
std::function< void(Model *)> | CircuitCovering (absl::Span< const std::vector< Literal > > graph, absl::Span< const int > distinguished_nodes) |
template<class IntContainer> | |
int | ReindexArcs (IntContainer *tails, IntContainer *heads, absl::flat_hash_map< int, int > *mapping_output=nullptr) |
bool | TrySolution (const CpModelProto &model, absl::Span< const int64_t > solution, absl::Span< const int64_t > new_solution, absl::Span< const int64_t > base_solution, std::vector< int64_t > *new_combined_solution) |
std::optional< std::vector< int64_t > > | FindCombinedSolution (const CpModelProto &model, absl::Span< const int64_t > new_solution, absl::Span< const int64_t > base_solution, const SharedResponseManager *response_manager, std::string *solution_info) |
PushedSolutionPointers | PushAndMaybeCombineSolution (SharedResponseManager *response_manager, const CpModelProto &model_proto, absl::Span< const int64_t > new_solution, const std::string &solution_info, absl::Span< const int64_t > base_solution, Model *model) |
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 (absl::Span< const 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, absl::Span< const IntegerVariable > vars, absl::Span< const 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) |
bool | ImportModelWithBasicPresolveIntoContext (const CpModelProto &in_model, PresolveContext *context) |
bool | ImportModelAndDomainsWithBasicPresolveIntoContext (const CpModelProto &in_model, absl::Span< const 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. | |
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) |
void | PostsolveIntMod (const ConstraintProto &ct, std::vector< Domain > *domains) |
We only support assigning to an affine target. | |
void | PostsolveIntProd (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, absl::Span< const int > postsolve_mapping, std::vector< int64_t > *solution) |
void | FillTightenedDomainInResponse (const CpModelProto &original_model, const CpModelProto &mapping_proto, absl::Span< const int > postsolve_mapping, absl::Span< const Domain > search_domains, CpSolverResponse *response, SolverLogger *logger) |
Domain | EvaluateImpliedIntProdDomain (const LinearArgumentProto &expr, const PresolveContext &context) |
CpSolverStatus | PresolveCpModel (PresolveContext *context, std::vector< int > *postsolve_mapping) |
Convenient wrapper to call the full presolve. | |
void | ApplyVariableMapping (absl::Span< int > mapping, std::vector< int > *reverse_mapping, CpModelProto *proto) |
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 (absl::Span< const 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, absl::Span< const 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) |
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, absl::Span< const int > postsolve_mapping, std::vector< int64_t > *solution) |
void | PostsolveResponseWrapper (const SatParameters ¶ms, int num_variable_in_original_model, const CpModelProto &mapping_proto, absl::Span< const 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) |
bool | FilterOrbitOnUnusedOrFixedVariables (SymmetryProto *symmetry, PresolveContext *context) |
void | CanonicalizeTable (PresolveContext *context, ConstraintProto *ct) |
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) |
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. | |
CpModelProto | Random3SatProblem (int num_variables, double proportion_of_constraints) |
CpModelProto | RandomLinearProblem (int num_variables, int num_constraints) |
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) |
void | AddWeightedLiteralToLinearConstraint (int lit, int64_t coeff, LinearConstraintProto *linear, int64_t *offset) |
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) |
void | InsertVariablesFromInterval (const CpModelProto &model_proto, int index, Bitset64< int > &output) |
Insert/Remove variables from an interval constraint into a bitset. | |
void | RemoveVariablesFromInterval (const CpModelProto &model_proto, int index, Bitset64< int > &output) |
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. | |
int64_t | AffineExpressionValueAt (const LinearExpressionProto &expr, int64_t value) |
Evaluates an affine expression at the given value. | |
int64_t | GetInnerVarValue (const LinearExpressionProto &expr, int64_t value) |
bool | AffineExpressionContainsVar (const LinearExpressionProto &expr, int var) |
Returns true if the expression is a * var + b. | |
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, absl::Span< const AffineExpression > demands, AffineExpression capacity, SchedulingConstraintHelper *helper) |
std::function< void(Model *)> | CumulativeTimeDecomposition (absl::Span< const IntervalVariable > vars, absl::Span< const AffineExpression > demands, AffineExpression capacity, SchedulingConstraintHelper *helper) |
std::function< void(Model *)> | CumulativeUsingReservoir (absl::Span< const IntervalVariable > vars, absl::Span< const 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 (absl::Span< const AffineExpression > exprs, Model *model) |
CutGenerator | CreateLinMaxCutGenerator (const IntegerVariable target, absl::Span< const LinearExpression > exprs, absl::Span< const IntegerVariable > z_vars, Model *model) |
bool | BuildMaxAffineUpConstraint (const LinearExpression &target, IntegerVariable var, absl::Span< const 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 (absl::Span< const 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< const int > rectangles, absl::string_view cut_name, Model *model, LinearConstraintManager *manager, SchedulingConstraintHelper *x_helper, SchedulingConstraintHelper *y_helper, SchedulingDemandHelper *y_demands_helper) |
CutGenerator | CreateNoOverlap2dEnergyCutGenerator (NoOverlap2DConstraintHelper *helper, Model *model) |
CutGenerator | CreateNoOverlap2dCompletionTimeCutGenerator (NoOverlap2DConstraintHelper *helper, Model *model) |
CompactVectorVector< int > | GetOverlappingRectangleComponents (absl::Span< const Rectangle > rectangles) |
bool | ReportEnergyConflict (Rectangle bounding_box, absl::Span< const int > boxes, SchedulingConstraintHelper *x, SchedulingConstraintHelper *y) |
bool | BoxesAreInEnergyConflict (absl::Span< const Rectangle > rectangles, absl::Span< const 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) |
void | ConstructOverlappingSets (absl::Span< IndexedInterval > intervals, CompactVectorVector< int > *result, absl::Span< const int > order) |
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 ItemWithVariableSize > items, std::vector< PairwiseRestriction > *result) |
void | AppendPairwiseRestrictions (absl::Span< const ItemWithVariableSize > items, absl::Span< const ItemWithVariableSize > 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::string_view extra_dot_payload) |
std::vector< Rectangle > | FindEmptySpaces (const Rectangle &bounding_box, std::vector< Rectangle > ocupied_rectangles) |
std::vector< Rectangle > | PavedRegionDifference (std::vector< Rectangle > original_region, absl::Span< const Rectangle > area_to_remove) |
std::vector< std::pair< int, int > > | FindPartialRectangleIntersectionsImpl (absl::Span< const Rectangle32 > rectangles, int32_t y_max) |
std::vector< std::pair< int, int > > | FindPartialRectangleIntersections (absl::Span< const Rectangle > rectangles) |
std::optional< std::pair< int, int > > | FindOneIntersectionIfPresent (absl::Span< const Rectangle > rectangles) |
std::optional< std::pair< int, int > > | FindOneIntersectionIfPresentWithZeroArea (absl::Span< const Rectangle > rectangles) |
double | CenterToCenterL2Distance (const Rectangle &a, const Rectangle &b) |
Returns the L2 distance between the centers of the two rectangles. | |
double | CenterToCenterLInfinityDistance (const Rectangle &a, const Rectangle &b) |
bool | RegionIncludesOther (absl::Span< const Rectangle > region, absl::Span< const Rectangle > other) |
The two regions must be defined by non-overlapping 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 (absl::Span< const 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, absl::Span< const 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. | |
template<typename Storage> | |
SubsetsDetector (const Storage &storage) -> SubsetsDetector< Storage > | |
std::pair< uint64_t, int > | ComputeSignatureAndMaxElement (absl::Span< const int > elements) |
std::vector< IntegerVariable > | NegationOf (absl::Span< const IntegerVariable > vars) |
Returns the vector of the negated variables. | |
std::ostream & | operator<< (std::ostream &os, const ValueLiteralPair &p) |
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) |
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. | |
bool | AddSquareTo (IntegerValue a, IntegerValue *result) |
Computes result += a * a, 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) |
DEFINE_STRONG_INDEX_TYPE (IntervalVariable) | |
const IntervalVariable | kNoIntervalVariable (-1) |
template<typename VectorInt> | |
std::function< void(Model *)> | WeightedSumLowerOrEqual (absl::Span< const IntegerVariable > vars, const VectorInt &coefficients, int64_t upper_bound) |
Weighted sum <= constant. | |
template<typename VectorInt> | |
std::function< void(Model *)> | WeightedSumGreaterOrEqual (absl::Span< const IntegerVariable > vars, const VectorInt &coefficients, int64_t lower_bound) |
Weighted sum >= constant. | |
template<typename VectorInt> | |
std::function< void(Model *)> | FixedWeightedSum (absl::Span< const 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 (absl::Span< const Literal > enforcement_literals, absl::Span< const IntegerVariable > vars, absl::Span< const int64_t > coefficients, int64_t upper_bound) |
std::function< void(Model *)> | ConditionalWeightedSumGreaterOrEqual (absl::Span< const Literal > enforcement_literals, absl::Span< const IntegerVariable > vars, absl::Span< const 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) |
void | AddIsEqualToMinOf (const LinearExpression &min_expr, std::vector< LinearExpression > exprs, Model *model) |
std::function< void(Model *)> | IsEqualToMinOf (const LinearExpression &min_expr, const std::vector< LinearExpression > &exprs) |
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, IntegerTrail *integer_trail, ObjectiveDefinition *objective_definition) |
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 (absl::Span< const 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 (absl::Span< const 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 (absl::Span< const BooleanOrIntegerVariable > vars, absl::Span< const 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) |
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) |
void | AppendVariablesFromCapacityAndDemands (const AffineExpression &capacity, SchedulingDemandHelper *demands_helper, Model *model, std::vector< IntegerVariable > *vars) |
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) |
bool | MergePositiveVariableTermsAndCheckForOverflow (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 (absl::Span< const IntervalVariable > intervals, absl::Span< const 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 | AppendNoOverlap2dRelaxationForComponent (absl::Span< const int > component, Model *model, NoOverlap2DConstraintHelper *no_overlap_helper, LinearConstraintManager *manager, ProductDecomposer *product_decomposer) |
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, absl::Span< const Literal > alternative_literals, absl::Span< const 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 (absl::Span< const 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, absl::Span< const 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 | ScaleFloatingPointObjective (const SatParameters ¶ms, SolverLogger *logger, CpModelProto *proto) |
bool | LoadModelForProbing (PresolveContext *context, Model *local_model) |
bool | LoadModelForPresolve (const CpModelProto &model_proto, SatParameters params, PresolveContext *context, Model *local_model, absl::string_view name_for_logging) |
template<typename ProtoWithVarsAndCoeffs, typename PresolveContextT> | |
bool | CanonicalizeLinearExpressionInternal (absl::Span< const int > enforcements, ProtoWithVarsAndCoeffs *proto, int64_t *offset, std::vector< std::pair< int, int64_t > > *tmp_terms, PresolveContextT *context) |
void | CreateValidModelWithSingleConstraint (const ConstraintProto &ct, const PresolveContext *context, std::vector< int > *variable_mapping, CpModelProto *mini_model) |
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, absl::Span< const std::pair< int, int > > arcs, int stop_at_num_components, std::vector< int > *subset_data, std::vector< absl::Span< const int > > *subsets) |
void | ExtractAllSubsetsFromForest (absl::Span< const int > parent, std::vector< int > *subset_data, std::vector< absl::Span< const int > > *subsets, int node_limit) |
std::vector< int > | ComputeGomoryHuTree (int num_nodes, absl::Span< const ArcWithLpValue > relevant_arcs) |
void | SymmetrizeArcs (std::vector< ArcWithLpValue > *arcs) |
void | SeparateSubtourInequalities (OutgoingCutHelper &helper, LinearConstraintManager *manager) |
CutGenerator | CreateStronglyConnectedGraphCutGenerator (int num_nodes, absl::Span< const int > tails, absl::Span< const int > heads, absl::Span< const Literal > literals, Model *model) |
CutGenerator | CreateCVRPCutGenerator (int num_nodes, absl::Span< const int > tails, absl::Span< const int > heads, absl::Span< const Literal > literals, absl::Span< const 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, absl::Span< const Literal > literals) |
std::function< void(Model *)> | ExactlyOneConstraint (absl::Span< const Literal > literals) |
std::function< void(Model *)> | AtMostOneConstraint (absl::Span< const 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 (absl::Span< const 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 (absl::Span< const 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 (absl::string_view 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) |
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 (const SchedulingConstraintHelper *helper, Model *model, std::vector< IntegerVariable > *vars, int mask) |
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, ModelSharedTimeLimit *time_limit) |
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 | GetSchreierVectorAndOrbit (int point, absl::Span< const std::unique_ptr< SparsePermutation > > generators, std::vector< int > *schrier_vector, std::vector< int > *orbit) |
std::vector< int > | TracePoint (int point, absl::Span< const int > schrier_vector, absl::Span< const std::unique_ptr< SparsePermutation > > generators) |
std::unique_ptr< SparsePermutation > | CreateSparsePermutationFromProto (int n, const SparsePermutationProto &proto) |
Creates a SparsePermutation on [0, n) from its proto representation. | |
void | TransformToGeneratorOfStabilizer (int to_stabilize, std::vector< std::unique_ptr< SparsePermutation > > *generators) |
std::string | ExtractSubSolverName (const std::string &improvement_info) |
std::function< void(Model *)> | LiteralTableConstraint (absl::Span< const std::vector< Literal > > literal_tuples, absl::Span< const 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) |
bool | DiophantineEquationOfSizeTwoHasSolutionInDomain (const Domain &x, int64_t a, const Domain &y, int64_t b, int64_t cte) |
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) |
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. | |
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) |
constexpr IntegerValue | kMaxIntegerValue (std::numeric_limits< IntegerValue::ValueType >::max() - 1) |
constexpr IntegerValue | kMinIntegerValue (-kMaxIntegerValue.value()) |
std::function< SatParameters(Model *)> | NewSatParameters (const std::string ¶ms) |
template<class Graph> | |
std::unique_ptr< Graph > | RemapGraph (const Graph &graph, absl::Span< const int > new_node_index) |
Variables | |
static constexpr int | kMaxProblemSize = 16 |
constexpr int64_t | kTableAnyValue = std::numeric_limits<int64_t>::min() |
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 double | kInfinity |
Infinity for type Fractional. | |
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.
Solution Feasibility.
At the end of presolve, the mapping model is initialized to contains all the variable from the original model + the one created during presolve expand. It also contains the tightened domains.
typedef double operations_research::glop::Fractional |
The type Fractional denotes the type of numbers on which the computations are performed. This is defined as double here, but it could as well be float, DoubleDouble, QuadDouble, or infinite-precision rationals. Floating-point representations are binary fractional numbers, thus the name. (See http://en.wikipedia.org/wiki/Fraction_(mathematics) .)
Definition at line 81 of file lp_types.h.
typedef double operations_research::glop::Fractional |
The type Fractional denotes the type of numbers on which the computations are performed. This is defined as double here, but it could as well be float, DoubleDouble, QuadDouble, or infinite-precision rationals. Floating-point representations are binary fractional numbers, thus the name. (See http://en.wikipedia.org/wiki/Fraction_(mathematics) .)
Definition at line 81 of file lp_types.h.
typedef double operations_research::glop::Fractional |
The type Fractional denotes the type of numbers on which the computations are performed. This is defined as double here, but it could as well be float, DoubleDouble, QuadDouble, or infinite-precision rationals. Floating-point representations are binary fractional numbers, thus the name. (See http://en.wikipedia.org/wiki/Fraction_(mathematics) .)
Definition at line 81 of file lp_types.h.
using operations_research::sat::InlinedIntegerLiteralVector = absl::InlinedVector<IntegerLiteral, 2> |
using operations_research::sat::IntegerSumLE = LinearConstraintPropagator<false> |
Definition at line 163 of file integer_expr.h.
Definition at line 164 of file integer_expr.h.
|
strong |
Different constraints statuses. The meaning is the same for the constraint activity relative to its bounds as it is for a variable value relative to its bounds. Actually, this is the VariableStatus of the slack variable associated to a constraint modulo a change of sign. The difference is that because of precision error, a constraint activity cannot exactly be equal to one of its bounds or to zero.
Definition at line 234 of file lp_types.h.
Enumerator | |
---|---|
TOP | |
RIGHT | |
BOTTOM | |
LEFT |
Definition at line 129 of file 2d_rectangle_presolve.h.
|
strong |
An enforced constraint can be in one of these 4 states.
Definition at line 51 of file linear_propagation.h.
Cuts helpers.
Enumerator | |
---|---|
kStart | |
kEnd | |
kSize | |
kPresence |
Definition at line 788 of file scheduling_helpers.h.
The file formats that can be used to save a list of clauses.
Enumerator | |
---|---|
DIMACS | |
DRAT |
Definition at line 333 of file drat_checker.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const AffineExpression & | e ) |
Definition at line 328 of file integer_base.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const BoolArgumentProto & | m ) |
Definition at line 365 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 387 of file cp_model_utils.h.
H operations_research::sat::AbslHashValue | ( | H | h, |
const LiteralWithCoeff & | term ) |
Definition at line 64 of file pb_constraint.h.
void operations_research::sat::AbslStringify | ( | Sink & | sink, |
EdgePosition | e ) |
Definition at line 132 of file 2d_rectangle_presolve.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 1880 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 1607 of file linear_relaxation.cc.
void operations_research::sat::AddCircuitCutGenerator | ( | const ConstraintProto & | ct, |
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Definition at line 581 of file linear_relaxation.cc.
void operations_research::sat::AddCircuitFlowConstraints | ( | LinearIncrementalEvaluator & | linear_evaluator, |
const ConstraintProto & | ct_proto ) |
Definition at line 1446 of file constraint_violation.cc.
|
inline |
Definition at line 666 of file integer_expr.h.
|
inline |
l => (a + b <= ub).
Definition at line 653 of file precedences.h.
|
inline |
l => (a + b + c <= ub).
Definition at line 670 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 1673 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 43 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 54 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 797 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 40 of file disjunctive.cc.
void operations_research::sat::AddDisjunctiveWithBooleanPrecedencesOnly | ( | absl::Span< const 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 156 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 984 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 | ( | const SchedulingConstraintHelper * | helper, |
Model * | model, | ||
std::vector< IntegerVariable > * | vars, | ||
int | mask ) |
Definition at line 991 of file scheduling_helpers.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 1505 of file linear_relaxation.cc.
|
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
Add for all i, min <= exprs[i].
Definition at line 715 of file integer_expr.h.
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 182 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 631 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 1780 of file linear_relaxation.cc.
void operations_research::sat::AddMaxAffineCutGenerator | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
If the target is constant, propagation is enough.
Definition at line 1140 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 1730 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 1707 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 |
Computes result += a * b, and return false iff there is an overflow.
Definition at line 134 of file integer_base.h.
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 32 of file timetable.cc.
void operations_research::sat::AddRoutesCutGenerator | ( | const ConstraintProto & | ct, |
Model * | m, | ||
LinearRelaxation * | relaxation ) |
Definition at line 595 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 1583 of file linear_relaxation.cc.
|
inline |
Computes result += a * a, and return false iff there is an overflow.
Definition at line 144 of file integer_base.h.
|
inline |
Definition at line 125 of file integer_base.h.
void operations_research::sat::AddWeightedLiteralToLinearConstraint | ( | int | lit, |
int64_t | coeff, | ||
LinearConstraintProto * | linear, | ||
int64_t * | offset ) |
Same as above, but with a single term (lit, coeff). Note that lit can be negative. The offset is relative to the linear expression (and should be negated when added to the rhs of the linear constraint proto).
Definition at line 646 of file cp_model_utils.cc.
|
inline |
enforcement_literals => sum >= lower_bound
We just negate everything and use an <= constraint.
Definition at line 587 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 471 of file integer_expr.h.
|
inline |
a + offset <= b. (when a and b are of the form 1 * var + offset).
Definition at line 638 of file precedences.h.
|
inline |
Returns true if the expression is a * var + b.
Definition at line 237 of file cp_model_utils.h.
|
inline |
Evaluates an affine expression at the given value.
Definition at line 220 of file cp_model_utils.h.
std::function< void(Model *)> operations_research::sat::AllDifferentAC | ( | absl::Span< const 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 104 of file all_different.cc.
std::function< void(Model *)> operations_research::sat::AllDifferentBinary | ( | absl::Span< const 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 41 of file all_different.cc.
std::function< void(Model *)> operations_research::sat::AllDifferentOnBounds | ( | absl::Span< const 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 87 of file all_different.cc.
std::function< void(Model *)> operations_research::sat::AllDifferentOnBounds | ( | const std::vector< AffineExpression > & | expressions | ) |
Definition at line 76 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 158 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 238 of file diffn_util.cc.
void operations_research::sat::AppendAtMostOneRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Definition at line 422 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 353 of file linear_relaxation.cc.
void operations_research::sat::AppendBoolOrRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Definition at line 339 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 493 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 754 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 1830 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 431 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 1238 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 1098 of file linear_relaxation.cc.
void operations_research::sat::AppendLinMaxRelaxationPart2 | ( | IntegerVariable | target, |
absl::Span< const Literal > | alternative_literals, | ||
absl::Span< const 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 1164 of file linear_relaxation.cc.
void operations_research::sat::AppendMaxAffineRelaxation | ( | const ConstraintProto & | ct, |
Model * | model, | ||
LinearRelaxation * | relaxation ) |
Definition at line 1120 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.
Definition at line 1055 of file linear_relaxation.cc.
void operations_research::sat::AppendNoOverlap2dRelaxationForComponent | ( | absl::Span< const int > | component, |
Model * | model, | ||
NoOverlap2DConstraintHelper * | no_overlap_helper, | ||
LinearConstraintManager * | manager, | ||
ProductDecomposer * | product_decomposer ) |
This can happen if the box must be absent.
All boxes must be absent.
We have only one active literal.
Not including the term if we don't have a view is ok.
Definition at line 987 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 717 of file linear_relaxation.cc.
void operations_research::sat::AppendPairwiseRestrictions | ( | absl::Span< const ItemWithVariableSize > | items, |
absl::Span< const ItemWithVariableSize > | 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 663 of file diffn_util.cc.
void operations_research::sat::AppendPairwiseRestrictions | ( | absl::Span< const ItemWithVariableSize > | 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 654 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 268 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 142 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 531 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 1541 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 1022 of file scheduling_helpers.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 414 of file cp_model_utils.cc.
void operations_research::sat::ApplyToAllLiteralIndices | ( | const std::function< void(int *)> & | f, |
ConstraintProto * | ct ) |
Definition at line 230 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 293 of file cp_model_utils.cc.
void operations_research::sat::ApplyVariableMapping | ( | absl::Span< int > | mapping, |
std::vector< int > * | reverse_mapping, | ||
CpModelProto * | proto ) |
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. If mapping[i] < 0 the variable can be ignored if possible. If it is not possible, then we will use a new index for it (at the end) and the mapping will be updated to reflect that.
The image of the mapping should be dense in [0, reverse_mapping->size()).
Remap all the variable/literal references in the constraints and the enforcement literals in the variables.
We extend the mapping if this variable is still used.
Remap the objective variables.
Remap the assumptions.
Remap the symmetries. Note that we should have properly dealt with fixed orbit and such in FilterOrbitOnUnusedOrFixedVariables().
We clear the orbitope info (we don't really use it after presolve).
Remap the search decision heuristic.
Remove strategy with empty affine expression.
Remap the solution hint.
Move the variable definitions.
Check that all variables have a non-empty domain.
Definition at line 13689 of file cp_model_presolve.cc.
|
inline |
Definition at line 108 of file integer_base.h.
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 59 of file integer_search.cc.
|
inline |
Definition at line 932 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 31 of file symmetry_util.cc.
|
inline |
Model based functions.
Definition at line 891 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 207 of file integer_search.cc.
bool operations_research::sat::BoxesAreInEnergyConflict | ( | absl::Span< const Rectangle > | rectangles, |
absl::Span< const 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 171 of file diffn_util.cc.
std::vector< SingleShape > operations_research::sat::BoxesToShapes | ( | absl::Span< const Rectangle > | rectangles, |
const Neighbours & | neighbours ) |
Given a set of rectangles, split it into connected components and transform each individual set into a shape described by its boundary and holes paths.
Get edge most to the bottom left
The left-most vertical edge of the connected component must be of its exterior boundary. So we must always see the exterior boundary before seeing any holes.
Follow the usual convention that holes are in the inverse orientation of the external boundary.
Definition at line 804 of file 2d_rectangle_presolve.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.
Definition at line 619 of file 2d_packing_brute_force.cc.
bool operations_research::sat::BuildMaxAffineUpConstraint | ( | const LinearExpression & | target, |
IntegerVariable | var, | ||
absl::Span< const 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.
Neighbours operations_research::sat::BuildNeighboursGraph | ( | absl::Span< const Rectangle > | rectangles | ) |
To build a graph of neighbours, we build a sorted vector for each one of the edges (top, bottom, etc) of the rectangles. Then we merge the bottom and top vectors and iterate on it. Due to the sorting order, segments where the bottom of a rectangle touches the top of another one must consecutive.
Definition at line 467 of file 2d_rectangle_presolve.cc.
LinearExpression operations_research::sat::CanonicalizeExpr | ( | const LinearExpression & | expr | ) |
Returns the same expression in the canonical form (all positive coefficients).
Definition at line 390 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, | ||
PresolveContextT * | 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 2542 of file presolve_context.cc.
void operations_research::sat::CanonicalizeTable | ( | PresolveContext * | context, |
ConstraintProto * | ct ) |
Canonicalizes the table constraint by removing all unreachable tuples, and all columns which have the same variable of a previous column.
This also sort all the tuples and remove all fixed columns from the table.
Make the trivial table constraint canonical.
Detect expressions sharing the same variable as a previous expression.
The mapping between the position in the original list of expressions, and the position in the reduced list of expressions.
Remove all scaling on expressions as we have stored the inner values.
The table was not empty from the beginning (we test it), but it became empty after removing all fixed variables. So either we also remove all the tuples, in which case there was no tuple that matched, or some tuple (of size 0!) remained and in this case we did find a match.
Add a trivially unsat (or trivially sat if negated) table constraint so code downstream can handle any eventual enforcement literals.
Write sorted tuples.
Definition at line 34 of file cp_model_table.cc.
|
inline |
Definition at line 100 of file integer_base.h.
|
inline |
Overflows and saturated arithmetic.
Definition at line 92 of file integer_base.h.
|
inline |
Definition at line 96 of file integer_base.h.
|
inline |
Definition at line 901 of file sat_solver.h.
|
inline |
Definition at line 72 of file integer_base.h.
int64_t operations_research::sat::CeilSquareRoot | ( | int64_t | a | ) |
|
inline |
Returns the L2 distance between the centers of the two rectangles.
Definition at line 135 of file diffn_util.h.
|
inline |
Definition at line 145 of file diffn_util.h.
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, |
IntegerTrail * | integer_trail, | ||
ObjectiveDefinition * | objective_definition ) |
If a variable appear in the objective, branch on its best objective value.
Definition at line 66 of file integer_search.cc.
std::function< void(Model *)> operations_research::sat::CircuitCovering | ( | absl::Span< const std::vector< Literal > > | graph, |
absl::Span< const int > | distinguished_nodes ) |
Definition at line 709 of file circuit.cc.
|
inline |
Definition at line 947 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 383 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 378 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 347 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 1015 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 1328 of file integer_search.cc.
void operations_research::sat::CompressTuples | ( | absl::Span< const int64_t > | domain_sizes, |
std::vector< std::vector< int64_t > > * | tuples ) |
Remove duplicates if any.
Definition at line 182 of file cp_model_table.cc.
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 174 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, |
absl::Span< const 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 562 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 682 of file scheduling_helpers.cc.
std::vector< int > operations_research::sat::ComputeGomoryHuTree | ( | int | num_nodes, |
absl::Span< const 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 1132 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 219 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 602 of file cp_model_utils.cc.
double operations_research::sat::ComputeL2Norm | ( | const LinearConstraint & | ct | ) |
Returns sqrt(sum square(coeff)).
Definition at line 211 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.
Definition at line 1872 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 1107 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 1023 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 1058 of file simplification.cc.
|
inline |
Compute the signature and the maximum element. We want a signature that is order invariant and is compatible with inclusion.
Definition at line 269 of file inclusion.h.
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 706 of file precedences.h.
|
inline |
Definition at line 613 of file integer_expr.h.
|
inline |
Definition at line 599 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 1206 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 475 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 1857 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 429 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 354 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 410 of file cp_model_search.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ConstructIntegerCompletionSearchStrategy | ( | absl::Span< const 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 385 of file cp_model_search.cc.
void operations_research::sat::ConstructOverlappingSets | ( | absl::Span< IndexedInterval > | intervals, |
CompactVectorVector< int > * | result, | ||
absl::Span< const int > | order = {} ) |
Given n fixed intervals that must be sorted by IndexedInterval::ComparatorByStart(), 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.
IMPORTANT: The span of intervals will not be usable after this function! this could be changed if needed with an extra copy.
All Intervals must have a positive size.
The algo is in O(n log n) + O(result_size) which is usually O(n^2).
If the last argument is not empty, we will sort the interval in the result according to the given order, i.e. i will be before j if order[i] < order[j].
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.
Push the current set to result first if its size is > 1.
Update the set. Note that we keep the order.
Add all the new intervals starting exactly at "time".
If order is not empty, make sure we maintain the order.
Push final set.
Definition at line 428 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 209 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 958 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.
We make sure the hint is within the variables domain.
This allows to avoid overflow because we know evaluating constraints on the variables domains should be safe thanks to the initial validation.
Definition at line 922 of file cp_model_copy.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 272 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 137 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 681 of file cp_model_solver.cc.
CutGenerator operations_research::sat::CreateAllDifferentCutGenerator | ( | absl::Span< const 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 452 of file linear_relaxation.cc.
void operations_research::sat::CreateAndRegisterMandatoryOverlapPropagator | ( | NoOverlap2DConstraintHelper * | helper, |
Model * | model, | ||
GenericLiteralWatcher * | watcher, | ||
int | priority ) |
Propagator that checks that no mandatory area of two boxes overlap in O(N * log N) time.
Definition at line 96 of file 2d_mandatory_overlap_propagator.cc.
void operations_research::sat::CreateAndRegisterTryEdgePropagator | ( | NoOverlap2DConstraintHelper * | helper, |
Model * | model, | ||
GenericLiteralWatcher * | watcher, | ||
int | priority ) |
Propagator that for each boxes participating in a no_overlap_2d constraint try to find the leftmost valid position that is compatible with all the other boxes. If none is found, it will propagate a conflict. Otherwise, if it is different from the current x_min, it will propagate the new x_min.
Definition at line 407 of file 2d_try_edge_propagator.cc.
CutGenerator operations_research::sat::CreateCliqueCutGenerator | ( | absl::Span< const 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 1570 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 584 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 953 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 698 of file scheduling_cuts.cc.
CutGenerator operations_research::sat::CreateCVRPCutGenerator | ( | int | num_nodes, |
absl::Span< const int > | tails, | ||
absl::Span< const int > | heads, | ||
absl::Span< const Literal > | literals, | ||
absl::Span< const 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 1336 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 1500 of file routing_cuts.cc.
CutGenerator operations_research::sat::CreateLinMaxCutGenerator | ( | IntegerVariable | target, |
absl::Span< const LinearExpression > | exprs, | ||
absl::Span< const 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 | ( | NoOverlap2DConstraintHelper * | helper, |
Model * | model ) |
Completion time cuts for the no_overlap_2d constraint. It actually generates the completion time cumulative cuts in both axis.
CutGenerator operations_research::sat::CreateNoOverlap2dEnergyCutGenerator | ( | NoOverlap2DConstraintHelper * | helper, |
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.
Definition at line 311 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 1523 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 647 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 987 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.
std::unique_ptr< SparsePermutation > operations_research::sat::CreateSparsePermutationFromProto | ( | int | n, |
const SparsePermutationProto & | proto ) |
Creates a SparsePermutation on [0, n) from its proto representation.
Definition at line 238 of file symmetry_util.cc.
CutGenerator operations_research::sat::CreateSquareCutGenerator | ( | AffineExpression | y, |
AffineExpression | x, | ||
int | linearization_level, | ||
Model * | model ) |
CutGenerator operations_research::sat::CreateStronglyConnectedGraphCutGenerator | ( | int | num_nodes, |
absl::Span< const int > | tails, | ||
absl::Span< const int > | heads, | ||
absl::Span< const 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 1320 of file routing_cuts.cc.
void operations_research::sat::CreateValidModelWithSingleConstraint | ( | const ConstraintProto & | ct, |
const PresolveContext * | context, | ||
std::vector< int > * | variable_mapping, | ||
CpModelProto * | mini_model ) |
Now add end = start + size for the interval. This is not strictly necessary but it makes the presolve more powerful.
Definition at line 2704 of file presolve_context.cc.
std::function< void(Model *)> operations_research::sat::Cumulative | ( | const std::vector< IntervalVariable > & | vars, |
absl::Span< const 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.
If there is no demand, since we already added a constraint that the capacity is not negative above, we can stop here.
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 44 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 776 of file integer_search.cc.
std::function< void(Model *)> operations_research::sat::CumulativeTimeDecomposition | ( | absl::Span< const IntervalVariable > | vars, |
absl::Span< const 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 294 of file cumulative.cc.
std::function< void(Model *)> operations_research::sat::CumulativeUsingReservoir | ( | absl::Span< const IntervalVariable > | vars, |
absl::Span< const AffineExpression > | demands, | ||
AffineExpression | capacity, | ||
SchedulingConstraintHelper * | helper ) |
Another testing code, same assumptions as the CumulativeTimeDecomposition().
Definition at line 378 of file cumulative.cc.
std::vector< Rectangle > operations_research::sat::CutShapeIntoRectangles | ( | SingleShape | shape | ) |
This function applies the method described in page 3 of [1].
[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.
To cut our polygon into rectangles, we first put it into a data structure that is easier to manipulate.
Some cuts connect two concave edges and will be duplicated in all_cuts. Those are important: since they "fix" two concavities with a single cut, they are called "good diagonals" in the literature. Note that in computational geometry jargon, a diagonal of a polygon is a line segment that connects two non-adjacent vertices of a polygon, even in cases like ours that we are only talking of diagonals that are not "diagonal" in the usual meaning of the word: ie., horizontal or vertical segments connecting two vertices of the polygon).
The "good diagonals" are only more optimal that any cut if they are not crossed by other cuts. To maximize their usefulness, we build a graph where the good diagonals are the vertices and we add an edge every time a vertical and horizontal diagonal cross. The minimum vertex cover of this graph is the minimal set of good diagonals that are not crossed by other cuts.
Since our data structure only allow to cut the shape according to a list of vertical or horizontal cuts, but not a list mixing both, we cut first on the chosen horizontal good diagonals.
We need to recompute the cuts after we applied the good diagonals, since the geometry has changed.
Now that we did all horizontal good diagonals, we need to cut on all vertical good diagonals and then cut arbitrarily to remove all concave edges. To make things simple, just apply all vertical cuts, since they include all the vertical good diagonals and also fully slice the shape into rectangles.
Remove duplicates coming from good diagonals first.
Now every connected component of the shape is a rectangle. Build the final result.
Definition at line 1267 of file 2d_rectangle_presolve.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.
Log orbit information.
Definition at line 769 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.
Super 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.
Fixing just a few variables to break large symmetry can be really bad. See for example cdc7-4-3-2.pb.gz where we don't find solution if we do that. On the other hand, enabling this make it worse on neos-3083784-nive.pb.gz.
In general, enabling this works better in single thread with max_lp_sym, but worse in multi-thread, where less workers are using symmetries, and so it is better to fix more stuff.
Fix "can_be_fixed_to_false" instead of the orbitope if it is larger.
We are breaking the symmetry in a way that makes the hint invalid. We want var
to be false, so we would naively pick a symmetry to enforce that. But that will be wrong if we do this twice: after we permute the hint to fix the first one we would look for a symmetry group element that fixes the second one to false. But there are many of those, and picking the wrong one would risk making the first one true again. Since this is a AMO, fixing the one that is true doesn't have this problem.
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.
The transformations below seems to hurt more than what they help. Especially when we handle symmetry during the search like with max_lp_sym worker. See for instance neos-948346.pb or map06.pb.gz.
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 936 of file cp_model_symmetries.cc.
Disjoint2dPackingResult operations_research::sat::DetectDisjointRegionIn2dPacking | ( | absl::Span< const RectangleInRange > | non_fixed_boxes, |
absl::Span< const Rectangle > | fixed_boxes, | ||
int | max_num_components ) |
If we are here, that means that the space where boxes can be placed is not connected.
Definition at line 1484 of file 2d_rectangle_presolve.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 | ( | absl::Span< const IntervalVariable > | intervals, |
absl::Span< const 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 636 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 909 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 128 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 989 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)
If one of the task presence is undecided, start by making it present.
Definition at line 699 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 271 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 791 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 124 of file cp_model_utils.h.
|
inline |
enforcement_literals => clause.
Definition at line 987 of file sat_solver.h.
|
inline |
Definition at line 52 of file cp_model_utils.h.
|
inline |
a == b.
Definition at line 687 of file precedences.h.
|
inline |
a == b.
Definition at line 962 of file sat_solver.h.
|
inline |
a + offset == b.
Definition at line 696 of file precedences.h.
Domain operations_research::sat::EvaluateImpliedIntProdDomain | ( | const LinearArgumentProto & | expr, |
const PresolveContext & | context ) |
Definition at line 1484 of file cp_model_presolve.cc.
|
inline |
Definition at line 917 of file sat_solver.h.
std::function< void(Model *)> operations_research::sat::ExactlyOnePerRowAndPerColumn | ( | absl::Span< const std::vector< Literal > > | graph | ) |
Definition at line 630 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 1053 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 2449 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 the hint value of a
is 1 then the hint value of b
should be 1 due to the a => b constraint. Hence the hint feasibility can always be preserved (if the hint value of a
is 0 the hint does not need to be updated).
If (b++, a++) is valid, then we can always set b to true. If the hint value of b
is 0 then the hint value of a
should be 0 due to the a => b constraint. Hence the hint feasibility can always be preserved (if the hint value of b
is 1 the hint does not need to be updated).
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.
The newly added implication can break the hint only if the hint value of ref
is 1 and the hint value of dom_ref
is 0. In this case the call below fixes it by negating both values. Otherwise it does nothing and thus preserves its feasibility.
dom– or var++ are now forbidden.
Definition at line 1515 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 615 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 620 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 270 of file cp_model_utils.h.
|
inline |
void operations_research::sat::ExtractAllSubsetsFromForest | ( | absl::Span< const 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 1079 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 549 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 682 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 397 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 780 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 500 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 133 of file cp_model_utils.h.
void operations_research::sat::FillTightenedDomainInResponse | ( | const CpModelProto & | original_model, |
const CpModelProto & | mapping_proto, | ||
absl::Span< const int > | postsolve_mapping, | ||
absl::Span< const 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 466 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 196 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 390 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 406 of file diffn_util.cc.
bool operations_research::sat::FilterOrbitOnUnusedOrFixedVariables | ( | SymmetryProto * | symmetry, |
PresolveContext * | context ) |
This make sure all variables from the same orbit have the same domain. We also remove from the generator cycles on fixed or removed variables.
Returns false on UNSAT.
We process each cycle at once. If all variables from a cycle are fixed to the same value, this is fine and we can just remove the cycle.
If we have affine relation, we only support the case where they are all the same.
Lets keep this cycle.
Lets remove empty generators.
Lets output the new statistics.
Definition at line 1583 of file cp_model_symmetries.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 pre-solvable.
Definition at line 2600 of file cp_model_expand.cc.
double operations_research::sat::FindBestScalingAndComputeErrors | ( | absl::Span< const 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.
std::optional< std::vector< int64_t > > operations_research::sat::FindCombinedSolution | ( | const CpModelProto & | model, |
absl::Span< const int64_t > | new_solution, | ||
absl::Span< const int64_t > | base_solution, | ||
const SharedResponseManager * | response_manager, | ||
std::string * | solution_info ) |
Given a new_solution
that was created by changing a bit a base_solution
, try to apply the same changes to the other solutions stored in the response_manager
and return any such generated solution that is valid.
Definition at line 49 of file combine_solutions.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 646 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 14026 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 1600 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.
std::optional< std::pair< int, int > > operations_research::sat::FindOneIntersectionIfPresent | ( | absl::Span< const Rectangle > | rectangles | ) |
This function is faster that the FindPartialRectangleIntersections() if one only want to know if there is at least one intersection. It is in O(N log N).
IMPORTANT: this assumes rectangles are already sorted by their x_min and does not support degenerate rectangles with zero area.
If a pair {i, j} is returned, we will have i < j, and no intersection in the subset of rectanges in [0, j).
Definition at line 2109 of file diffn_util.cc.
std::optional< std::pair< int, int > > operations_research::sat::FindOneIntersectionIfPresentWithZeroArea | ( | absl::Span< const Rectangle > | rectangles | ) |
Same as FindOneIntersectionIfPresent() but supports degenerate rectangles with zero area.
Definition at line 2114 of file diffn_util.cc.
std::vector< std::pair< int, int > > operations_research::sat::FindPartialRectangleIntersections | ( | absl::Span< const Rectangle > | rectangles | ) |
For a given a set of N rectangles in rectangles
, there might be up to N*(N-1)/2 pairs of rectangles that intersect one another. If each of these pairs describe an arc and each rectangle describe a node, the rectangles and their intersections describe a graph. This function returns the full spanning forest for this graph (ie., a spanning tree for each connected component). This function allows to know if a set of rectangles has any intersection, find an example intersection for each rectangle that has one, or split the rectangles into connected components according to their intersections.
The returned tuples are the arcs of the spanning forest represented by their indices in the input vector.
This function works with degenerate rectangles (ie., points or lines) and have the same semantics for overlap as Rectangle::IsDisjoint().
Definition at line 2101 of file diffn_util.cc.
std::vector< std::pair< int, int > > operations_research::sat::FindPartialRectangleIntersectionsImpl | ( | absl::Span< const Rectangle32 > | rectangles, |
int32_t | y_max ) |
Requires that rectangles are sorted by x_min and that sizes on both dimensions are > 0.
We are going to use a sweep line algorithm to find the intersections. First, we sort the rectangles by their x coordinates, then consider a sweep line that goes from the left to the right. See the comment on the SweepLineIntervalTree class for more details about what we store for each line.
Definition at line 1814 of file diffn_util.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 1513 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 689 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 696 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 707 of file cp_model_utils.cc.
|
inline |
Definition at line 289 of file cp_model_utils.h.
|
inline |
Definition at line 297 of file cp_model_utils.h.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::FirstUnassignedVarAtItsMinHeuristic | ( | absl::Span< const 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 171 of file integer_search.cc.
|
inline |
Adds the constraint: a / b = c where b is a constant.
Definition at line 810 of file integer_expr.h.
|
inline |
Adds the constraint: a % b = c where b is a constant.
Definition at line 824 of file integer_expr.h.
|
inline |
Weighted sum == constant.
Definition at line 460 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:
|
inline |
Definition at line 81 of file integer_base.h.
int64_t operations_research::sat::FloorSquareRoot | ( | int64_t | a | ) |
std::function< BooleanOrIntegerLiteral()> operations_research::sat::FollowHint | ( | absl::Span< const BooleanOrIntegerVariable > | vars, |
absl::Span< const 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 1128 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 390 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.
Definition at line 321 of file cp_model_table.cc.
|
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 * size_min_i) >= (sum(size_min_i^2) + sum(size_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 lift intervals that starts before a given value, but are forced to cross it. This lifting procedure implies trimming interval to its part that is after the given value.
In the case of a cumulative constraint with a capacity of C, we compute a valid equation by splitting the task (size_min si, demand_min di) into di tasks of size si and demand 1, that we spread across C no_overlap constraint. When doing so, the lhs of the equation is the same, the first term of the rhs is also unchanged. A lower bound of the second term of the rhs is reached when the split is exact (each no_overlap sees a long demand of sum(si * di / C). Thus the second term is greater or equal to (sum (si * di) ^ 2) / (2 * C)
Sometimes, the min energy of the task i is greater than si * di. Let's introduce ai the minimum energy of the task and rewrite the previous equation. In that new setting, we can rewrite the cumulative transformation by splitting each tasks into at least di tasks of size at least si and demand 1.
In that setting, the lhs is rewritten as sum(ai * ei) and the second term of the rhs is rewritten as sum(ai) ^ 2 / (2 * C).
The question is how to rewrite the term `sum(di * si * si). The minimum contribution is when the task has size si and demand ai / si. (note that si is the minimum size of the task, and di its minimum demand). We can replace the small rectangle area term by ai * si.
The separation procedure is implemented using two loops:
Sort by start min to bucketize by start_min.
First loop: we loop on potential start times.
Skip to the next start_min value.
We look at events 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.
Best cut so far for this loop.
Used in the first term of the rhs of the equation.
Used in the second term of the rhs of the equation.
For normalization.
We will add tasks one by one, sorted by end time, and evaluate the potential cut at each step.
Second loop: we add tasks one by one.
Make sure we do not overflow.
In the no_overlap case, we have: area = event.x_size_min ^ 2 In the simple cumulative case, we split split the task (demand_min, size_min) into demand_min tasks in the no_overlap case. area = event.y_size_min * event.x_size_min * event.x_size_min In the cumulative case, we can have energy_min > side_min * demand_min. In that case, we use energy_min * size_min.
Maintain the reachable capacity with a bounded complexity subset sum.
This is competing with the brute force approach. Skip cases covered by the other code.
Do we have a violated cut ?
shift contribution by current_start_min.
The efficacy of the cut is the normalized violation of the above equation. We will normalize by the sqrt of the sum of squared energies.
For a given start time, we only keep the best cut. The reason is that is the cut is strongly violated, we can get a sequence of violated cuts as we add more tasks. These new cuts will be less violated, but will not bring anything useful to the LP relaxation. At the same time, this sequence of cuts can push out other cuts from a disjoint set of tasks.
We have inserted all tasks. Have we found a violated cut ? If so, add the most violated one to the top_n cut container.
Definition at line 1365 of file scheduling_cuts.cc.
void operations_research::sat::GenerateCumulativeEnergeticCuts | ( | absl::string_view | 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 483 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 276 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 857 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, |
absl::Span< const 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 1019 of file routing_cuts.cc.
std::vector< ItemWithVariableSize > operations_research::sat::GenerateItemsRectanglesWithNoPairwiseConflict | ( | absl::Span< const Rectangle > | rectangles, |
double | slack_factor, | ||
absl::BitGenRef | random ) |
Definition at line 181 of file 2d_orthogonal_packing_testing.cc.
std::vector< ItemWithVariableSize > 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 204 of file 2d_orthogonal_packing_testing.cc.
std::vector< Rectangle > operations_research::sat::GenerateNonConflictingRectangles | ( | int | num_rectangles, |
absl::BitGenRef | random ) |
Definition at line 33 of file 2d_orthogonal_packing_testing.cc.
std::vector< Rectangle > operations_research::sat::GenerateNonConflictingRectanglesWithPacking | ( | std::pair< IntegerValue, IntegerValue > | bb, |
int | average_num_boxes, | ||
absl::BitGenRef | random ) |
Alternative way of generating random rectangles. This one generate random rectangles and try to pack them using the left-bottom-first order.
Definition at line 83 of file 2d_orthogonal_packing_testing.cc.
void operations_research::sat::GenerateNoOverlap2dEnergyCut | ( | absl::Span< const std::vector< LiteralValueValue > > | energies, |
absl::Span< const 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 140 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 2071 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 2135 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 events 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 1150 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 456 of file linear_constraint.cc.
IntegerValue operations_research::sat::GetCoefficientOfPositiveVar | ( | const IntegerVariable | var, |
const LinearExpression & | expr ) |
Definition at line 468 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 996 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.
If there is no symmetry, max_lp_sym and max_lp are the same, but we prefer the less confusing name.
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 817 of file cp_model_search.cc.
|
inline |
Returns the value of the inner variable of an affine expression from the value of the expression. It will DCHECK that the result is valid.
Definition at line 228 of file cp_model_utils.h.
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 534 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.
Given that each workers work on a different part of the subtree, it might not be a good idea to try to work on a global shared solution.
Base parameters for LNS worker.
We disable costly presolve/inprocessing.
For routing, the LP relaxation seems pretty important, so we prefer an high linearization level to solve LNS subproblems.
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 505 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 189 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 154 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 501 of file diffn_util.cc.
CompactVectorVector< int > operations_research::sat::GetOverlappingRectangleComponents | ( | absl::Span< const Rectangle > | rectangles | ) |
Creates a graph when two nodes are connected iff their rectangles overlap. Then partition into connected components.
Definition at line 111 of file diffn_util.cc.
|
inline |
Definition at line 169 of file integer_base.h.
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.
void operations_research::sat::GetSchreierVectorAndOrbit | ( | int | point, |
absl::Span< const std::unique_ptr< SparsePermutation > > | generators, | ||
std::vector< int > * | schrier_vector, | ||
std::vector< int > * | orbit ) |
See Chapter 7 of Butler, Gregory, ed. Fundamental algorithms for permutation groups. Berlin, Heidelberg: Springer Berlin Heidelberg, 1991.
Definition at line 201 of file symmetry_util.cc.
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 626 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 679 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 78 of file integer_search.cc.
|
inline |
Definition at line 135 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 69 of file diophantine.cc.
|
inline |
Small utility functions to deal with half-reified constraints.
Definition at line 49 of file cp_model_utils.h.
|
inline |
Always true! nothing to do.
Always false.
a => b.
Definition at line 955 of file sat_solver.h.
bool operations_research::sat::ImportModelAndDomainsWithBasicPresolveIntoContext | ( | const CpModelProto & | in_model, |
absl::Span< const Domain > | domains, | ||
std::function< bool(int)> | active_constraints, | ||
PresolveContext * | context ) |
Same as ImportModelWithBasicPresolveIntoContext() except that variable domains are read from domains.
Definition at line 907 of file cp_model_copy.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 895 of file cp_model_copy.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 291 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.
|
inline |
Insert/Remove variables from an interval constraint into a bitset.
Definition at line 104 of file cp_model_utils.h.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::InstrumentSearchStrategy | ( | const CpModelProto & | cp_model_proto, |
absl::Span< const 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 448 of file cp_model_search.cc.
|
inline |
Definition at line 173 of file integer_base.h.
|
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 369 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 1652 of file linear_relaxation.cc.
|
inline |
Definition at line 68 of file integer_base.h.
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 |
Definition at line 756 of file integer_expr.h.
|
inline |
|
inline |
|
inline |
Definition at line 250 of file intervals.h.
|
inline |
Definition at line 256 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 |
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 |
|
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 281 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 463 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 679 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 353 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 404 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 | ( | absl::Span< const std::vector< Literal > > | literal_tuples, |
absl::Span< const 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 123 of file cp_constraints.h.
void operations_research::sat::LoadAllDiffConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1533 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 2941 of file cp_model_solver.cc.
void operations_research::sat::LoadAtMostOneConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1038 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 1079 of file cp_model_solver_helpers.cc.
void operations_research::sat::LoadBoolAndConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1024 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 307 of file cp_model_loader.cc.
void operations_research::sat::LoadBoolOrConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Constraint loading functions.
Definition at line 1011 of file cp_model_loader.cc.
void operations_research::sat::LoadBoolXorConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1058 of file cp_model_loader.cc.
void operations_research::sat::LoadCircuitConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1677 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 630 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 1702 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 1234 of file cp_model_solver_helpers.cc.
void operations_research::sat::LoadCumulativeConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1646 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 1048 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 1202 of file cp_model_solver_helpers.cc.
void operations_research::sat::LoadIntDivConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1581 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 1601 of file cp_model_loader.cc.
void operations_research::sat::LoadIntProdConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1540 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.
For enforcement => var \in domain, we can potentially reuse the encoding literal directly rather than creating new ones.
Skip non-reachable intervals.
Skip trivial constraint. Note that when this happens, all the intervals before where non-reachable.
If there is just two terms and no enforcement, we don't need to create an extra boolean as the second case can be controlled by the negation of the first.
Make sure all booleans are tights when enumerating all solutions.
Definition at line 1220 of file cp_model_loader.cc.
|
inline |
Definition at line 662 of file integer_expr.h.
void operations_research::sat::LoadLinMaxConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1613 of file cp_model_loader.cc.
bool operations_research::sat::LoadModelForPresolve | ( | const CpModelProto & | model_proto, |
SatParameters | params, | ||
PresolveContext * | context, | ||
Model * | local_model, | ||
absl::string_view | name_for_logging ) |
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 2500 of file presolve_context.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.
Definition at line 2487 of file presolve_context.cc.
void operations_research::sat::LoadNoOverlap2dConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1636 of file cp_model_loader.cc.
void operations_research::sat::LoadNoOverlapConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1631 of file cp_model_loader.cc.
void operations_research::sat::LoadReservoirConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1656 of file cp_model_loader.cc.
void operations_research::sat::LoadRoutesConstraint | ( | const ConstraintProto & | ct, |
Model * | m ) |
Definition at line 1689 of file cp_model_loader.cc.
void operations_research::sat::LoadSubcircuitConstraint | ( | int | num_nodes, |
absl::Span< const int > | tails, | ||
absl::Span< const int > | heads, | ||
absl::Span< const 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 650 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 127 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 420 of file probing.cc.
|
inline |
|
inline |
|
inline |
|
inline |
a + offset <= b.
Definition at line 627 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 238 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 300 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 311 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 148 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 576 of file encoding.cc.
|
inline |
Definition at line 244 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 441 of file encoding.cc.
|
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 411 of file linear_constraint.h.
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 2830 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 57 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 114 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 211 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 1712 of file cp_model_solver_helpers.cc.
|
inline |
Model based functions.
Definition at line 238 of file intervals.h.
int64_t operations_research::sat::ModularInverse | ( | int64_t | x, |
int64_t | m ) |
Using the extended Euclidean 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 185 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 44 of file cp_model_utils.h.
std::vector< IntegerVariable > operations_research::sat::NegationOf | ( | absl::Span< const IntegerVariable > | vars | ) |
Returns the vector of the negated variables.
Definition at line 52 of file integer.cc.
LinearExpression operations_research::sat::NegationOf | ( | const LinearExpression & | expr | ) |
Preserves canonicality.
Definition at line 433 of file linear_constraint.cc.
|
inline |
Definition at line 155 of file integer_base.h.
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 2227 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 2219 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 2212 of file cp_model_solver.cc.
|
inline |
|
inline |
|
inline |
Definition at line 263 of file intervals.h.
|
inline |
Definition at line 278 of file intervals.h.
|
inline |
Definition at line 286 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 298 of file intervals.h.
|
inline |
Definition at line 319 of file intervals.h.
|
inline |
Definition at line 329 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 2247 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 2236 of file cp_model_solver.cc.
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 2236 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 683 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 377 of file linear_constraint.cc.
void operations_research::sat::NonDeterministicLoop | ( | std::vector< std::unique_ptr< SubSolver > > & | subsolvers, |
int | num_threads, | ||
ModelSharedTimeLimit * | time_limit ) |
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 194 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 1213 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 1366 of file cp_model.h.
|
inline |
Definition at line 1361 of file cp_model.h.
|
inline |
Definition at line 1280 of file cp_model.h.
|
inline |
Definition at line 1276 of file cp_model.h.
|
inline |
Definition at line 1292 of file cp_model.h.
|
inline |
Definition at line 1303 of file cp_model.h.
|
inline |
Definition at line 1234 of file cp_model.h.
|
inline |
Definition at line 1243 of file cp_model.h.
|
inline |
Definition at line 1323 of file cp_model.h.
|
inline |
Definition at line 1298 of file cp_model.h.
|
inline |
Definition at line 1308 of file cp_model.h.
|
inline |
Definition at line 1319 of file cp_model.h.
|
inline |
Definition at line 1239 of file cp_model.h.
|
inline |
Definition at line 1247 of file cp_model.h.
|
inline |
Definition at line 1328 of file cp_model.h.
|
inline |
Definition at line 1339 of file cp_model.h.
|
inline |
Definition at line 1257 of file cp_model.h.
|
inline |
Definition at line 1266 of file cp_model.h.
|
inline |
Definition at line 1355 of file cp_model.h.
|
inline |
Definition at line 1334 of file cp_model.h.
|
inline |
Definition at line 1345 of file cp_model.h.
|
inline |
Definition at line 1351 of file cp_model.h.
|
inline |
For DoubleLinearExpr.
Definition at line 1287 of file cp_model.h.
|
inline |
Definition at line 1262 of file cp_model.h.
|
inline |
Definition at line 1271 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 1232 of file cp_model.h.
|
inline |
Definition at line 239 of file integer_base.h.
|
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 53 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 129 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 66 of file integer.cc.
|
inline |
Definition at line 234 of file integer_base.h.
|
inline |
Definition at line 117 of file sat_base.h.
|
inline |
Definition at line 69 of file pb_constraint.h.
|
inline |
Definition at line 1073 of file sat_solver.h.
|
inline |
hashing support.
Currently limited to a few inner types of ConstraintProto.
Definition at line 351 of file cp_model_utils.h.
|
inline |
Definition at line 372 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 1188 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 162 of file cp_constraints.h.
std::vector< Rectangle > operations_research::sat::PavedRegionDifference | ( | std::vector< Rectangle > | original_region, |
absl::Span< const Rectangle > | area_to_remove ) |
Given two regions, each one of them defined by a vector of non-overlapping rectangles paving them, returns a vector of non-overlapping rectangles that paves the points that were part of the first region but not of the second. This can also be seen as the set difference of the points of the regions.
Definition at line 1611 of file diffn_util.cc.
int64_t operations_research::sat::PositiveMod | ( | int64_t | x, |
int64_t | m ) |
|
inline |
Definition at line 45 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.
Definition at line 118 of file integer_base.h.
LinearExpression operations_research::sat::PositiveVarExpr | ( | const LinearExpression & | expr | ) |
Returns the same expression with positive variables.
Definition at line 441 of file linear_constraint.cc.
|
inline |
Definition at line 163 of file integer_base.h.
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 1011 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 479 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 40 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveElement | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
We only support 2 cases: either the index was removed, of the target, not both.
Deal with fixed index.
Deal with fixed target (and constant vars).
Definition at line 283 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 63 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 326 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveIntProd | ( | const ConstraintProto & | ct, |
std::vector< Domain > * | domains ) |
We only support assigning to an affine target.
Definition at line 342 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.
The constraint is satisfied, if there is any enforcement that are not fixed yet, we need to fix them.
Tricky: We sometime push two constraints for postsolve: 1/ l => A 2/ not(l) => B if B is true, it is better to fix l
so that the constraint 2/ is enforced. This way we should have no problem when processing 1/
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.
We assign that afterwards for better debugging if we run into the domains empty above.
Definition at line 117 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 263 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveResponse | ( | int64_t | num_variables_in_original_model, |
const CpModelProto & | mapping_proto, | ||
absl::Span< const 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 382 of file cp_model_postsolve.cc.
void operations_research::sat::PostsolveResponseWithFullSolver | ( | int | num_variables_in_original_model, |
CpModelProto | mapping_proto, | ||
absl::Span< const 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 1822 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, | ||
absl::Span< const int > | postsolve_mapping, | ||
std::vector< int64_t > * | solution ) |
Definition at line 1866 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 546 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 851 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 13057 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
.
The greedy algorithm is really fast. Run it first since it might greatly reduce the size of large trivial instances.
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.
^ ++++ . ++++ . . ++++ . => ++++ \/
Since less turns means less edges, this should be a good way to reduce the number of boxes.
Definition at line 165 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 1141 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 168 of file optimization.cc.
void operations_research::sat::ProcessFloatingPointOVariablesAndObjective | ( | fz::Model * | fz_model | ) |
Scan the model to replace all int2float to int_eq, and all floating point variables used in these int2float constraint to be integral.
Scan the model to find a floating point objective (defined by a single floating point variable and a single float_lin_eq constraint defining it), and replace them by a single objective with integer variables and floating point weights.
Scan the model, rename int2float to int_eq, change type of the floating point variables to integer.
Scan the model to find the float objective variable and the float objective constraint if defined.
Definition at line 1355 of file cp_model_fz_solver.cc.
|
inline |
Definition at line 104 of file integer_base.h.
|
inline |
Adds the constraint: a * b = p.
Definition at line 768 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 334 of file cp_model_table.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 823 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 454 of file integer_search.cc.
PushedSolutionPointers operations_research::sat::PushAndMaybeCombineSolution | ( | SharedResponseManager * | response_manager, |
const CpModelProto & | model_proto, | ||
absl::Span< const int64_t > | new_solution, | ||
const std::string & | solution_info, | ||
absl::Span< const int64_t > | base_solution, | ||
Model * | model ) |
Definition at line 79 of file combine_solutions.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 1627 of file cp_model_solver_helpers.cc.
CpModelProto operations_research::sat::Random3SatProblem | ( | int | num_variables, |
double | proportion_of_constraints = 4.26 ) |
Generates a random 3-SAT problem with a number of constraints given by: num_variables * proportions_of_constraints. With the default proportion value, we are around the transition SAT/UNSAT.
Definition at line 28 of file cp_model_test_utils.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 973 of file integer_search.cc.
CpModelProto operations_research::sat::RandomLinearProblem | ( | int | num_variables, |
int | num_constraints ) |
Generates a random 0-1 "covering" optimization linear problem:
Sum >= num_variables / 10.
To ensure that the constraint is feasible, we enforce that it has at least the 'minimum' number of terms. This clause should only rarely be used, when num_variables is high.
Objective: minimize variables at one.
Sum of all other variables == 0
Definition at line 57 of file cp_model_test_utils.cc.
Domain operations_research::sat::ReadDomainFromProto | ( | const ProtoWithDomain & | proto | ) |
Reads a Domain from the domain field of a proto.
Definition at line 144 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 46 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 503 of file encoding.cc.
bool operations_research::sat::ReduceNumberOfBoxesExactMandatory | ( | std::vector< Rectangle > * | mandatory_rectangles, |
std::vector< Rectangle > * | optional_rectangles ) |
Same as above, but this implementation returns the optimal solution in minimizing the number of boxes if optional_rectangles
is empty. On the other hand, its handling of optional boxes is rather limited. It simply fills the holes in the mandatory boxes with optional boxes, if possible.
This heuristic can be slow for very large problems, so gate it with a reasonable limit.
Now for every connected component of the holes in the mandatory area, see if we can fill them with optional boxes.
Fill the hole.
We can modify optional_rectangles
here since we know that if we remove a hole this function will return true.
This is the function that applies the algorithm described in [1].
It is possible that the algorithm actually increases the number of boxes. See the "Problematic2" test.
Definition at line 1420 of file 2d_rectangle_presolve.cc.
bool operations_research::sat::ReduceNumberofBoxesGreedy | ( | std::vector< Rectangle > * | mandatory_rectangles, |
std::vector< Rectangle > * | optional_rectangles ) |
The current implementation just greedly merge rectangles that shares an edge.
bool for is_optional
Merge two rectangles!
Definition at line 343 of file 2d_rectangle_presolve.cc.
|
inline |
Definition at line 46 of file cp_model_utils.h.
|
inline |
The two regions must be defined by non-overlapping rectangles.
Definition at line 694 of file diffn_util.h.
void operations_research::sat::RegisterAndTransferOwnership | ( | Model * | model, |
T * | ct ) |
Definition at line 763 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 954 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.
Temporarily disable clause sharing so we don't immediately re-export the clauses we just imported.
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).
The new clauses may be subsumed, so try to minimize them to reduce overhead of sharing. We only share up to 1024 literals worth of new clauses per second, so at most 1024 decisions to vivify all new clauses, so this should be relatively cheap.
Definition at line 1006 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 870 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 899 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 687 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 788 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 1005 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 1022 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 970 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.
|
inline |
Definition at line 112 of file cp_model_utils.h.
void operations_research::sat::RemoveZeroTerms | ( | LinearConstraint * | constraint | ) |
Removes the entries with a coefficient of zero.
Definition at line 288 of file linear_constraint.cc.
std::string operations_research::sat::RenderDot | ( | std::optional< Rectangle > | bb, |
absl::Span< const Rectangle > | solution, | ||
std::string_view | extra_dot_payload = "" ) |
Render a packing solution as a Graphviz dot file. Only works in the "neato" or "fdp" Graphviz backends.
Definition at line 1573 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 1068 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 139 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 1599 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 1178 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 246 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 660 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 415 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 1192 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 2813 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 227 of file linear_constraint.cc.
bool operations_research::sat::ScaleAndSetObjective | ( | const SatParameters & | params, |
absl::Span< const 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.
ABSL_MUST_USE_RESULT bool operations_research::sat::ScaleFloatingPointObjective | ( | const SatParameters & | params, |
SolverLogger * | logger, | ||
CpModelProto * | proto ) |
If a floating point objective is present, scale it using the current domains and transform it to an integer_objective.
Definition at line 1002 of file presolve_context.cc.
|
inline |
Similar to ScaleObjectiveValue() but uses the integer version.
Definition at line 183 of file cp_model_utils.h.
|
inline |
Scales back a objective value to a double value from the original model.
Definition at line 170 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 1176 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 1382 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 476 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 1356 of file routing_cuts.cc.
void operations_research::sat::SeparateSubtourInequalities | ( | OutgoingCutHelper & | helper, |
LinearConstraintManager * | manager ) |
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.
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 1195 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 95 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 296 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 307 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 94 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 947 of file cp_model_utils.cc.
std::function< BooleanOrIntegerLiteral()> operations_research::sat::ShaveObjectiveLb | ( | Model * | model | ) |
Definition at line 430 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 941 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 789 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 1490 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 1479 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 1864 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 2920 of file cp_model_solver.cc.
void operations_research::sat::SolveCpDestroyAtomicBool | ( | void *const | atomic_bool | ) |
Definition at line 53 of file cp_solver_c.cc.
void operations_research::sat::SolveCpInterruptible | ( | void *const | limit_reached, |
const void * | creq, | ||
int | creq_len, | ||
const void * | cparams, | ||
int | cparams_len, | ||
void ** | cres, | ||
int * | cres_len ) |
Definition at line 61 of file cp_solver_c.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 as the presolve is done. Note that only postsolve_mapping and mapping_proto are needed for postsolve.
Detect the symmetry of the presolved model.
Symmetry should be already computed and correct, so we don't redo it. Moreover it is possible we will not find them again as the constraints might have changed.
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.
We dump the response when infeasible, this might help debugging.
Crash.
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 2304 of file cp_model_solver.cc.
void operations_research::sat::SolveCpModelWithParameters | ( | const void * | creq, |
int | creq_len, | ||
const void * | cparams, | ||
int | cparams_len, | ||
void ** | cres, | ||
int * | cres_len ) |
Definition at line 44 of file cp_solver_c.cc.
void * operations_research::sat::SolveCpNewAtomicBool | ( | ) |
Definition at line 51 of file cp_solver_c.cc.
void operations_research::sat::SolveCpStopSolve | ( | void *const | atomic_bool | ) |
Definition at line 57 of file cp_solver_c.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 122 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 ) |
Solves the given flatzinc model using the CP-SAT solver.
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 1414 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 1617 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 1495 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 2925 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 2933 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 1154 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 89 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 117 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.
std::vector< std::vector< int > > operations_research::sat::SplitInConnectedComponents | ( | const Neighbours & | neighbours | ) |
Definition at line 559 of file 2d_rectangle_presolve.cc.
IntegerLiteral operations_research::sat::SplitUsingBestSolutionValueInRepository | ( | IntegerVariable | var, |
const SharedSolutionRepository< int64_t > & | solution_repo, | ||
Model * | model ) |
Definition at line 146 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.
operations_research::sat::SubsetsDetector | ( | const Storage & | storage | ) | -> SubsetsDetector< Storage > |
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 232 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 1164 of file routing_cuts.cc.
|
inline |
Definition at line 60 of file integer_base.h.
|
inline |
Model based functions.
Definition at line 113 of file cp_constraints.h.
std::vector< int > operations_research::sat::TracePoint | ( | int | point, |
absl::Span< const int > | schrier_vector, | ||
absl::Span< const std::unique_ptr< SparsePermutation > > | generators ) |
Given a schreier vector for a given base point and a point in the same orbit of the base point, returns a list of index of the generators
to apply to get a permutation mapping the base point to get the given point.
Definition at line 224 of file symmetry_util.cc.
|
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 97 of file symmetry_util.h.
bool operations_research::sat::TrySolution | ( | const CpModelProto & | model, |
absl::Span< const int64_t > | solution, | ||
absl::Span< const int64_t > | new_solution, | ||
absl::Span< const int64_t > | base_solution, | ||
std::vector< int64_t > * | new_combined_solution ) |
A value that changed that we patch.
Definition at line 33 of file combine_solutions.cc.
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 1379 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 | ( | absl::Span< const 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 275 of file integer_search.cc.
|
inline |
Removes the objective scaling and offset from the given value.
Definition at line 194 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 542 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 529 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 1048 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 1251 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 407 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 55 of file parameters_validation.cc.
|
inline |
This checks that the variable is fixed.
Definition at line 1041 of file sat_solver.h.
|
inline |
This checks that the variable is fixed.
Definition at line 1032 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 |
Definition at line 159 of file integer_base.h.
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 449 of file integer_expr.h.
|
inline |
bool operations_research::sat::WriteModelProtoToFile | ( | const M & | proto, |
absl::string_view | filename ) |
Definition at line 331 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 54 of file presolve_context.h.
|
constexpr |
Definition at line 55 of file presolve_context.h.
|
constexpr |
Default seed for fingerprints.
Definition at line 286 of file cp_model_utils.h.
|
constexpr |
Infinity for type Fractional.
Definition at line 87 of file lp_types.h.
|
staticconstexpr |
Definition at line 34 of file 2d_packing_brute_force.cc.
|
constexpr |
We use some special constraint index in our variable <-> constraint graph.
Definition at line 53 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.
Definition at line 43 of file cp_model_table.h.
const int operations_research::sat::kUnsatTrailIndex = -1 |
A constant used by the EnqueueDecision*() API.
Definition at line 54 of file sat_solver.h.