forked from google/or-tools
-
Notifications
You must be signed in to change notification settings - Fork 3
/
boolean_problem.h
145 lines (120 loc) · 6.5 KB
/
boolean_problem.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2010-2018 Google LLC
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.
#ifndef OR_TOOLS_SAT_BOOLEAN_PROBLEM_H_
#define OR_TOOLS_SAT_BOOLEAN_PROBLEM_H_
#include <memory>
#include <string>
#include <vector>
#include "absl/status/status.h"
#include "ortools/algorithms/sparse_permutation.h"
#include "ortools/base/strong_vector.h"
#include "ortools/sat/boolean_problem.pb.h"
#include "ortools/sat/cp_model.pb.h"
#include "ortools/sat/pb_constraint.h"
#include "ortools/sat/sat_base.h"
#include "ortools/sat/sat_solver.h"
#include "ortools/sat/simplification.h"
namespace operations_research {
namespace sat {
// Converts a LinearBooleanProblem to a CpModelProto which should eventually
// replace completely the LinearBooleanProblem proto.
CpModelProto BooleanProblemToCpModelproto(const LinearBooleanProblem& problem);
// Adds the offset and returns the scaled version of the given objective value.
inline double AddOffsetAndScaleObjectiveValue(
const LinearBooleanProblem& problem, Coefficient v) {
return (static_cast<double>(v.value()) + problem.objective().offset()) *
problem.objective().scaling_factor();
}
// 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.
void ChangeOptimizationDirection(LinearBooleanProblem* problem);
// 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.
void ExtractAssignment(const LinearBooleanProblem& problem,
const SatSolver& solver, std::vector<bool>* assignment);
// Tests the preconditions of the given problem (as described in the proto) and
// returns an error if they are not all satisfied.
absl::Status ValidateBooleanProblem(const LinearBooleanProblem& problem);
// Loads a BooleanProblem into a given SatSolver instance.
bool LoadBooleanProblem(const 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).
bool LoadAndConsumeBooleanProblem(LinearBooleanProblem* problem,
SatSolver* solver);
// Uses the objective coefficient to drive the SAT search towards an
// heuristically better solution.
void UseObjectiveForSatAssignmentPreference(const LinearBooleanProblem& problem,
SatSolver* solver);
// Adds the constraint that the objective is smaller than the given upper bound.
bool AddObjectiveUpperBound(const LinearBooleanProblem& problem,
Coefficient upper_bound, SatSolver* solver);
// Adds the constraint that the objective is smaller or equals to 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);
// Returns the objective value under the current assignment.
Coefficient ComputeObjectiveValue(const LinearBooleanProblem& problem,
const std::vector<bool>& assignment);
// Checks that an assignment is valid for the given BooleanProblem.
bool IsAssignmentValid(const LinearBooleanProblem& problem,
const std::vector<bool>& assignment);
// Converts a LinearBooleanProblem to the cnf file format.
// Note that this only works for pure SAT problems (only clauses), max-sat or
// weighted max-sat problems. Returns an empty string on error.
std::string LinearBooleanProblemToCnfString(
const LinearBooleanProblem& problem);
// Store a variable assignment into the given BooleanAssignement proto.
// Note that only the assigned variables are stored, so the assignment may be
// incomplete.
void StoreAssignment(const VariablesAssignment& assignment,
BooleanAssignment* output);
// Constructs a sub-problem formed by the constraints with given indices.
void ExtractSubproblem(const LinearBooleanProblem& problem,
const std::vector<int>& constraint_indices,
LinearBooleanProblem* subproblem);
// Modifies the given LinearBooleanProblem so that all the literals appearing
// inside are positive.
void MakeAllLiteralsPositive(LinearBooleanProblem* problem);
// 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.
void FindLinearBooleanProblemSymmetries(
const LinearBooleanProblem& problem,
std::vector<std::unique_ptr<SparsePermutation>>* generators);
// 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.
void ApplyLiteralMappingToBooleanProblem(
const absl::StrongVector<LiteralIndex, LiteralIndex>& mapping,
LinearBooleanProblem* problem);
// 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.
void ProbeAndSimplifyProblem(SatPostsolver* postsolver,
LinearBooleanProblem* problem);
} // namespace sat
} // namespace operations_research
#endif // OR_TOOLS_SAT_BOOLEAN_PROBLEM_H_