Skip to content

Commit

Permalink
[CP-SAT] add support for element with affine expressions in C# + test
Browse files Browse the repository at this point in the history
  • Loading branch information
lperron committed Oct 18, 2024
1 parent 80087b8 commit 1177061
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
41 changes: 24 additions & 17 deletions ortools/sat/csharp/CpModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,19 +233,19 @@ public Constraint AddAllDifferent(IEnumerable<LinearExpr> exprs)

/**
* <summary>
* Adds the element constraint: <c>variables[index] == target</c>.
* Adds the element constraint: <c>exprs[index] == target</c>.
* </summary>
*/
public Constraint AddElement(IntVar index, IEnumerable<IntVar> vars, IntVar target)
public Constraint AddElement(LinearExpr index, IEnumerable<LinearExpr> exprs, LinearExpr target)
{
ElementConstraintProto element = new ElementConstraintProto();
element.Index = index.Index;
element.Vars.TrySetCapacity(vars);
foreach (IntVar var in vars)
element.LinearIndex = GetLinearExpressionProto(index);
element.Exprs.TrySetCapacity(exprs);
foreach (LinearExpr expr in exprs)
{
element.Vars.Add(var.Index);
element.Exprs.Add(GetLinearExpressionProto(expr));
}
element.Target = target.Index;
element.LinearTarget = GetLinearExpressionProto(target);

Constraint ct = new Constraint(model_);
ct.Proto.Element = element;
Expand All @@ -257,16 +257,16 @@ public Constraint AddElement(IntVar index, IEnumerable<IntVar> vars, IntVar targ
* Adds the element constraint: <c> values[index] == target</c>.
* </summary>
*/
public Constraint AddElement(IntVar index, IEnumerable<long> values, IntVar target)
public Constraint AddElement(LinearExpr index, IEnumerable<long> values, LinearExpr target)
{
ElementConstraintProto element = new ElementConstraintProto();
element.Index = index.Index;
element.Vars.TrySetCapacity(values);
element.LinearIndex = GetLinearExpressionProto(index);
element.Exprs.TrySetCapacity(values);
foreach (long value in values)
{
element.Vars.Add(ConvertConstant(value));
element.Exprs.Add(GetLinearExpressionProto(value));
}
element.Target = target.Index;
element.LinearTarget = GetLinearExpressionProto(target);

Constraint ct = new Constraint(model_);
ct.Proto.Element = element;
Expand All @@ -278,16 +278,16 @@ public Constraint AddElement(IntVar index, IEnumerable<long> values, IntVar targ
* Adds the element constraint: <c> values[index] == target</c>.
* </summary>
*/
public Constraint AddElement(IntVar index, IEnumerable<int> values, IntVar target)
public Constraint AddElement(LinearExpr index, IEnumerable<int> values, LinearExpr target)
{
ElementConstraintProto element = new ElementConstraintProto();
element.Index = index.Index;
element.Vars.TrySetCapacity(values);
element.LinearIndex = GetLinearExpressionProto(index);
element.Exprs.TrySetCapacity(values);
foreach (int value in values)
{
element.Vars.Add(ConvertConstant(value));
element.Exprs.Add(GetLinearExpressionProto(value));
}
element.Target = target.Index;
element.LinearTarget = GetLinearExpressionProto(target);

Constraint ct = new Constraint(model_);
ct.Proto.Element = element;
Expand Down Expand Up @@ -1258,6 +1258,13 @@ internal LinearExpressionProto GetLinearExpressionProto(LinearExpr expr, bool ne
return linear;
}

internal LinearExpressionProto GetLinearExpressionProto(long value)
{
LinearExpressionProto linear = new LinearExpressionProto();
linear.Offset = value;
return linear;
}

private CpModelProto model_;
private Dictionary<long, int> constant_map_;
private Dictionary<int, long> var_value_map_;
Expand Down
22 changes: 22 additions & 0 deletions ortools/sat/csharp/SatSolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,28 @@ public void Modulo()
// Console.WriteLine("response = " + response.ToString());
}

[Fact]
public void ValueElement()
{
CpModel model = new CpModel();
IntVar v1 = model.NewIntVar(1, 10, "v1");
IntVar v2 = model.NewIntVar(1, 10, "v2");
model.AddElement(v1 + 2, new int[] {1, 3, 5}, 5 - v2);
Assert.Equal(3, model.Model.Constraints[0].Element.Exprs.Count);
}

public void ExprElement()
{
CpModel model = new CpModel();
IntVar v1 = model.NewIntVar(1, 10, "v1");
IntVar v2 = model.NewIntVar(1, 10, "v2");
IntVar x = model.NewIntVar(0, 5, "x");
IntVar y = model.NewIntVar(0, 5, "y");
IntVar z = model.NewIntVar(0, 5, "z");
model.AddElement(v1, new LinearExpr[] {x + 2, -y, LinearExpr.Constant(5), 2 * z}, 5 - v2);
Assert.Equal(4, model.Model.Constraints[0].Element.Exprs.Count);
}

[Fact]
public void LargeWeightedSumLong()
{
Expand Down

0 comments on commit 1177061

Please sign in to comment.