[CP-SAT] ScalProd -> WeightedSum
This commit is contained in:
@@ -304,7 +304,7 @@ void AddAlternativeTaskDurationRelaxation(
|
||||
cp_model.AddEquality(
|
||||
tasks[t].end,
|
||||
tasks[t].start +
|
||||
LinearExpr::ScalProd(presence_literals, shifted_durations) +
|
||||
LinearExpr::WeightedSum(presence_literals, shifted_durations) +
|
||||
min_duration);
|
||||
}
|
||||
}
|
||||
@@ -452,9 +452,9 @@ 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::ScalProd(literals, transitions) + tail.fixed_duration);
|
||||
cp_model.AddEquality(tail.interval.SizeExpr(),
|
||||
LinearExpr::WeightedSum(literals, transitions) +
|
||||
tail.fixed_duration);
|
||||
}
|
||||
}
|
||||
LOG(INFO) << "Machine " << m
|
||||
@@ -540,11 +540,12 @@ void CreateObjective(
|
||||
problem.scaling_factor().value());
|
||||
}
|
||||
cp_model.Minimize(
|
||||
DoubleLinearExpr::ScalProd(objective_vars, double_objective_coeffs) +
|
||||
DoubleLinearExpr::WeightedSum(objective_vars, double_objective_coeffs) +
|
||||
static_cast<double>(objective_offset));
|
||||
} else {
|
||||
cp_model.Minimize(LinearExpr::ScalProd(objective_vars, objective_coeffs) +
|
||||
objective_offset);
|
||||
cp_model.Minimize(
|
||||
LinearExpr::WeightedSum(objective_vars, objective_coeffs) +
|
||||
objective_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ 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::ScalProd(var_domains[j], values),
|
||||
cp_model.AddEquality(LinearExpr::WeightedSum(var_domains[j], values),
|
||||
LinearExpr::Sum(vars_equal_to_j));
|
||||
}
|
||||
|
||||
|
||||
@@ -80,10 +80,11 @@ 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::ScalProd(items_in_bins[b], weights),
|
||||
builder.AddEquality(LinearExpr::WeightedSum(items_in_bins[b], weights),
|
||||
bin_weight);
|
||||
builder.AddLinearConstraint(LinearExpr::ScalProd(items_in_bins[b], volumes),
|
||||
{kVolumeMin, kVolumeMax});
|
||||
builder.AddLinearConstraint(
|
||||
LinearExpr::WeightedSum(items_in_bins[b], volumes),
|
||||
{kVolumeMin, kVolumeMax});
|
||||
}
|
||||
|
||||
// Each item is selected at most one time.
|
||||
|
||||
@@ -91,7 +91,7 @@ public class BalanceGroupSat
|
||||
{
|
||||
var itemValues = allItems.Select(x => itemInGroup[x, @group]).ToArray();
|
||||
|
||||
var sum = LinearExpr.ScalProd(itemValues, values);
|
||||
var sum = LinearExpr.WeightedSum(itemValues, values);
|
||||
model.Add(sum <= averageSumPerGroup + e);
|
||||
model.Add(sum >= averageSumPerGroup - e);
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ public class NetworkRoutingSat
|
||||
traffics.Add(_demands[i].Traffic);
|
||||
}
|
||||
|
||||
var sum = LinearExpr.ScalProd(vars, traffics);
|
||||
var sum = LinearExpr.WeightedSum(vars, traffics);
|
||||
var trafficVar = cpModel.NewIntVar(0, sumOfTraffic, $"trafficVar{arcIndex}");
|
||||
trafficVars.Add(trafficVar);
|
||||
cpModel.Add(sum == trafficVar);
|
||||
|
||||
@@ -253,8 +253,8 @@ public class ShiftSchedulingSat
|
||||
}
|
||||
|
||||
// Objective
|
||||
var objBoolSum = LinearExpr.ScalProd(objBoolVars, objBoolCoeffs);
|
||||
var objIntSum = LinearExpr.ScalProd(objIntVars, objIntCoeffs);
|
||||
var objBoolSum = LinearExpr.WeightedSum(objBoolVars, objBoolCoeffs);
|
||||
var objIntSum = LinearExpr.WeightedSum(objIntVars, objIntCoeffs);
|
||||
|
||||
model.Minimize(objBoolSum + objIntSum);
|
||||
|
||||
|
||||
@@ -1922,7 +1922,7 @@ def bus_driver_scheduling(minimize_drivers, max_num_drivers):
|
||||
model.Add(
|
||||
cp_model.LinearExpr.Sum(working_times) == total_driving_time +
|
||||
num_drivers * (setup_time + cleanup_time) +
|
||||
cp_model.LinearExpr.ScalProd(delay_literals, delay_weights))
|
||||
cp_model.LinearExpr.WeightedSum(delay_literals, delay_weights))
|
||||
|
||||
if minimize_drivers:
|
||||
# Minimize the number of working drivers
|
||||
@@ -1931,7 +1931,7 @@ def bus_driver_scheduling(minimize_drivers, max_num_drivers):
|
||||
# Minimize the sum of delays between tasks, which in turns minimize the
|
||||
# sum of working times as the total driving time is fixed
|
||||
model.Minimize(
|
||||
cp_model.LinearExpr.ScalProd(delay_literals, delay_weights))
|
||||
cp_model.LinearExpr.WeightedSum(delay_literals, delay_weights))
|
||||
|
||||
if not minimize_drivers and FLAGS.output_proto:
|
||||
print('Writing proto to %s' % FLAGS.output_proto)
|
||||
|
||||
@@ -127,7 +127,7 @@ def solve_with_duplicate_items(data, max_height, max_width):
|
||||
model.AddNoOverlap2D(x_intervals, y_intervals)
|
||||
|
||||
## Objective.
|
||||
model.Maximize(cp_model.LinearExpr.ScalProd(is_used, item_values))
|
||||
model.Maximize(cp_model.LinearExpr.WeightedSum(is_used, item_values))
|
||||
|
||||
# Output proto to file.
|
||||
if FLAGS.output_proto:
|
||||
@@ -217,7 +217,7 @@ def solve_with_duplicate_optional_items(data, max_height, max_width):
|
||||
model.AddNoOverlap2D(x_intervals, y_intervals)
|
||||
|
||||
## Objective.
|
||||
model.Maximize(cp_model.LinearExpr.ScalProd(is_used, item_values))
|
||||
model.Maximize(cp_model.LinearExpr.WeightedSum(is_used, item_values))
|
||||
|
||||
# Output proto to file.
|
||||
if FLAGS.output_proto:
|
||||
@@ -330,7 +330,7 @@ def solve_with_rotations(data, max_height, max_width):
|
||||
model.AddNoOverlap2D(x_intervals, y_intervals)
|
||||
|
||||
# Objective.
|
||||
model.Maximize(cp_model.LinearExpr.ScalProd(is_used, item_values))
|
||||
model.Maximize(cp_model.LinearExpr.WeightedSum(is_used, item_values))
|
||||
|
||||
# Output proto to file.
|
||||
if FLAGS.output_proto:
|
||||
|
||||
@@ -288,7 +288,7 @@ def solve_shift_scheduling(params, output_proto):
|
||||
# Exactly one shift per day.
|
||||
for e in range(num_employees):
|
||||
for d in range(num_days):
|
||||
model.Add(sum(work[e, s, d] for s in range(num_shifts)) == 1)
|
||||
model.AddExactlyOne([work[e, s, d] for s in range(num_shifts)])
|
||||
|
||||
# Fixed assignments.
|
||||
for e, s, d in fixed_assignments:
|
||||
|
||||
@@ -156,7 +156,7 @@ public final class LinearExprTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinearExpr_scalProd() {
|
||||
public void testLinearExpr_weightedSum() {
|
||||
final CpModel model = new CpModel();
|
||||
assertNotNull(model);
|
||||
final Domain domain = new Domain(0, 10);
|
||||
@@ -193,7 +193,7 @@ public final class LinearExprTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinearExpr_booleanScalProd() {
|
||||
public void testLinearExpr_booleanWeightedSum() {
|
||||
final CpModel model = new CpModel();
|
||||
assertNotNull(model);
|
||||
final Literal x = model.newBoolVar("x");
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace Google.OrTools.Tests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeScalProdLong()
|
||||
public void LargeWeightedSumLong()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
@@ -304,14 +304,14 @@ namespace Google.OrTools.Tests
|
||||
}
|
||||
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.ScalProd(vars, coeffs));
|
||||
model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Long: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeScalProdInt()
|
||||
public void LargeWeightedSumInt()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
@@ -324,14 +324,14 @@ namespace Google.OrTools.Tests
|
||||
}
|
||||
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.ScalProd(vars, coeffs));
|
||||
model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Int: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeScalProdExpr()
|
||||
public void LargeWeightedSumExpr()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<LinearExpr> exprs = new List<LinearExpr>();
|
||||
@@ -349,7 +349,7 @@ namespace Google.OrTools.Tests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeScalProdProto()
|
||||
public void LargeWeightedSumProto()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
@@ -388,7 +388,7 @@ namespace Google.OrTools.Tests
|
||||
public void SolveFromString()
|
||||
{
|
||||
string model_str = @"
|
||||
{
|
||||
{
|
||||
""variables"": [
|
||||
{ ""name"": ""C"", ""domain"": [ ""1"", ""9"" ] },
|
||||
{ ""name"": ""P"", ""domain"": [ ""0"", ""9"" ] },
|
||||
|
||||
@@ -923,7 +923,7 @@ public final class CpModel {
|
||||
public void minimize(DoubleLinearExpr expr) {
|
||||
FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
|
||||
for (int i = 0; i < expr.numElements(); ++i) {
|
||||
obj.addVars(expr.getVariable(i).getIndex()).addCoeffs(expr.getCoefficient(i));
|
||||
obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
|
||||
}
|
||||
obj.setOffset(expr.getOffset()).setMaximize(false);
|
||||
}
|
||||
@@ -942,7 +942,7 @@ public final class CpModel {
|
||||
public void maximize(DoubleLinearExpr expr) {
|
||||
FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
|
||||
for (int i = 0; i < expr.numElements(); ++i) {
|
||||
obj.addVars(expr.getVariable(i).getIndex()).addCoeffs(expr.getCoefficient(i));
|
||||
obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
|
||||
}
|
||||
obj.setOffset(expr.getOffset()).setMaximize(true);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ package com.google.ortools.sat;
|
||||
|
||||
/** A linear expression interface that can be parsed. */
|
||||
public class DoubleLinearExpr {
|
||||
private final IntVar[] variables;
|
||||
private final int[] variableIndices;
|
||||
private final double[] coefficients;
|
||||
private double offset;
|
||||
|
||||
@@ -24,49 +24,49 @@ public class DoubleLinearExpr {
|
||||
return sumWithOffset(variables, 0.0);
|
||||
}
|
||||
|
||||
/** Creates a sum expression. */
|
||||
static DoubleLinearExpr sum(Literal[] literals) {
|
||||
// We need the scalar product for the negative coefficient of negated Boolean variables.
|
||||
return sumWithOffset(literals, 0.0);
|
||||
}
|
||||
|
||||
/** Creates a sum expression with a double offset. */
|
||||
static DoubleLinearExpr sumWithOffset(IntVar[] variables, double offset) {
|
||||
return new DoubleLinearExpr(variables, offset);
|
||||
}
|
||||
|
||||
/** Creates a sum expression. */
|
||||
static DoubleLinearExpr booleanSum(Literal[] literals) {
|
||||
// We need the scalar product for the negative coefficient of negated Boolean variables.
|
||||
return booleanSumWithOffset(literals, 0.0);
|
||||
}
|
||||
|
||||
/** Creates a sum expression with a double offset. */
|
||||
static DoubleLinearExpr booleanSumWithOffset(Literal[] literals, double offset) {
|
||||
static DoubleLinearExpr sumWithOffset(Literal[] literals, double offset) {
|
||||
// We need the scalar product for the negative coefficient of negated Boolean variables.
|
||||
return new DoubleLinearExpr(literals, offset);
|
||||
}
|
||||
|
||||
/** Creates a scalar product. */
|
||||
static DoubleLinearExpr scalProd(IntVar[] variables, double[] coefficients) {
|
||||
return scalProdWithOffset(variables, coefficients, 0.0);
|
||||
static DoubleLinearExpr weightedSum(IntVar[] variables, double[] coefficients) {
|
||||
return weightedSumWithOffset(variables, coefficients, 0.0);
|
||||
}
|
||||
|
||||
/** Creates a scalar product. */
|
||||
static DoubleLinearExpr scalProdWithOffset(
|
||||
static DoubleLinearExpr weightedSum(Literal[] literals, double[] coefficients) {
|
||||
return weightedSumWithOffset(literals, coefficients, 0.0);
|
||||
}
|
||||
|
||||
/** Creates a scalar product. */
|
||||
static DoubleLinearExpr weightedSumWithOffset(
|
||||
IntVar[] variables, double[] coefficients, double offset) {
|
||||
if (variables.length != coefficients.length) {
|
||||
throw new CpModel.MismatchedArrayLengths(
|
||||
"DoubleLinearExpr.scalProd", "variables", "coefficients");
|
||||
"DoubleLinearExpr.weightedSum", "variables", "coefficients");
|
||||
}
|
||||
return new DoubleLinearExpr(variables, coefficients, offset);
|
||||
}
|
||||
|
||||
/** Creates a scalar product. */
|
||||
static DoubleLinearExpr booleanScalProd(Literal[] literals, double[] coefficients) {
|
||||
return booleanScalProdWithOffset(literals, coefficients, 0.0);
|
||||
}
|
||||
|
||||
/** Creates a scalar product with a double offset. */
|
||||
static DoubleLinearExpr booleanScalProdWithOffset(
|
||||
static DoubleLinearExpr weightedSumWithOffset(
|
||||
Literal[] literals, double[] coefficients, double offset) {
|
||||
if (literals.length != coefficients.length) {
|
||||
throw new CpModel.MismatchedArrayLengths(
|
||||
"DoubleLinearExpr.scalProd", "literals", "coefficients");
|
||||
"DoubleLinearExpr.weightedSum", "literals", "coefficients");
|
||||
}
|
||||
return new DoubleLinearExpr(literals, coefficients, offset);
|
||||
}
|
||||
@@ -98,20 +98,20 @@ public class DoubleLinearExpr {
|
||||
|
||||
/** Returns the number of elements in the interface. */
|
||||
public int numElements() {
|
||||
return variables.length;
|
||||
return variableIndices.length;
|
||||
}
|
||||
|
||||
/** Returns the ith variable. */
|
||||
public IntVar getVariable(int index) {
|
||||
if (index < 0 || index >= variables.length) {
|
||||
public int getVariableIndex(int index) {
|
||||
if (index < 0 || index >= variableIndices.length) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getVariable(): " + index);
|
||||
}
|
||||
return variables[index];
|
||||
return variableIndices[index];
|
||||
}
|
||||
|
||||
/** Returns the ith coefficient. */
|
||||
public double getCoefficient(int index) {
|
||||
if (index < 0 || index >= variables.length) {
|
||||
if (index < 0 || index >= variableIndices.length) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getCoefficient(): " + index);
|
||||
}
|
||||
return coefficients[index];
|
||||
@@ -123,14 +123,17 @@ public class DoubleLinearExpr {
|
||||
}
|
||||
|
||||
public DoubleLinearExpr(IntVar[] variables, double[] coefficients, double offset) {
|
||||
this.variables = variables;
|
||||
this.variableIndices = new int[variables.length];
|
||||
for (int i = 0; i < variables.length; ++i) {
|
||||
this.variableIndices[i] = variables[i].getIndex();
|
||||
}
|
||||
this.coefficients = coefficients;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public DoubleLinearExpr(Literal[] literals, double[] coefficients, double offset) {
|
||||
int size = literals.length;
|
||||
this.variables = new IntVar[size];
|
||||
this.variableIndices = new int[size];
|
||||
this.coefficients = new double[size];
|
||||
this.offset = offset;
|
||||
|
||||
@@ -138,10 +141,10 @@ public class DoubleLinearExpr {
|
||||
Literal lit = literals[i];
|
||||
double coeff = coefficients[i];
|
||||
if (lit.getIndex() >= 0) {
|
||||
this.variables[i] = (IntVar) lit;
|
||||
this.variableIndices[i] = lit.getIndex();
|
||||
this.coefficients[i] = coeff;
|
||||
} else {
|
||||
this.variables[i] = (IntVar) lit.not();
|
||||
this.variableIndices[i] = lit.not().getIndex();
|
||||
this.coefficients[i] = -coeff;
|
||||
this.offset -= coeff;
|
||||
}
|
||||
@@ -149,18 +152,18 @@ public class DoubleLinearExpr {
|
||||
}
|
||||
|
||||
public DoubleLinearExpr(IntVar var, double coefficient, double offset) {
|
||||
this.variables = new IntVar[] {var};
|
||||
this.variableIndices = new int[] {var.getIndex()};
|
||||
this.coefficients = new double[] {coefficient};
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public DoubleLinearExpr(Literal lit, double coefficient, double offset) {
|
||||
if (lit.getIndex() >= 0) {
|
||||
this.variables = new IntVar[] {(IntVar) lit};
|
||||
this.variableIndices = new int[] {lit.getIndex()};
|
||||
this.coefficients = new double[] {coefficient};
|
||||
this.offset = offset;
|
||||
} else {
|
||||
this.variables = new IntVar[] {(IntVar) lit.not()};
|
||||
this.variableIndices = new int[] {lit.not().getIndex()};
|
||||
this.coefficients = new double[] {-coefficient};
|
||||
this.offset = offset + coefficient;
|
||||
}
|
||||
@@ -168,29 +171,29 @@ public class DoubleLinearExpr {
|
||||
|
||||
public DoubleLinearExpr(IntVar[] vars, double offset) {
|
||||
int size = vars.length;
|
||||
this.variables = new IntVar[size];
|
||||
this.variableIndices = new int[size];
|
||||
this.coefficients = new double[size];
|
||||
this.offset = offset;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
this.variables[i] = vars[i];
|
||||
this.variableIndices[i] = vars[i].getIndex();
|
||||
this.coefficients[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public DoubleLinearExpr(Literal[] literals, double offset) {
|
||||
int size = literals.length;
|
||||
this.variables = new IntVar[size];
|
||||
this.variableIndices = new int[size];
|
||||
this.coefficients = new double[size];
|
||||
this.offset = offset;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
Literal lit = literals[i];
|
||||
if (lit.getIndex() >= 0) {
|
||||
this.variables[i] = (IntVar) lit;
|
||||
this.variableIndices[i] = lit.getIndex();
|
||||
this.coefficients[i] = 1;
|
||||
} else { // NotBooleanVar.
|
||||
this.variables[i] = (IntVar) lit.not();
|
||||
} else { // NotBoolVar.
|
||||
this.variableIndices[i] = lit.not().getIndex();
|
||||
this.coefficients[i] = -1.0;
|
||||
this.offset -= 1.0;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
|
||||
package com.google.ortools.sat;
|
||||
|
||||
/** A object that can build a LinearExpr object. */
|
||||
/**
|
||||
* A object that can build a LinearExpr object.
|
||||
*
|
||||
* <p>This class is used in all modeling methods of the CpModel class.
|
||||
*/
|
||||
public interface LinearArgument {
|
||||
/** Builds a linear expression. */
|
||||
LinearExpr build();
|
||||
|
||||
@@ -202,8 +202,8 @@ LinearExpr LinearExpr::Sum(absl::Span<const BoolVar> vars) {
|
||||
return result;
|
||||
}
|
||||
|
||||
LinearExpr LinearExpr::ScalProd(absl::Span<const IntVar> vars,
|
||||
absl::Span<const int64_t> coeffs) {
|
||||
LinearExpr LinearExpr::WeightedSum(absl::Span<const IntVar> vars,
|
||||
absl::Span<const int64_t> coeffs) {
|
||||
CHECK_EQ(vars.size(), coeffs.size());
|
||||
LinearExpr result;
|
||||
for (int i = 0; i < vars.size(); ++i) {
|
||||
@@ -212,8 +212,8 @@ LinearExpr LinearExpr::ScalProd(absl::Span<const IntVar> vars,
|
||||
return result;
|
||||
}
|
||||
|
||||
LinearExpr LinearExpr::ScalProd(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const int64_t> coeffs) {
|
||||
LinearExpr LinearExpr::WeightedSum(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) {
|
||||
@@ -222,8 +222,8 @@ LinearExpr LinearExpr::ScalProd(absl::Span<const BoolVar> vars,
|
||||
return result;
|
||||
}
|
||||
|
||||
LinearExpr LinearExpr::ScalProd(std::initializer_list<IntVar> vars,
|
||||
absl::Span<const int64_t> coeffs) {
|
||||
LinearExpr LinearExpr::WeightedSum(std::initializer_list<IntVar> vars,
|
||||
absl::Span<const int64_t> coeffs) {
|
||||
CHECK_EQ(vars.size(), coeffs.size());
|
||||
LinearExpr result;
|
||||
int count = 0;
|
||||
@@ -253,8 +253,8 @@ LinearExpr LinearExpr::BooleanSum(absl::Span<const BoolVar> vars) {
|
||||
return result;
|
||||
}
|
||||
|
||||
LinearExpr LinearExpr::BooleanScalProd(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const int64_t> coeffs) {
|
||||
LinearExpr LinearExpr::BooleanWeightedSum(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) {
|
||||
@@ -386,8 +386,8 @@ DoubleLinearExpr DoubleLinearExpr::Sum(absl::Span<const BoolVar> vars) {
|
||||
return result;
|
||||
}
|
||||
|
||||
DoubleLinearExpr DoubleLinearExpr::ScalProd(absl::Span<const IntVar> vars,
|
||||
absl::Span<const double> coeffs) {
|
||||
DoubleLinearExpr DoubleLinearExpr::WeightedSum(
|
||||
absl::Span<const IntVar> vars, absl::Span<const double> coeffs) {
|
||||
CHECK_EQ(vars.size(), coeffs.size());
|
||||
DoubleLinearExpr result;
|
||||
for (int i = 0; i < vars.size(); ++i) {
|
||||
@@ -396,8 +396,8 @@ DoubleLinearExpr DoubleLinearExpr::ScalProd(absl::Span<const IntVar> vars,
|
||||
return result;
|
||||
}
|
||||
|
||||
DoubleLinearExpr DoubleLinearExpr::ScalProd(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const double> coeffs) {
|
||||
DoubleLinearExpr DoubleLinearExpr::WeightedSum(
|
||||
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) {
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
IntVar pheasants = cp_model.NewIntVar(all_animals).WithName("pheasants");
|
||||
|
||||
cp_model.AddEquality(LinearExpr::Sum({rabbits, pheasants}), 20);
|
||||
cp_model.AddEquality(LinearExpr::ScalProd({rabbits, pheasants}, {4, 2}), 56);
|
||||
cp_model.AddEquality(LinearExpr::WeightedSum({rabbits, pheasants}, {4, 2}),
|
||||
56);
|
||||
|
||||
const CpSolverResponse response = Solve(cp_model.Build());
|
||||
if (response.status() == CpSolverStatus::FEASIBLE) {
|
||||
@@ -260,17 +261,17 @@ class LinearExpr {
|
||||
static LinearExpr Sum(absl::Span<const BoolVar> vars);
|
||||
|
||||
/// Constructs the scalar product of variables and coefficients.
|
||||
static LinearExpr ScalProd(absl::Span<const IntVar> vars,
|
||||
absl::Span<const int64_t> coeffs);
|
||||
static LinearExpr WeightedSum(absl::Span<const IntVar> vars,
|
||||
absl::Span<const int64_t> coeffs);
|
||||
|
||||
/// Constructs the scalar product of Boolean variables and coefficients.
|
||||
static LinearExpr ScalProd(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const int64_t> coeffs);
|
||||
static LinearExpr WeightedSum(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);
|
||||
static LinearExpr WeightedSum(std::initializer_list<IntVar> vars,
|
||||
absl::Span<const int64_t> coeffs);
|
||||
|
||||
/// Constructs var * coefficient.
|
||||
static LinearExpr Term(IntVar var, int64_t coefficient);
|
||||
@@ -281,9 +282,9 @@ class LinearExpr {
|
||||
/// Deprecated. Use Sum() instead.
|
||||
static LinearExpr BooleanSum(absl::Span<const BoolVar> vars);
|
||||
|
||||
/// Deprecated. Use ScalProd() instead.
|
||||
static LinearExpr BooleanScalProd(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const int64_t> coeffs);
|
||||
/// Deprecated. Use WeightedSum() instead.
|
||||
static LinearExpr BooleanWeightedSum(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const int64_t> coeffs);
|
||||
|
||||
/// Constructs a linear expr from its proto representation.
|
||||
static LinearExpr FromProto(const LinearExpressionProto& proto);
|
||||
@@ -348,14 +349,14 @@ std::ostream& operator<<(std::ostream& os, const LinearExpr& e);
|
||||
// e2 = x + y + 5
|
||||
DoubleLinearExpr e2 = DoubleLinearExpr::Sum({x, y}).AddConstant(5.0);
|
||||
// e3 = 2 * x - y
|
||||
DoubleLinearExpr e3 = DoubleLinearExpr::ScalProd({x, y}, {2, -1});
|
||||
DoubleLinearExpr e3 = DoubleLinearExpr::WeightedSum({x, y}, {2, -1});
|
||||
DoubleLinearExpr e4(b); // e4 = b.
|
||||
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::Sum(bools); // e6 = b + 1 - c;
|
||||
// e7 = -3.0 * b + 1.5 - 1.5 * c;
|
||||
DoubleLinearExpr e7 = DoubleLinearExpr::ScalProd(bools, {-3.0, 1.5});
|
||||
DoubleLinearExpr e7 = DoubleLinearExpr::WeightedSum(bools, {-3.0, 1.5});
|
||||
\endcode
|
||||
* This can be used in the objective definition.
|
||||
* \code
|
||||
@@ -410,12 +411,12 @@ class DoubleLinearExpr {
|
||||
static DoubleLinearExpr Sum(absl::Span<const BoolVar> vars);
|
||||
|
||||
/// Constructs the scalar product of variables and coefficients.
|
||||
static DoubleLinearExpr ScalProd(absl::Span<const IntVar> vars,
|
||||
absl::Span<const double> coeffs);
|
||||
static DoubleLinearExpr WeightedSum(absl::Span<const IntVar> vars,
|
||||
absl::Span<const double> coeffs);
|
||||
|
||||
/// Constructs the scalar product of Boolean variables and coefficients.
|
||||
static DoubleLinearExpr ScalProd(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const double> coeffs);
|
||||
static DoubleLinearExpr WeightedSum(absl::Span<const BoolVar> vars,
|
||||
absl::Span<const double> coeffs);
|
||||
|
||||
/// Returns the vector of variable indices.
|
||||
const std::vector<int>& variables() const { return variables_; }
|
||||
|
||||
@@ -17,28 +17,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Google.OrTools.Util;
|
||||
|
||||
// Helpers.
|
||||
|
||||
// IntVar[] helper class.
|
||||
public static class IntVarArrayHelper
|
||||
{
|
||||
[Obsolete("This Sum method is deprecated, please use LinearExpr.Sum() instead.")]
|
||||
public static LinearExpr Sum(this IntVar[] vars)
|
||||
{
|
||||
return LinearExpr.Sum(vars);
|
||||
}
|
||||
[Obsolete("This ScalProd method is deprecated, please use LinearExpr.ScalProd() instead.")]
|
||||
public static LinearExpr ScalProd(this IntVar[] vars, int[] coeffs)
|
||||
{
|
||||
return LinearExpr.ScalProd(vars, coeffs);
|
||||
}
|
||||
[Obsolete("This ScalProd method is deprecated, please use LinearExpr.ScalProd() instead.")]
|
||||
public static LinearExpr ScalProd(this IntVar[] vars, long[] coeffs)
|
||||
{
|
||||
return LinearExpr.ScalProd(vars, coeffs);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ILiteral
|
||||
{
|
||||
ILiteral Not();
|
||||
@@ -58,12 +36,12 @@ public class LinearExpr
|
||||
return new SumArray(exprs);
|
||||
}
|
||||
|
||||
public static LinearExpr ScalProd(IEnumerable<IntVar> vars, IEnumerable<int> coeffs)
|
||||
public static LinearExpr WeightedSum(IEnumerable<IntVar> vars, IEnumerable<int> coeffs)
|
||||
{
|
||||
return new SumArray(vars, coeffs);
|
||||
}
|
||||
|
||||
public static LinearExpr ScalProd(IEnumerable<IntVar> vars, IEnumerable<long> coeffs)
|
||||
public static LinearExpr WeightedSum(IEnumerable<IntVar> vars, IEnumerable<long> coeffs)
|
||||
{
|
||||
return new SumArray(vars, coeffs);
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ public class BinPackingProblemSat
|
||||
{
|
||||
tmp[i] = x[i, b];
|
||||
}
|
||||
model.Add(load[b] == LinearExpr.ScalProd(tmp, sizes));
|
||||
model.Add(load[b] == LinearExpr.WeightedSum(tmp, sizes));
|
||||
}
|
||||
|
||||
// Place all items.
|
||||
|
||||
@@ -96,7 +96,8 @@ type is not uniform across languages.
|
||||
### Other methods
|
||||
|
||||
To exclude a single value, use ranges combined with int64min and int64max
|
||||
values, e.g., `[[int64min, -3], [-1, int64max]]`, or use the `Complement` method.
|
||||
values, e.g., `[[int64min, -3], [-1, int64max]]`, or use the `Complement`
|
||||
method.
|
||||
|
||||
To create a variable with a single value domain, use the `NewConstant()` API (or
|
||||
`newConstant()` in Java).
|
||||
@@ -106,13 +107,13 @@ To create a variable with a single value domain, use the `NewConstant()` API (or
|
||||
### C++ and Java linear constraints and linear expressions
|
||||
|
||||
**C++** and **Java** APIs do not use arithmetic operators (+, \*, -, <=...).
|
||||
Linear constraints are created using a method of the model factory, such as
|
||||
Linear constraints are created using a method of the model factory, such as
|
||||
`cp_model.AddEquality(x, 3)` in C++, or `cp_model.addGreaterOrEqual(x, 10)` in
|
||||
Java.
|
||||
|
||||
Furthermore, helper methods can be used to create sums and scalar products like
|
||||
`LinearExpr::Sum({x, y, z})` in C++, and `LinearExpr.scalProd(new IntVar[] {x,
|
||||
y, z}, new long[] {1, 2, 3})` in Java.
|
||||
`LinearExpr::Sum({x, y, z})` in C++, and `LinearExpr.weightedSum(new IntVar[]
|
||||
{x, y, z}, new long[] {1, 2, 3})` in Java.
|
||||
|
||||
### Python and C\# linear constraints and linear expressions
|
||||
|
||||
@@ -122,9 +123,9 @@ y, z}, new long[] {1, 2, 3})` in Java.
|
||||
|
||||
### Generic linear constraint
|
||||
|
||||
in **all languages**, the cp_model factory offers a generic method to constrain a
|
||||
linear expression to be in a domain. This is used in the step function examples
|
||||
below.
|
||||
in **all languages**, the cp_model factory offers a generic method to constrain
|
||||
a linear expression to be in a domain. This is used in the step function
|
||||
examples below.
|
||||
|
||||
### Limitations
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ public class SolutionHintingSampleSat
|
||||
model.AddHint(x, 1);
|
||||
model.AddHint(y, 2);
|
||||
|
||||
model.Maximize(LinearExpr.ScalProd(new IntVar[] { x, y, z }, new int[] { 1, 2, 3 }));
|
||||
model.Maximize(LinearExpr.WeightedSum(new IntVar[] { x, y, z }, new int[] { 1, 2, 3 }));
|
||||
|
||||
// Creates a solver and solves the model.
|
||||
CpSolver solver = new CpSolver();
|
||||
|
||||
@@ -172,7 +172,7 @@ class LinearExpr(object):
|
||||
|
||||
```
|
||||
model.Minimize(cp_model.LinearExpr.Sum(expressions))
|
||||
model.Add(cp_model.LinearExpr.ScalProd(expressions, coefficients) >= 0)
|
||||
model.Add(cp_model.LinearExpr.WeightedSum(expressions, coefficients) >= 0)
|
||||
```
|
||||
"""
|
||||
|
||||
@@ -184,14 +184,14 @@ class LinearExpr(object):
|
||||
return _SumArray(expressions)
|
||||
|
||||
@classmethod
|
||||
def ScalProd(cls, expressions, coefficients):
|
||||
def WeightedSum(cls, expressions, coefficients):
|
||||
"""Creates the expression sum(expressions[i] * coefficients[i])."""
|
||||
if LinearExpr.IsEmptyOrAllNull(coefficients):
|
||||
return 0
|
||||
elif len(expressions) == 1:
|
||||
return expressions[0] * coefficients[0]
|
||||
else:
|
||||
return _ScalProd(expressions, coefficients)
|
||||
return _WeightedSum(expressions, coefficients)
|
||||
|
||||
@classmethod
|
||||
def Term(cls, expression, coefficient):
|
||||
@@ -229,7 +229,7 @@ class LinearExpr(object):
|
||||
if all_ones:
|
||||
return _SumArray(variables, offset)
|
||||
else:
|
||||
return _ScalProd(variables, coeffs, offset)
|
||||
return _WeightedSum(variables, coeffs, offset)
|
||||
|
||||
def GetIntegerVarValueMap(self):
|
||||
"""Scans the expression, and returns (var_coef_map, constant)."""
|
||||
@@ -250,7 +250,7 @@ class LinearExpr(object):
|
||||
for e in expr.Expressions():
|
||||
to_process.append((e, coeff))
|
||||
constant += expr.Constant() * coeff
|
||||
elif isinstance(expr, _ScalProd):
|
||||
elif isinstance(expr, _WeightedSum):
|
||||
for e, c in zip(expr.Expressions(), expr.Coefficients()):
|
||||
to_process.append((e, coeff * c))
|
||||
constant += expr.Constant() * coeff
|
||||
@@ -285,7 +285,7 @@ class LinearExpr(object):
|
||||
for e in expr.Expressions():
|
||||
to_process.append((e, coeff))
|
||||
constant += expr.Constant() * coeff
|
||||
elif isinstance(expr, _ScalProd):
|
||||
elif isinstance(expr, _WeightedSum):
|
||||
for e, c in zip(expr.Expressions(), expr.Coefficients()):
|
||||
to_process.append((e, coeff * c))
|
||||
constant += expr.Constant() * coeff
|
||||
@@ -547,8 +547,8 @@ class _SumArray(LinearExpr):
|
||||
return self.__constant
|
||||
|
||||
|
||||
class _ScalProd(LinearExpr):
|
||||
"""Represents the scalar product of expressions with constants and a constant."""
|
||||
class _WeightedSum(LinearExpr):
|
||||
"""Represents sum(ai * xi) + b."""
|
||||
|
||||
def __init__(self, expressions, coefficients, constant=0):
|
||||
self.__expressions = []
|
||||
@@ -556,7 +556,7 @@ class _ScalProd(LinearExpr):
|
||||
self.__constant = constant
|
||||
if len(expressions) != len(coefficients):
|
||||
raise TypeError(
|
||||
'In the LinearExpr.ScalProd method, the expression array and the '
|
||||
'In the LinearExpr.WeightedSum method, the expression array and the '
|
||||
' coefficient array must have the same length.')
|
||||
for e, c in zip(expressions, coefficients):
|
||||
c = cmh.assert_is_a_number(c)
|
||||
@@ -597,7 +597,7 @@ class _ScalProd(LinearExpr):
|
||||
return output
|
||||
|
||||
def __repr__(self):
|
||||
return 'ScalProd([{}], [{}], {})'.format(
|
||||
return 'WeightedSum([{}], [{}], {})'.format(
|
||||
', '.join(map(repr, self.__expressions)),
|
||||
', '.join(map(repr, self.__coefficients)), self.__constant)
|
||||
|
||||
@@ -2090,7 +2090,7 @@ def EvaluateLinearExpr(expression, solution):
|
||||
for e in expr.Expressions():
|
||||
to_process.append((e, coeff))
|
||||
value += expr.Constant() * coeff
|
||||
elif isinstance(expr, _ScalProd):
|
||||
elif isinstance(expr, _WeightedSum):
|
||||
for e, c in zip(expr.Expressions(), expr.Coefficients()):
|
||||
to_process.append((e, coeff * c))
|
||||
value += expr.Constant() * coeff
|
||||
@@ -2362,7 +2362,7 @@ class CpSolverSolutionCallback(pywrapsat.SolutionCallback):
|
||||
for e in expr.Expressions():
|
||||
to_process.append((e, coeff))
|
||||
value += expr.Constant() * coeff
|
||||
elif isinstance(expr, _ScalProd):
|
||||
elif isinstance(expr, _WeightedSum):
|
||||
for e, c in zip(expr.Expressions(), expr.Coefficients()):
|
||||
to_process.append((e, coeff * c))
|
||||
value += expr.Constant() * coeff
|
||||
|
||||
@@ -139,7 +139,7 @@ public class AssignmentGroupsSat
|
||||
|
||||
// Objective
|
||||
// [START objective]
|
||||
model.Minimize(LinearExpr.ScalProd(xFlat, costsFlat));
|
||||
model.Minimize(LinearExpr.WeightedSum(xFlat, costsFlat));
|
||||
// [END objective]
|
||||
|
||||
// Solve
|
||||
|
||||
@@ -80,7 +80,7 @@ public class AssignmentSat
|
||||
|
||||
// Objective
|
||||
// [START objective]
|
||||
model.Minimize(LinearExpr.ScalProd(xFlat, costsFlat));
|
||||
model.Minimize(LinearExpr.WeightedSum(xFlat, costsFlat));
|
||||
// [END objective]
|
||||
|
||||
// Solve
|
||||
|
||||
@@ -76,7 +76,7 @@ public class AssignmentTaskSizesSat
|
||||
{
|
||||
vars[task] = x[worker, task];
|
||||
}
|
||||
model.Add(LinearExpr.ScalProd(vars, taskSizes) <= totalSizeMax);
|
||||
model.Add(LinearExpr.WeightedSum(vars, taskSizes) <= totalSizeMax);
|
||||
}
|
||||
|
||||
// Each task is assigned to exactly one worker.
|
||||
@@ -93,7 +93,7 @@ public class AssignmentTaskSizesSat
|
||||
|
||||
// Objective
|
||||
// [START objective]
|
||||
model.Minimize(LinearExpr.ScalProd(xFlat, costsFlat));
|
||||
model.Minimize(LinearExpr.WeightedSum(xFlat, costsFlat));
|
||||
// [END objective]
|
||||
|
||||
// Solve
|
||||
|
||||
@@ -112,7 +112,7 @@ public class AssignmentTeamsSat
|
||||
|
||||
// Objective
|
||||
// [START objective]
|
||||
model.Minimize(LinearExpr.ScalProd(xFlat, costsFlat));
|
||||
model.Minimize(LinearExpr.WeightedSum(xFlat, costsFlat));
|
||||
// [END objective]
|
||||
|
||||
// Solve
|
||||
|
||||
@@ -67,7 +67,7 @@ public class BinPackingProblemSat
|
||||
{
|
||||
tmp[i] = x[i, b];
|
||||
}
|
||||
model.Add(load[b] == LinearExpr.ScalProd(tmp, sizes));
|
||||
model.Add(load[b] == LinearExpr.WeightedSum(tmp, sizes));
|
||||
}
|
||||
|
||||
// Place all items.
|
||||
|
||||
@@ -74,7 +74,7 @@ public class MultipleKnapsackSat
|
||||
{
|
||||
vars[i] = x[i, b];
|
||||
}
|
||||
model.Add(LinearExpr.ScalProd(vars, Weights) <= BinCapacities[b]);
|
||||
model.Add(LinearExpr.WeightedSum(vars, Weights) <= BinCapacities[b]);
|
||||
}
|
||||
// [END constraints]
|
||||
|
||||
@@ -91,7 +91,7 @@ public class MultipleKnapsackSat
|
||||
objectiveValues[k] = Values[i];
|
||||
}
|
||||
}
|
||||
model.Maximize(LinearExpr.ScalProd(objectiveVars, objectiveValues));
|
||||
model.Maximize(LinearExpr.WeightedSum(objectiveVars, objectiveValues));
|
||||
// [END objective]
|
||||
|
||||
// Solve
|
||||
|
||||
@@ -181,7 +181,7 @@ public class ScheduleRequestsSat
|
||||
}
|
||||
}
|
||||
}
|
||||
model.Maximize(LinearExpr.ScalProd(flatShifts, flatShiftRequests));
|
||||
model.Maximize(LinearExpr.WeightedSum(flatShifts, flatShiftRequests));
|
||||
// [END objective]
|
||||
|
||||
// Solve
|
||||
|
||||
@@ -73,7 +73,7 @@ public class SolutionHintingSampleSat
|
||||
model.AddHint(y, 2);
|
||||
|
||||
// [START objective]
|
||||
model.Maximize(LinearExpr.ScalProd(new IntVar[] { x, y, z }, new int[] { 1, 2, 3 }));
|
||||
model.Maximize(LinearExpr.WeightedSum(new IntVar[] { x, y, z }, new int[] { 1, 2, 3 }));
|
||||
// [END objective]
|
||||
|
||||
// Creates a solver and solves the model.
|
||||
|
||||
Reference in New Issue
Block a user