[CP-SAT] deprecate BooleanSum and BooleanScalProd in favor of Sum and ScalProd

This commit is contained in:
Laurent Perron
2021-12-08 16:29:40 +01:00
parent da59aadfe1
commit 2d22667f30
11 changed files with 149 additions and 69 deletions

View File

@@ -158,8 +158,8 @@ void CostasBool(const int dim) {
}
for (int i = 0; i < dim; ++i) {
cp_model.AddEquality(LinearExpr::BooleanSum(vars[i]), 1);
cp_model.AddEquality(LinearExpr::BooleanSum(transposed_vars[i]), 1);
cp_model.AddEquality(LinearExpr::Sum(vars[i]), 1);
cp_model.AddEquality(LinearExpr::Sum(transposed_vars[i]), 1);
}
// Check that the pairwise difference is unique
@@ -179,8 +179,8 @@ void CostasBool(const int dim) {
Not(vars[var + step][value]), neg});
}
}
cp_model.AddLessOrEqual(LinearExpr::BooleanSum(positive_diffs), 1);
cp_model.AddLessOrEqual(LinearExpr::BooleanSum(negative_diffs), 1);
cp_model.AddLessOrEqual(LinearExpr::Sum(positive_diffs), 1);
cp_model.AddLessOrEqual(LinearExpr::Sum(negative_diffs), 1);
}
}
@@ -229,8 +229,8 @@ void CostasBoolSoft(const int dim) {
}
for (int i = 0; i < dim; ++i) {
cp_model.AddEquality(LinearExpr::BooleanSum(vars[i]), 1);
cp_model.AddEquality(LinearExpr::BooleanSum(transposed_vars[i]), 1);
cp_model.AddEquality(LinearExpr::Sum(vars[i]), 1);
cp_model.AddEquality(LinearExpr::Sum(transposed_vars[i]), 1);
}
std::vector<IntVar> all_violations;
@@ -256,9 +256,9 @@ void CostasBoolSoft(const int dim) {
const IntVar neg_var =
cp_model.NewIntVar(Domain(0, negative_diffs.size()));
cp_model.AddGreaterOrEqual(
pos_var, LinearExpr::BooleanSum(positive_diffs).AddConstant(-1));
pos_var, LinearExpr::Sum(positive_diffs).AddConstant(-1));
cp_model.AddGreaterOrEqual(
neg_var, LinearExpr::BooleanSum(negative_diffs).AddConstant(-1));
neg_var, LinearExpr::Sum(negative_diffs).AddConstant(-1));
all_violations.push_back(pos_var);
all_violations.push_back(neg_var);
}

View File

