Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
cp_model_table.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_SAT_CP_MODEL_TABLE_H_
15#define OR_TOOLS_SAT_CP_MODEL_TABLE_H_
16
17#include <cstdint>
18#include <limits>
19#include <vector>
20
21#include "absl/container/flat_hash_set.h"
22#include "absl/container/inlined_vector.h"
23#include "absl/types/span.h"
24#include "ortools/sat/cp_model.pb.h"
26
27namespace operations_research {
28namespace sat {
29
30// Canonicalizes the table constraint by removing all unreachable tuples, and
31// all columns which have the same variable of a previous column.
32//
33// This also sort all the tuples and remove all fixed columns from the table.
34void CanonicalizeTable(PresolveContext* context, ConstraintProto* ct);
35
36// This method tries to compress a list of tuples by merging complementary
37// tuples, that is a set of tuples that only differ on one variable, and that
38// cover the domain of the variable. In that case, it will keep only one tuple,
39// and replace the value for variable by any_value, the equivalent of '*' in
40// regexps.
41//
42// This method is exposed for testing purposes.
43constexpr int64_t kTableAnyValue = std::numeric_limits<int64_t>::min();
44void CompressTuples(absl::Span<const int64_t> domain_sizes,
45 std::vector<std::vector<int64_t>>* tuples);
46
47// Similar to CompressTuples() but produces a final table where each cell is
48// a set of value. This should result in a table that can still be encoded
49// efficiently in SAT but with less tuples and thus less extra Booleans. Note
50// that if a set of value is empty, it is interpreted at "any" so we can gain
51// some space.
52//
53// The passed tuples vector is used as temporary memory and is detroyed.
54// We interpret kTableAnyValue as an "any" tuple.
55//
56// TODO(user): To reduce memory, we could return some absl::Span in the last
57// layer instead of vector.
58//
59// TODO(user): The final compression is depend on the order of the variables.
60// For instance the table (1,1)(1,2)(1,3),(1,4),(2,3) can either be compressed
61// as (1,*)(2,3) or (1,{1,2,4})({1,3},3). More experiment are needed to devise
62// a better heuristic. It might for example be good to call CompressTuples()
63// first.
64std::vector<std::vector<absl::InlinedVector<int64_t, 2>>> FullyCompressTuples(
65 absl::Span<const int64_t> domain_sizes,
66 std::vector<std::vector<int64_t>>* tuples);
67
68// Fills and propagates the set of reachable states/labels.
69void PropagateAutomaton(const AutomatonConstraintProto& proto,
70 const PresolveContext& context,
71 std::vector<absl::flat_hash_set<int64_t>>* states,
72 std::vector<absl::flat_hash_set<int64_t>>* labels);
73
74} // namespace sat
75} // namespace operations_research
76
77#endif // OR_TOOLS_SAT_CP_MODEL_TABLE_H_
constexpr int64_t kTableAnyValue
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.
void CanonicalizeTable(PresolveContext *context, ConstraintProto *ct)
In SWIG mode, we don't want anything besides these top-level includes.