add incremental constraint creation in CP-SAT C#
This commit is contained in:
@@ -89,11 +89,7 @@ public class GateSchedulingSat
|
||||
}
|
||||
|
||||
// Max Length constraint (modeled as a cumulative)
|
||||
CumulativeConstraint cumul = model.AddCumulative(max_length);
|
||||
foreach (var p in intervals.Zip(demands, (i, d) => new { Interval = i, Demand = d }))
|
||||
{
|
||||
cumul.AddDemand(p.Interval, p.Demand);
|
||||
}
|
||||
model.AddCumulative(max_length).AddDemands(intervals, demands);
|
||||
|
||||
// Choose which machine to perform the jobs on.
|
||||
model.AddNoOverlap(intervals0);
|
||||
|
||||
@@ -233,10 +233,7 @@ public class SatSolverTest
|
||||
model.Add(delta == x - 5);
|
||||
long[,] tuples = { { -5, 25 }, { -4, 16 }, { -3, 9 }, { -2, 4 }, { -1, 1 }, { 0, 0 },
|
||||
{ 1, 1 }, { 2, 4 }, { 3, 9 }, { 4, 16 }, { 5, 25 } };
|
||||
TableConstraint ct = model.AddAllowedAssignments(new IntVar[] { delta, squaredDelta });
|
||||
for (int i = 0; i < tuples.GetLength(0); ++i) {
|
||||
ct.AddTuple(new long[] { tuples[i, 0], tuples[i, 1]});
|
||||
}
|
||||
model.AddAllowedAssignments(new IntVar[] { delta, squaredDelta }).AddTuples(tuples);
|
||||
model.Minimize(squaredDelta);
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Google.OrTools.Sat
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public class Constraint
|
||||
{
|
||||
@@ -170,6 +171,56 @@ public class TableConstraint : Constraint
|
||||
throw new ArgumentException("addTuple", "tuple does not have the same length as the variables");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a set of tuple of possible/forbidden values to the constraint.
|
||||
*
|
||||
* @param tuples the set of tuples to add to the constraint.
|
||||
* @throws CpModel.WrongLength if tuples do not have the same length as the array of
|
||||
* variables of the constraint.
|
||||
*/
|
||||
public void AddTuples(int[,] tuples)
|
||||
{
|
||||
TableConstraintProto table = Proto.Table;
|
||||
|
||||
if (tuples.GetLength(1) != table.Vars.Count)
|
||||
{
|
||||
throw new ArgumentException("addTuples", "tuples does not have the same length as the variables");
|
||||
}
|
||||
|
||||
for (int i = 0; i < tuples.GetLength(0); ++i)
|
||||
{
|
||||
for (int j = 0; j < tuples.GetLength(1); ++j)
|
||||
{
|
||||
table.Values.Add(tuples[i, j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a set of tuple of possible/forbidden values to the constraint.
|
||||
*
|
||||
* @param tuples the set of tuples to add to the constraint.
|
||||
* @throws CpModel.WrongLength if tuples do not have the same length as the array of
|
||||
* variables of the constraint.
|
||||
*/
|
||||
public void AddTuples(long[,] tuples)
|
||||
{
|
||||
TableConstraintProto table = Proto.Table;
|
||||
|
||||
if (tuples.GetLength(1) != table.Vars.Count)
|
||||
{
|
||||
throw new ArgumentException("addTuples", "tuples does not have the same length as the variables");
|
||||
}
|
||||
|
||||
for (int i = 0; i < tuples.GetLength(0); ++i)
|
||||
{
|
||||
for (int j = 0; j < tuples.GetLength(1); ++j)
|
||||
{
|
||||
table.Values.Add(tuples[i, j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,6 +310,18 @@ public class CumulativeConstraint : Constraint
|
||||
cumul.Demands.Add(cp_model_.GetLinearExpressionProto(demandExpr));
|
||||
}
|
||||
|
||||
/// Adds all pairs (interval, demand) to the constraint.
|
||||
public void AddDemands<D>(IEnumerable<IntervalVar> intervals, IEnumerable<D> demands)
|
||||
{
|
||||
CumulativeConstraintProto cumul = Proto.Cumulative;
|
||||
foreach (var p in intervals.Zip(demands, (i, d) => new { Interval = i, Demand = d }))
|
||||
{
|
||||
cumul.Intervals.Add(p.Interval.GetIndex());
|
||||
LinearExpr demandExpr = cp_model_.GetLinearExpr(p.Demand);
|
||||
cumul.Demands.Add(cp_model_.GetLinearExpressionProto(demandExpr));
|
||||
}
|
||||
}
|
||||
|
||||
private CpModel cp_model_;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,28 +40,28 @@ public class AssignmentGroupsSat
|
||||
|
||||
// Allowed groups of workers:
|
||||
// [START allowed_groups]
|
||||
long[][] group1 = {
|
||||
new long[] { 0, 0, 1, 1 }, // Workers 2, 3
|
||||
new long[] { 0, 1, 0, 1 }, // Workers 1, 3
|
||||
new long[] { 0, 1, 1, 0 }, // Workers 1, 2
|
||||
new long[] { 1, 1, 0, 0 }, // Workers 0, 1
|
||||
new long[] { 1, 0, 1, 0 }, // Workers 0, 2
|
||||
long[,] group1 = {
|
||||
{ 0, 0, 1, 1 }, // Workers 2, 3
|
||||
{ 0, 1, 0, 1 }, // Workers 1, 3
|
||||
{ 0, 1, 1, 0 }, // Workers 1, 2
|
||||
{ 1, 1, 0, 0 }, // Workers 0, 1
|
||||
{ 1, 0, 1, 0 }, // Workers 0, 2
|
||||
};
|
||||
|
||||
long[][] group2 = {
|
||||
new long[] { 0, 0, 1, 1 }, // Workers 6, 7
|
||||
new long[] { 0, 1, 0, 1 }, // Workers 5, 7
|
||||
new long[] { 0, 1, 1, 0 }, // Workers 5, 6
|
||||
new long[] { 1, 1, 0, 0 }, // Workers 4, 5
|
||||
new long[] { 1, 0, 0, 1 }, // Workers 4, 7
|
||||
long[,] group2 = {
|
||||
{ 0, 0, 1, 1 }, // Workers 6, 7
|
||||
{ 0, 1, 0, 1 }, // Workers 5, 7
|
||||
{ 0, 1, 1, 0 }, // Workers 5, 6
|
||||
{ 1, 1, 0, 0 }, // Workers 4, 5
|
||||
{ 1, 0, 0, 1 }, // Workers 4, 7
|
||||
};
|
||||
|
||||
long[][] group3 = {
|
||||
new long[] { 0, 0, 1, 1 }, // Workers 10, 11
|
||||
new long[] { 0, 1, 0, 1 }, // Workers 9, 11
|
||||
new long[] { 0, 1, 1, 0 }, // Workers 9, 10
|
||||
new long[] { 1, 0, 1, 0 }, // Workers 8, 10
|
||||
new long[] { 1, 0, 0, 1 }, // Workers 8, 11
|
||||
long[,] group3 = {
|
||||
{ 0, 0, 1, 1 }, // Workers 10, 11
|
||||
{ 0, 1, 0, 1 }, // Workers 9, 11
|
||||
{ 0, 1, 1, 0 }, // Workers 9, 10
|
||||
{ 1, 0, 1, 0 }, // Workers 8, 10
|
||||
{ 1, 0, 0, 1 }, // Workers 8, 11
|
||||
};
|
||||
// [END allowed_groups]
|
||||
|
||||
@@ -127,21 +127,9 @@ public class AssignmentGroupsSat
|
||||
}
|
||||
|
||||
// Define the allowed groups of worders
|
||||
TableConstraint group1_ct = model.AddAllowedAssignments(new IntVar[] { work[0], work[1], work[2], work[3] });
|
||||
foreach (long[] tuple in group1)
|
||||
{
|
||||
group1_ct.AddTuple(tuple);
|
||||
}
|
||||
TableConstraint group2_ct = model.AddAllowedAssignments(new IntVar[] { work[4], work[5], work[6], work[7] });
|
||||
foreach (long[] tuple in group2)
|
||||
{
|
||||
group2_ct.AddTuple(tuple);
|
||||
}
|
||||
TableConstraint group3_ct = model.AddAllowedAssignments(new IntVar[] { work[8], work[9], work[10], work[11] });
|
||||
foreach (long[] tuple in group3)
|
||||
{
|
||||
group3_ct.AddTuple(tuple);
|
||||
}
|
||||
model.AddAllowedAssignments(new IntVar[] { work[0], work[1], work[2], work[3] }).AddTuples(group1);
|
||||
model.AddAllowedAssignments(new IntVar[] { work[4], work[5], work[6], work[7] }).AddTuples(group2);
|
||||
model.AddAllowedAssignments(new IntVar[] { work[8], work[9], work[10], work[11] }).AddTuples(group3);
|
||||
// [END assignments]
|
||||
|
||||
// Objective
|
||||
|
||||
Reference in New Issue
Block a user