@@ -252,7 +252,7 @@ void CreateAlternativeTasks(
for (const AlternativeTaskData& alternative : alternatives) {
interval_presences.push_back(alternative.presence);
}
cp_model.AddEquality(LinearExpr::BooleanSum(interval_presences), 1);
cp_model.AddEquality(LinearExpr::Sum(interval_presences), 1);
}
}
}
@@ -303,7 +303,7 @@ void AddAlternativeTaskDurationRelaxation(
// sum(shifted_duration[i] * presence_literals[i])
cp_model.AddEquality(
LinearExpr::ScalProd({tasks[t].end, tasks[t].start}, {1, -1}),
LinearExpr::BooleanScalProd(presence_literals, shifted_durations)
LinearExpr::ScalProd(presence_literals, shifted_durations)
.AddConstant(min_duration));
}
}
@@ -442,7 +442,7 @@ void CreateMachines(
// Add a linear equation to define the size of the tail interval.
if (absl::GetFlag(FLAGS_use_variable_duration_to_encode_transition)) {
cp_model.AddEquality(tail.interval.SizeExpr(),
LinearExpr::BooleanScalProd(literals, transitions)
LinearExpr::ScalProd(literals, transitions)
.AddConstant(tail.fixed_duration));
}
}
@@ -493,8 +493,8 @@ void CreateObjective(
objective_coeffs.push_back(lateness_penalty);
} else {
const IntVar lateness_var = cp_model.NewIntVar(Domain(0, horizon));
cp_model.AddLinMaxEquality(
lateness_var, {LinearExpr(0), job_end.AddConstant(-due_date)});
cp_model.AddMaxEquality(lateness_var,
{0, job_end.AddConstant(-due_date)});
objective_vars.push_back(lateness_var);
objective_coeffs.push_back(lateness_penalty);
}
@@ -508,10 +508,9 @@ void CreateObjective(
if (due_date > 0) {
const IntVar earliness_var = cp_model.NewIntVar(Domain(0, horizon));
cp_model.AddLinMaxEquality(
cp_model.AddMaxEquality(
earliness_var,
{LinearExpr(0),
LinearExpr::Term(job_end, -1).AddConstant(due_date)});
{0, LinearExpr::Term(job_end, -1).AddConstant(due_date)});
objective_vars.push_back(earliness_var);
objective_coeffs.push_back(earliness_penalty);
}

View File

@@ -47,7 +47,7 @@ void MagicSequence(int size) {
// Domain constraint on each position.
for (int i = 0; i < size; ++i) {
cp_model.AddEquality(LinearExpr::BooleanSum(var_domains[i]), 1);
cp_model.AddEquality(LinearExpr::Sum(var_domains[i]), 1);
}
// The number of variables equal to j shall be the value of vars[j].
@@ -60,8 +60,8 @@ void MagicSequence(int size) {
for (int i = 0; i < size; ++i) {
vars_equal_to_j.push_back(var_domains[i][j]);
}
cp_model.AddEquality(LinearExpr::BooleanScalProd(var_domains[j], values),
LinearExpr::BooleanSum(vars_equal_to_j));
cp_model.AddEquality(LinearExpr::ScalProd(var_domains[j], values),
LinearExpr::Sum(vars_equal_to_j));
}
const CpSolverResponse response =

View File

@@ -80,11 +80,10 @@ void MultiKnapsackSat(int scaling, const std::string& params) {
for (int b = 0; b < num_bins; ++b) {
IntVar bin_weight = builder.NewIntVar({kWeightMin, kWeightMax});
bin_weights.push_back(bin_weight);
builder.AddEquality(LinearExpr::BooleanScalProd(items_in_bins[b], weights),
builder.AddEquality(LinearExpr::ScalProd(items_in_bins[b], weights),
bin_weight);
builder.AddLinearConstraint(
LinearExpr::BooleanScalProd(items_in_bins[b], volumes),
{kVolumeMin, kVolumeMax});
builder.AddLinearConstraint(LinearExpr::ScalProd(items_in_bins[b], volumes),
{kVolumeMin, kVolumeMax});
}
// Each item is selected at most one time.
@@ -93,8 +92,7 @@ void MultiKnapsackSat(int scaling, const std::string& params) {
for (int b = 0; b < num_bins; ++b) {
bin_contain_item[b] = items_in_bins[b][i];
}
builder.AddEquality(LinearExpr::BooleanSum(bin_contain_item),
selected_items[i]);
builder.AddEquality(LinearExpr::Sum(bin_contain_item), selected_items[i]);
}
// Maximize the sums of weights.

View File

@@ -32,6 +32,7 @@
#include <utility>
#include <vector>
#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/flags/flag.h"
@@ -233,8 +234,8 @@ class NetworkRoutingDataBuilder {
AddEdge(i, j);
}
std::set<int> to_complete;
std::set<int> not_full;
absl::btree_set<int> to_complete;
absl::btree_set<int> not_full;
for (int i = 0; i < num_backbones_; ++i) {
if (degrees_[i] < min_backbone_degree_) {
to_complete.insert(i);

View File

@@ -31,6 +31,7 @@
#include <string>
#include <vector>
#include "absl/container/btree_set.h"
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/flags/usage.h"
@@ -237,8 +238,8 @@ void LoadAndSolve(const std::string& file_name) {
// For each time point, count the number of active jobs at that time,
// then the number of active workers on these jobs is equal to the number of
// active jobs.
std::set<int> time_points;
std::set<std::vector<int>> visited_job_lists;
absl::btree_set<int> time_points;
absl::btree_set<std::vector<int>> visited_job_lists;
for (int j = 0; j < num_jobs; ++j) {
time_points.insert(parser.jobs()[j].start);
@@ -275,8 +276,7 @@ void LoadAndSolve(const std::string& file_name) {
// Add the count constraints: We have as many active workers as jobs.
const int num_jobs = intersecting_jobs.size();
cp_model.AddEquality(LinearExpr::BooleanSum(overlapping_worker_jobs),
num_jobs);
cp_model.AddEquality(LinearExpr::Sum(overlapping_worker_jobs), num_jobs);
// Book keeping.
max_intersection_size = std::max(max_intersection_size, num_jobs);
num_count_constraints++;
@@ -290,7 +290,7 @@ void LoadAndSolve(const std::string& file_name) {
// Objective.
const IntVar objective_var =
cp_model.NewIntVar(Domain(max_intersection_size, num_workers));
cp_model.AddEquality(LinearExpr::BooleanSum(active_workers), objective_var);
cp_model.AddEquality(LinearExpr::Sum(active_workers), objective_var);
cp_model.Minimize(objective_var);
// Solve.

View File

@@ -168,7 +168,7 @@ void SlitherLink(const std::vector<std::vector<int> >& data) {
const int right_arc = undirected_vertical_arc(x + 1, y);
neighbors.push_back(vertical_arcs[2 * right_arc]);
neighbors.push_back(vertical_arcs[2 * right_arc + 1]);
builder.AddEquality(LinearExpr::BooleanSum(neighbors), data[y][x]);
builder.AddEquality(LinearExpr::Sum(neighbors), data[y][x]);
}
}

View File

@@ -141,7 +141,7 @@ void OpponentModel(int num_teams) {
builder.AddAllDifferent(moving);
}
builder.AddEquality(LinearExpr::BooleanSum(home_aways[t]), num_teams - 1);
builder.AddEquality(LinearExpr::Sum(home_aways[t]), num_teams - 1);
// Forbid sequence of 3 homes or 3 aways.
for (int start = 0; start < num_days - 2; ++start) {
@@ -166,7 +166,7 @@ void OpponentModel(int num_teams) {
}
}
builder.Minimize(LinearExpr::BooleanSum(breaks));
builder.Minimize(LinearExpr::Sum(breaks));
Model model;
if (!absl::GetFlag(FLAGS_params).empty()) {
@@ -234,7 +234,7 @@ void FixtureModel(int num_teams) {
possible_opponents.push_back(fixtures[d][team][other]);
possible_opponents.push_back(fixtures[d][other][team]);
}
builder.AddEquality(LinearExpr::BooleanSum(possible_opponents), 1);
builder.AddEquality(LinearExpr::Sum(possible_opponents), 1);
}
}
@@ -246,7 +246,7 @@ void FixtureModel(int num_teams) {
for (int d = 0; d < num_days; ++d) {
possible_days.push_back(fixtures[d][team][other]);
}
builder.AddEquality(LinearExpr::BooleanSum(possible_days), 1);
builder.AddEquality(LinearExpr::Sum(possible_days), 1);
}
}
@@ -262,8 +262,8 @@ void FixtureModel(int num_teams) {
second_half.push_back(fixtures[d + matches_per_day][team][other]);
second_half.push_back(fixtures[d + matches_per_day][other][team]);
}
builder.AddEquality(LinearExpr::BooleanSum(first_half), 1);
builder.AddEquality(LinearExpr::BooleanSum(second_half), 1);
builder.AddEquality(LinearExpr::Sum(first_half), 1);
builder.AddEquality(LinearExpr::Sum(second_half), 1);
}
}
@@ -305,9 +305,9 @@ void FixtureModel(int num_teams) {
}
}
builder.AddGreaterOrEqual(LinearExpr::BooleanSum(breaks), 2 * num_teams - 4);
builder.AddGreaterOrEqual(LinearExpr::Sum(breaks), 2 * num_teams - 4);
builder.Minimize(LinearExpr::BooleanSum(breaks));
builder.Minimize(LinearExpr::Sum(breaks));
Model model;
if (!absl::GetFlag(FLAGS_params).empty()) {

View File

@@ -152,6 +152,22 @@ LinearExpr LinearExpr::Sum(absl::Span<const IntVar> vars) {
return result;
}
LinearExpr LinearExpr::Sum(absl::Span<const BoolVar> vars) {
LinearExpr result;
for (const BoolVar& var : vars) {
result.AddVar(var);
}
return result;
}
LinearExpr LinearExpr::Sum(std::initializer_list<IntVar> vars) {
LinearExpr result;
for (const IntVar& var : vars) {
result.AddVar(var);
}
return result;
}
LinearExpr LinearExpr::ScalProd(absl::Span<const IntVar> vars,
absl::Span<const int64_t> coeffs) {
CHECK_EQ(vars.size(), coeffs.size());
@@ -162,6 +178,27 @@ LinearExpr LinearExpr::ScalProd(absl::Span<const IntVar> vars,
return result;
}
LinearExpr LinearExpr::ScalProd(absl::Span<const BoolVar> vars,
absl::Span<const int64_t> coeffs) {
CHECK_EQ(vars.size(), coeffs.size());
LinearExpr result;
for (int i = 0; i < vars.size(); ++i) {
result.AddTerm(vars[i], coeffs[i]);
}
return result;
}
LinearExpr LinearExpr::ScalProd(std::initializer_list<IntVar> vars,
absl::Span<const int64_t> coeffs) {
CHECK_EQ(vars.size(), coeffs.size());
LinearExpr result;
int count = 0;
for (const IntVar& var : vars) {
result.AddTerm(var, coeffs[count++]);
}
return result;
}
LinearExpr LinearExpr::Term(IntVar var, int64_t coefficient) {
LinearExpr result;
result.AddTerm(var, coefficient);
@@ -288,6 +325,22 @@ DoubleLinearExpr DoubleLinearExpr::Sum(absl::Span<const IntVar> vars) {
return result;
}
DoubleLinearExpr DoubleLinearExpr::Sum(absl::Span<const BoolVar> vars) {
DoubleLinearExpr result;
for (const BoolVar& var : vars) {
result.AddVar(var);
}
return result;
}
DoubleLinearExpr DoubleLinearExpr::Sum(std::initializer_list<IntVar> vars) {
DoubleLinearExpr result;
for (const IntVar& var : vars) {
result.AddVar(var);
}
return result;
}
DoubleLinearExpr DoubleLinearExpr::ScalProd(absl::Span<const IntVar> vars,
absl::Span<const double> coeffs) {
CHECK_EQ(vars.size(), coeffs.size());
@@ -298,22 +351,8 @@ DoubleLinearExpr DoubleLinearExpr::ScalProd(absl::Span<const IntVar> vars,
return result;
}
DoubleLinearExpr DoubleLinearExpr::Term(IntVar var, double coefficient) {
DoubleLinearExpr result;
result.AddTerm(var, coefficient);
return result;
}
DoubleLinearExpr DoubleLinearExpr::BooleanSum(absl::Span<const BoolVar> vars) {
DoubleLinearExpr result;
for (const BoolVar& var : vars) {
result.AddVar(var);
}
return result;
}
DoubleLinearExpr DoubleLinearExpr::BooleanScalProd(
absl::Span<const BoolVar> vars, absl::Span<const double> coeffs) {
DoubleLinearExpr DoubleLinearExpr::ScalProd(absl::Span<const BoolVar> vars,
absl::Span<const double> coeffs) {
CHECK_EQ(vars.size(), coeffs.size());
DoubleLinearExpr result;
for (int i = 0; i < vars.size(); ++i) {
@@ -322,6 +361,23 @@ DoubleLinearExpr DoubleLinearExpr::BooleanScalProd(
return result;
}
DoubleLinearExpr DoubleLinearExpr::ScalProd(std::initializer_list<IntVar> vars,
absl::Span<const double> coeffs) {
CHECK_EQ(vars.size(), coeffs.size());
DoubleLinearExpr result;
int count = 0;
for (const IntVar& var : vars) {
result.AddTerm(var, coeffs[count++]);
}
return result;
}
DoubleLinearExpr DoubleLinearExpr::Term(IntVar var, double coefficient) {
DoubleLinearExpr result;
result.AddTerm(var, coefficient);
return result;
}
DoubleLinearExpr& DoubleLinearExpr::AddConstant(double value) {
constant_ += value;
return *this;

View File

@@ -39,6 +39,7 @@
#define OR_TOOLS_SAT_CP_MODEL_H_
#include <cstdint>
#include <initializer_list>
#include <limits>
#include <string>
@@ -237,9 +238,9 @@ std::ostream& operator<<(std::ostream& os, const IntVar& var);
LinearExpr e5(b.Not()); // e5 = 1 - b.
// If passing a std::vector<BoolVar>, a specialized method must be called.
std::vector<BoolVar> bools = {b, Not(c)};
LinearExpr e6 = LinearExpr::BooleanSum(bools); // e6 = b + 1 - c;
LinearExpr e6 = LinearExpr::Sum(bools); // e6 = b + 1 - c;
// e7 = -3 * b + 1 - c;
LinearExpr e7 = LinearExpr::BooleanScalProd(bools, {-3, 1});
LinearExpr e7 = LinearExpr::ScalProd(bools, {-3, 1});
\endcode
* This can be used implicitly in some of the CpModelBuilder methods.
* \code
@@ -279,16 +280,33 @@ class LinearExpr {
/// Constructs the sum of a list of variables.
static LinearExpr Sum(absl::Span<const IntVar> vars);
/// Constructs the sum of a list of Boolean variables.
static LinearExpr Sum(absl::Span<const BoolVar> vars);
/// Constructs the sum of a list of Boolean variables.
// TODO(user): Remove when the operators + and * are implemented.
static LinearExpr Sum(std::initializer_list<IntVar> vars);
/// Constructs the scalar product of variables and coefficients.
static LinearExpr ScalProd(absl::Span<const IntVar> vars,
absl::Span<const int64_t> coeffs);
/// Constructs the sum of a list of Booleans.
/// Constructs the scalar product of Boolean variables and coefficients.
static LinearExpr ScalProd(absl::Span<const BoolVar> vars,
absl::Span<const int64_t> coeffs);
/// Constructs the scalar product of variables and coefficients.
// TODO(user): Remove when the operators + and * are implemented.
static LinearExpr ScalProd(std::initializer_list<IntVar> vars,
absl::Span<const int64_t> coeffs);
/// Deprecated. Use Sum() instead.
static LinearExpr BooleanSum(absl::Span<const BoolVar> vars);
/// Constructs the scalar product of Booleans and coefficients.
/// Deprecated. Use ScalProd() instead.
static LinearExpr BooleanScalProd(absl::Span<const BoolVar> vars,
absl::Span<const int64_t> coeffs);
/// Constructs var * coefficient.
static LinearExpr Term(IntVar var, int64_t coefficient);
@@ -344,9 +362,9 @@ std::ostream& operator<<(std::ostream& os, const LinearExpr& e);
DoubleLinearExpr e5(b.Not()); // e5 = 1 - b.
// If passing a std::vector<BoolVar>, a specialized method must be called.
std::vector<BoolVar> bools = {b, Not(c)};
DoubleLinearExpr e6 = DoubleLinearExpr::BooleanSum(bools); // e6 = b + 1 - c;
DoubleLinearExpr e6 = DoubleLinearExpr::Sum(bools); // e6 = b + 1 - c;
// e7 = -3.0 * b + 1.5 - 1.5 * c;
DoubleLinearExpr e7 = DoubleLinearExpr::BooleanScalProd(bools, {-3.0, 1.5});
DoubleLinearExpr e7 = DoubleLinearExpr::ScalProd(bools, {-3.0, 1.5});
\endcode
* This can be used in the objective definition.
* \code
@@ -386,16 +404,24 @@ class DoubleLinearExpr {
/// Constructs the sum of a list of variables.
static DoubleLinearExpr Sum(absl::Span<const IntVar> vars);
/// Constructs the sum of a list of Boolean variables.
static DoubleLinearExpr Sum(absl::Span<const BoolVar> vars);
/// Constructs the sum of a list of variables.
static DoubleLinearExpr Sum(std::initializer_list<IntVar> vars);
/// Constructs the scalar product of variables and coefficients.
static DoubleLinearExpr ScalProd(absl::Span<const IntVar> vars,
absl::Span<const double> coeffs);
/// Constructs the sum of a list of Booleans.
static DoubleLinearExpr BooleanSum(absl::Span<const BoolVar> vars);
/// Constructs the scalar product of Boolean variables and coefficients.
static DoubleLinearExpr ScalProd(absl::Span<const BoolVar> vars,
absl::Span<const double> coeffs);
/// Constructs the scalar product of variables and coefficients.
static DoubleLinearExpr ScalProd(std::initializer_list<IntVar> vars,
absl::Span<const double> coeffs);
/// Constructs the scalar product of Booleans and coefficients.
static DoubleLinearExpr BooleanScalProd(absl::Span<const BoolVar> vars,
absl::Span<const double> coeffs);
/// Constructs var * coefficient.
static DoubleLinearExpr Term(IntVar var, double coefficient);

View File

@@ -75,7 +75,7 @@ void BinpackingProblemSat() {
}
// Maximize sum of slacks.
cp_model.Maximize(LinearExpr::BooleanSum(slacks));
cp_model.Maximize(LinearExpr::Sum(slacks));
// Solving part.
const CpSolverResponse response = Solve(cp_model.Build());