OR-Tools  9.1
cp_model_utils.h
Go to the documentation of this file.
1// Copyright 2010-2021 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_UTILS_H_
15#define OR_TOOLS_SAT_CP_MODEL_UTILS_H_
16
17#include <algorithm>
18#include <cstdint>
19#include <functional>
20#include <limits>
21#include <string>
22#include <vector>
23
24#include "absl/container/flat_hash_set.h"
29
30namespace operations_research {
31namespace sat {
32
33// Small utility functions to deal with negative variable/literal references.
34inline int NegatedRef(int ref) { return -ref - 1; }
35inline int PositiveRef(int ref) { return std::max(ref, NegatedRef(ref)); }
36inline bool RefIsPositive(int ref) { return ref >= 0; }
37
38// Small utility functions to deal with half-reified constraints.
40 return !ct.enforcement_literal().empty();
41}
43 return ct.enforcement_literal(0);
44}
45
46// Fills the target as negated ref.
47void SetToNegatedLinearExpression(const LinearExpressionProto& input_expr,
48 LinearExpressionProto* output_negated_expr);
49
50// Collects all the references used by a constraint. This function is used in a
51// few places to have a "generic" code dealing with constraints. Note that the
52// enforcement_literal is NOT counted here and that the vectors can have
53// duplicates.
55 std::vector<int> variables;
56 std::vector<int> literals;
57};
59
60// Applies the given function to all variables/literals/intervals indices of the
61// constraint. This function is used in a few places to have a "generic" code
62// dealing with constraints.
63void ApplyToAllVariableIndices(const std::function<void(int*)>& function,
65void ApplyToAllLiteralIndices(const std::function<void(int*)>& function,
67void ApplyToAllIntervalIndices(const std::function<void(int*)>& function,
69
70// Returns the name of the ConstraintProto::ConstraintCase oneof enum.
71// Note(user): There is no such function in the proto API as of 16/01/2017.
72std::string ConstraintCaseName(ConstraintProto::ConstraintCase constraint_case);
73
74// Returns the sorted list of variables used by a constraint.
75// Note that this include variable used as a literal.
76std::vector<int> UsedVariables(const ConstraintProto& ct);
77
78// Returns the sorted list of interval used by a constraint.
79std::vector<int> UsedIntervals(const ConstraintProto& ct);
80
81// Returns true if a proto.domain() contain the given value.
82// The domain is expected to be encoded as a sorted disjoint interval list.
83template <typename ProtoWithDomain>
84bool DomainInProtoContains(const ProtoWithDomain& proto, int64_t value) {
85 for (int i = 0; i < proto.domain_size(); i += 2) {
86 if (value >= proto.domain(i) && value <= proto.domain(i + 1)) return true;
87 }
88 return false;
89}
90
91// Serializes a Domain into the domain field of a proto.
92template <typename ProtoWithDomain>
93void FillDomainInProto(const Domain& domain, ProtoWithDomain* proto) {
94 proto->clear_domain();
95 proto->mutable_domain()->Reserve(domain.NumIntervals());
96 for (const ClosedInterval& interval : domain) {
97 proto->add_domain(interval.start);
98 proto->add_domain(interval.end);
99 }
100}
101
102// Reads a Domain from the domain field of a proto.
103template <typename ProtoWithDomain>
104Domain ReadDomainFromProto(const ProtoWithDomain& proto) {
105#if defined(__PORTABLE_PLATFORM__)
107 {proto.domain().begin(), proto.domain().end()});
108#else
109 return Domain::FromFlatSpanOfIntervals(proto.domain());
110#endif
111}
112
113// Returns the list of values in a given domain.
114// This will fail if the domain contains more than one millions values.
115//
116// TODO(user): work directly on the Domain class instead.
117template <typename ProtoWithDomain>
118std::vector<int64_t> AllValuesInDomain(const ProtoWithDomain& proto) {
119 std::vector<int64_t> result;
120 for (int i = 0; i < proto.domain_size(); i += 2) {
121 for (int64_t v = proto.domain(i); v <= proto.domain(i + 1); ++v) {
122 CHECK_LE(result.size(), 1e6);
123 result.push_back(v);
124 }
125 }
126 return result;
127}
128
129// Scales back a objective value to a double value from the original model.
131 int64_t value) {
132 double result = static_cast<double>(value);
134 result = -std::numeric_limits<double>::infinity();
136 result = std::numeric_limits<double>::infinity();
137 result += proto.offset();
138 if (proto.scaling_factor() == 0) return result;
139 return proto.scaling_factor() * result;
140}
141
142// Removes the objective scaling and offset from the given value.
144 double value) {
145 double result = value;
146 if (proto.scaling_factor() != 0) {
147 result /= proto.scaling_factor();
148 }
149 return result - proto.offset();
150}
151
152// Computes the "inner" objective of a response that contains a solution.
153// This is the objective without offset and scaling. Call ScaleObjectiveValue()
154// to get the user facing objective.
155int64_t ComputeInnerObjective(const CpObjectiveProto& objective,
156 const CpSolverResponse& response);
157
158} // namespace sat
159} // namespace operations_research
160
161#endif // OR_TOOLS_SAT_CP_MODEL_UTILS_H_
int64_t max
Definition: alldiff_cst.cc:140
int64_t min
Definition: alldiff_cst.cc:139
#define CHECK_LE(val1, val2)
Definition: base/logging.h:700
We call domain any subset of Int64 = [kint64min, kint64max].
static Domain FromFlatSpanOfIntervals(absl::Span< const int64_t > flat_intervals)
Same as FromIntervals() for a flattened representation (start, end, start, end, .....
int NumIntervals() const
Basic read-only std::vector<> wrapping to view a Domain as a sorted list of non-adjacent intervals.
static Domain FromFlatIntervals(const std::vector< int64_t > &flat_intervals)
This method is available in Python, Java and .NET.
CpModelProto proto
SharedResponseManager * response
const Constraint * ct
int64_t value
int64_t ComputeInnerObjective(const CpObjectiveProto &objective, const CpSolverResponse &response)
std::vector< int > UsedVariables(const ConstraintProto &ct)
double UnscaleObjectiveValue(const CpObjectiveProto &proto, double value)
bool RefIsPositive(int ref)
std::vector< int > UsedIntervals(const ConstraintProto &ct)
void SetToNegatedLinearExpression(const LinearExpressionProto &input_expr, LinearExpressionProto *output_negated_expr)
bool HasEnforcementLiteral(const ConstraintProto &ct)
bool DomainInProtoContains(const ProtoWithDomain &proto, int64_t value)
double ScaleObjectiveValue(const CpObjectiveProto &proto, int64_t value)
void ApplyToAllLiteralIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
void ApplyToAllIntervalIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
void FillDomainInProto(const Domain &domain, ProtoWithDomain *proto)
Domain ReadDomainFromProto(const ProtoWithDomain &proto)
void ApplyToAllVariableIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
IndexReferences GetReferencesUsedByConstraint(const ConstraintProto &ct)
std::string ConstraintCaseName(ConstraintProto::ConstraintCase constraint_case)
int EnforcementLiteral(const ConstraintProto &ct)
std::vector< int64_t > AllValuesInDomain(const ProtoWithDomain &proto)
Collection of objects used to extend the Constraint Solver library.
IntervalVar * interval
Definition: resource.cc:100
Represents a closed interval [start, end].