diff --git a/examples/dotnet/BalanceGroupSat.cs b/examples/dotnet/BalanceGroupSat.cs index 97a1f5fdfa..f493f1b0fb 100644 --- a/examples/dotnet/BalanceGroupSat.cs +++ b/examples/dotnet/BalanceGroupSat.cs @@ -73,14 +73,14 @@ public class BalanceGroupSat foreach (var @group in allGroups) { var itemsInGroup = allItems.Select(x => itemInGroup[x, @group]).ToArray(); - model.AddLinearConstraint(itemsInGroup.Sum(), numItemsPerGroup, numItemsPerGroup); + model.AddLinearConstraint(LinearExpr.Sum(itemsInGroup), numItemsPerGroup, numItemsPerGroup); } //# One item must belong to exactly one group. foreach (var item in allItems) { var groupsForItem = allGroups.Select(x => itemInGroup[item, x]).ToArray(); - model.AddLinearConstraint(groupsForItem.Sum(), 1, 1); + model.AddLinearConstraint(LinearExpr.Sum(groupsForItem, 1, 1); } // The deviation of the sum of each items in a group against the average. @@ -91,7 +91,7 @@ public class BalanceGroupSat { var itemValues = allItems.Select(x => itemInGroup[x, @group]).ToArray(); - var sum = itemValues.ScalProd(values); + var sum = LinearExpr.ScalProd(itemValues, values); model.Add(sum <= averageSumPerGroup + e); model.Add(sum >= averageSumPerGroup - e); } @@ -123,7 +123,7 @@ public class BalanceGroupSat { var literal = colorInGroup[color, @group]; var items = itemsPerColor[color].Select(x => itemInGroup[x, @group]).ToArray(); - model.Add(items.Sum() >= minItemsOfSameColorPerGroup).OnlyEnforceIf(literal); + model.Add(LinearExpr.Sum(items >= minItemsOfSameColorPerGroup).OnlyEnforceIf(literal); } } @@ -135,7 +135,7 @@ public class BalanceGroupSat foreach (var @group in allGroups) { var all = allColors.Select(x => colorInGroup[x, @group]).ToArray(); - model.Add(all.Sum() <= maxColor); + model.Add(LinearExpr.Sum(all) <= maxColor); } } diff --git a/examples/dotnet/JobshopSat.cs b/examples/dotnet/JobshopSat.cs index 17b4beddde..395096446c 100644 --- a/examples/dotnet/JobshopSat.cs +++ b/examples/dotnet/JobshopSat.cs @@ -156,7 +156,7 @@ class JobshopSat // Adds no_overkap constraints on unary resources. for (int machineId = 0; machineId < machinesCount; ++machineId) { - model.AddNoOverlap(machinesToTasks[machineId].ToArray()); + model.AddNoOverlap(machinesToTasks[machineId]); } // Creates array of end_times of jobs. diff --git a/examples/dotnet/NetworkRoutingSat.cs b/examples/dotnet/NetworkRoutingSat.cs index 90a68e856d..dc2c436931 100644 --- a/examples/dotnet/NetworkRoutingSat.cs +++ b/examples/dotnet/NetworkRoutingSat.cs @@ -701,7 +701,7 @@ public class NetworkRoutingSat pathCount++; } - var pathCt = cpModel.AddAllowedAssignments(pathVars[demandIndex].ToArray(), tuples); + var pathCt = cpModel.AddAllowedAssignments(pathVars[demandIndex], tuples); } var trafficVars = new List(numArcs); @@ -724,14 +724,14 @@ public class NetworkRoutingSat traffics.Add(_demands[i].Traffic); } - var sum = vars.ToArray().ScalProd(traffics.ToArray()); + var sum = LinearExpr.ScalProd(vars, traffics); var trafficVar = cpModel.NewIntVar(0, sumOfTraffic, $"trafficVar{arcIndex}"); trafficVars.Add(trafficVar); cpModel.Add(sum == trafficVar); var capacity = _arcCapacity[arcIndex]; var scaledTraffic = cpModel.NewIntVar(0, sumOfTraffic * 1000, $"scaledTrafficVar{arcIndex}"); - var scaledTrafficVar = new[] {trafficVar}.ScalProd(new[] {1000}); + var scaledTrafficVar = traffic_var * 1000); cpModel.Add(scaledTrafficVar == scaledTraffic); var normalizedTraffic = @@ -752,7 +752,7 @@ public class NetworkRoutingSat var obj = new List() {maxUsageCost}; obj.AddRange(comfortableTrafficVars); - cpModel.Minimize(obj.ToArray().Sum()); + cpModel.Minimize(LinearExpr.Sum(obj)); CpSolver solver = new CpSolver(); solver.StringParameters = parameters; diff --git a/examples/dotnet/NursesSat.cs b/examples/dotnet/NursesSat.cs index 6580b610a1..727ba7eeb7 100644 --- a/examples/dotnet/NursesSat.cs +++ b/examples/dotnet/NursesSat.cs @@ -112,7 +112,7 @@ public class NursesSat { tmp[n] = shift[n, d, s]; } - model.Add(tmp.Sum() == 1); + model.Add(LinearExpr.Sum(tmp) == 1); } } @@ -126,7 +126,7 @@ public class NursesSat { tmp[s] = shift[n, d, s]; } - model.Add(tmp.Sum() == 1); + model.Add(LinearExpr.Sum(tmp) == 1); } } @@ -139,7 +139,7 @@ public class NursesSat { tmp[d] = shift[n, d, 0]; } - model.Add(1 <= tmp.Sum() <= 2); + model.AddLinearConstraint(LinearExpr.Sum(tmp), 1, 2); } // works_shift[(n, s)] is 1 if nurse n works shift s at least one day in @@ -169,7 +169,7 @@ public class NursesSat { tmp[n] = works_shift[n, s]; } - model.Add(tmp.Sum() <= 2); + model.Add(LinearExpr.Sum(tmp) <= 2); } // If a nurse works shifts 2 or 3 on, she must also work that diff --git a/examples/dotnet/ShiftSchedulingSat.cs b/examples/dotnet/ShiftSchedulingSat.cs index 720038220b..9a46d717af 100644 --- a/examples/dotnet/ShiftSchedulingSat.cs +++ b/examples/dotnet/ShiftSchedulingSat.cs @@ -151,7 +151,7 @@ public class ShiftSchedulingSat temp[s] = work[e, s, d]; } - model.Add(temp.Sum() == 1); + model.Add(LinearExpr.Sum(temp) == 1); } } @@ -261,7 +261,7 @@ public class ShiftSchedulingSat // Ignore off shift var minDemand = weeklyCoverDemands[d][s - 1]; var worked = model.NewIntVar(minDemand, numEmployees, ""); - model.Add(works.Sum() == worked); + model.Add(LinearExpr.Sum(works) == worked); var overPenalty = excessCoverPenalties[s - 1]; if (overPenalty > 0) @@ -277,8 +277,8 @@ public class ShiftSchedulingSat } // Objective - var objBoolSum = objBoolVars.ToArray().ScalProd(objBoolCoeffs.ToArray()); - var objIntSum = objIntVars.ToArray().ScalProd(objIntCoeffs.ToArray()); + var objBoolSum = LinearExpr.ScalProd(objBoolVars, objBoolCoeffs); + var objIntSum = LinearExpr.ScalProd(objIntVars, objIntCoeffs); model.Minimize(objBoolSum + objIntSum); @@ -494,7 +494,7 @@ public class ShiftSchedulingSat var costCoefficients = new List(); var sumVar = model.NewIntVar(hardMin, hardMax, ""); // This adds the hard constraints on the sum. - model.Add(sumVar == works.Sum()); + model.Add(sumVar == LinearExpr.Sum(works)); var zero = model.NewIntVar(0, 0, ""); diff --git a/examples/dotnet/SpeakerSchedulingSat.cs b/examples/dotnet/SpeakerSchedulingSat.cs index 916b6906a1..8359ad0cc9 100644 --- a/examples/dotnet/SpeakerSchedulingSat.cs +++ b/examples/dotnet/SpeakerSchedulingSat.cs @@ -121,12 +121,12 @@ class SpeakerScheduling } } } - model.Add(all_vars.ToArray().Sum() == 1); + model.Add(LinearExpr.Sum(all_vars) == 1); } // Force the schedule to be consistent. for (int slot = first_slot; slot <= last_slot; ++slot) { - model.Add(contributions_per_slot[slot].ToArray().Sum() <= 1); + model.Add(LinearExpr.Sum(contributions_per_slot[slot]) <= 1); } // Creates last_slot. diff --git a/examples/dotnet/TaskSchedulingSat.cs b/examples/dotnet/TaskSchedulingSat.cs index e6cfe13f7b..72a29f02ad 100644 --- a/examples/dotnet/TaskSchedulingSat.cs +++ b/examples/dotnet/TaskSchedulingSat.cs @@ -154,11 +154,11 @@ class TaskSchedulingSat { tasksToEquipment[t.Equipment] = new List(); tasksToEquipment[t.Equipment].Add(tasks[ti]); } - model.Add(tmp.Sum() == 1); + model.Add(LinearExpr.Sum(tmp) == 1); } foreach (KeyValuePair> pair in tasksToEquipment) { - model.AddNoOverlap(pair.Value.ToArray()); + model.AddNoOverlap(pair.Value); } IntVar makespan = model.NewIntVar(0, 100000, "makespan"); diff --git a/examples/tests/SatSolverTests.cs b/examples/tests/SatSolverTests.cs index 3ac1fdd34d..3c00f60f35 100644 --- a/examples/tests/SatSolverTests.cs +++ b/examples/tests/SatSolverTests.cs @@ -153,7 +153,7 @@ namespace Google.OrTools.Tests { IntVar v2 = model.NewIntVar(-10, 10, "v2"); model.Add(-100000 <= v1 + 2 * v2 <= 100000); model.Minimize(v1 - 2 * v2); - //Console.WriteLine("model = " + model.Model.ToString()); + Console.WriteLine("model = " + model.Model.ToString()); CpSolver solver = new CpSolver(); CpSolverStatus status = solver.Solve(model); diff --git a/ortools/sat/csharp/CpModel.cs b/ortools/sat/csharp/CpModel.cs index 1759245174..32e57ec956 100644 --- a/ortools/sat/csharp/CpModel.cs +++ b/ortools/sat/csharp/CpModel.cs @@ -69,16 +69,16 @@ namespace Google.OrTools.Sat return new IntVar(model_, new Domain(0, 1), name); } - public Constraint AddLinearConstraint(LinearExpression linear_expr, long lb, + public Constraint AddLinearConstraint(LinearExpr linear_expr, long lb, long ub) { return AddLinearExpressionInDomain(linear_expr, new Domain(lb, ub)); } - public Constraint AddLinearExpressionInDomain(LinearExpression linear_expr, Domain domain) + public Constraint AddLinearExpressionInDomain(LinearExpr linear_expr, Domain domain) { Dictionary dict = new Dictionary(); - long constant = LinearExpression.GetVarValueMap(linear_expr, 1L, dict); + long constant = LinearExpr.GetVarValueMap(linear_expr, 1L, dict); Constraint ct = new Constraint(model_); LinearConstraintProto linear = new LinearConstraintProto(); foreach (KeyValuePair term in dict) @@ -580,12 +580,12 @@ namespace Google.OrTools.Sat // Objective. - public void Minimize(LinearExpression obj) + public void Minimize(LinearExpr obj) { SetObjective(obj, true); } - public void Maximize(LinearExpression obj) + public void Maximize(LinearExpr obj) { SetObjective(obj, false); } @@ -613,7 +613,7 @@ namespace Google.OrTools.Sat // Internal methods. - void SetObjective(LinearExpression obj, bool minimize) + void SetObjective(LinearExpr obj, bool minimize) { CpObjectiveProto objective = new CpObjectiveProto(); if (obj is IntVar) @@ -634,7 +634,7 @@ namespace Google.OrTools.Sat else { Dictionary dict = new Dictionary(); - long constant = LinearExpression.GetVarValueMap(obj, 1L, dict); + long constant = LinearExpr.GetVarValueMap(obj, 1L, dict); if (minimize) { objective.ScalingFactor = 1L; diff --git a/ortools/sat/csharp/CpSolver.cs b/ortools/sat/csharp/CpSolver.cs index 326f5d7ddc..14adf94025 100644 --- a/ortools/sat/csharp/CpSolver.cs +++ b/ortools/sat/csharp/CpSolver.cs @@ -93,9 +93,9 @@ namespace Google.OrTools.Sat get { return response_; } } - public long Value(LinearExpression e) + public long Value(LinearExpr e) { - List exprs = new List(); + List exprs = new List(); List coeffs = new List(); exprs.Add(e); coeffs.Add(1L); @@ -103,7 +103,7 @@ namespace Google.OrTools.Sat while (exprs.Count > 0) { - LinearExpression expr = exprs[0]; + LinearExpr expr = exprs[0]; exprs.RemoveAt(0); long coeff = coeffs[0]; coeffs.RemoveAt(0); @@ -122,7 +122,7 @@ namespace Google.OrTools.Sat { SumArray a = (SumArray)expr; constant += coeff * a.Constant; - foreach (LinearExpression sub in a.Expressions) + foreach (LinearExpr sub in a.Expressions) { exprs.Add(sub); coeffs.Add(coeff); diff --git a/ortools/sat/csharp/IntegerExpressions.cs b/ortools/sat/csharp/IntegerExpressions.cs index 45de6a4f1a..278a0558ab 100644 --- a/ortools/sat/csharp/IntegerExpressions.cs +++ b/ortools/sat/csharp/IntegerExpressions.cs @@ -22,27 +22,17 @@ namespace Google.OrTools.Sat // IntVar[] helper class. public static class IntVarArrayHelper { - public static SumArray Sum(this IntVar[] vars) + public static LinearExpr Sum(this IntVar[] vars) { - return new SumArray(vars); + return LinearExpr.Sum(vars); } - public static SumArray ScalProd(this IntVar[] vars, int[] coeffs) + public static LinearExpr ScalProd(this IntVar[] vars, int[] coeffs) { - LinearExpression[] exprs = new LinearExpression[vars.Length]; - for (int i = 0; i < vars.Length; ++i) - { - exprs[i] = vars[i] * coeffs[i]; - } - return new SumArray(exprs); + return LinearExpr.ScalProd(vars, coeffs); } - public static SumArray ScalProd(this IntVar[] vars, long[] coeffs) + public static LinearExpr ScalProd(this IntVar[] vars, long[] coeffs) { - LinearExpression[] exprs = new LinearExpression[vars.Length]; - for (int i = 0; i < vars.Length; ++i) - { - exprs[i] = vars[i] * coeffs[i]; - } - return new SumArray(exprs); + return LinearExpr.ScalProd(vars, coeffs); } } @@ -53,9 +43,23 @@ namespace Google.OrTools.Sat } // Holds an linear expression. - public class LinearExpression + public class LinearExpr { + public static LinearExpr Sum(IEnumerable vars) + { + return new SumArray(vars); + } + + public static LinearExpr ScalProd(IEnumerable vars, IEnumerable coeffs) + { + return new SumArray(vars, coeffs); + } + public static LinearExpr ScalProd(IEnumerable vars, IEnumerable coeffs) + { + return new SumArray(vars, coeffs); + } + public int Index { get { return GetIndex(); } @@ -71,148 +75,132 @@ namespace Google.OrTools.Sat return ToString(); } - public static LinearExpression operator +(LinearExpression a, - LinearExpression b) + public static LinearExpr operator +(LinearExpr a, LinearExpr b) { return new SumArray(a, b); } - public static LinearExpression operator +(LinearExpression a, long v) + public static LinearExpr operator +(LinearExpr a, long v) { return new SumArray(a, v); } - public static LinearExpression operator +(long v, LinearExpression a) + public static LinearExpr operator +(long v, LinearExpr a) { return new SumArray(a, v); } - public static LinearExpression operator -(LinearExpression a, - LinearExpression b) + public static LinearExpr operator -(LinearExpr a, LinearExpr b) { return new SumArray(a, Prod(b, -1)); } - public static LinearExpression operator -(LinearExpression a, long v) + public static LinearExpr operator -(LinearExpr a, long v) { return new SumArray(a, -v); } - public static LinearExpression operator -(long v, LinearExpression a) + public static LinearExpr operator -(long v, LinearExpr a) { return new SumArray(Prod(a, -1), v); } - public static LinearExpression operator *(LinearExpression a, long v) + public static LinearExpr operator *(LinearExpr a, long v) { return Prod(a, v); } - public static LinearExpression operator *(long v, LinearExpression a) + public static LinearExpr operator *(long v, LinearExpr a) { return Prod(a, v); } - public static LinearExpression operator -(LinearExpression a) + public static LinearExpr operator -(LinearExpr a) { return Prod(a, -1); } - public static BoundedLinearExpression operator ==(LinearExpression a, - LinearExpression b) + public static BoundedLinearExpression operator ==(LinearExpr a, LinearExpr b) { return new BoundedLinearExpression(a, b, true); } - public static BoundedLinearExpression operator !=(LinearExpression a, - LinearExpression b) + public static BoundedLinearExpression operator !=(LinearExpr a, LinearExpr b) { return new BoundedLinearExpression(a, b, false); } - public static BoundedLinearExpression operator ==(LinearExpression a, - long v) + public static BoundedLinearExpression operator ==(LinearExpr a, long v) { return new BoundedLinearExpression(a, v, true); } - public static BoundedLinearExpression operator !=(LinearExpression a, - long v) + public static BoundedLinearExpression operator !=(LinearExpr a, long v) { return new BoundedLinearExpression(a, v, false); } - public static BoundedLinearExpression operator >=(LinearExpression a, - long v) + public static BoundedLinearExpression operator >=(LinearExpr a, long v) { return new BoundedLinearExpression(v, a, Int64.MaxValue); } - public static BoundedLinearExpression operator >=(long v, - LinearExpression a) + public static BoundedLinearExpression operator >=(long v, LinearExpr a) { return a <= v; } - public static BoundedLinearExpression operator >(LinearExpression a, - long v) + public static BoundedLinearExpression operator >(LinearExpr a, long v) { return new BoundedLinearExpression(v + 1, a, Int64.MaxValue); } - public static BoundedLinearExpression operator >(long v, LinearExpression a) + public static BoundedLinearExpression operator >(long v, LinearExpr a) { return a < v; } - public static BoundedLinearExpression operator <=(LinearExpression a, - long v) + public static BoundedLinearExpression operator <=(LinearExpr a, long v) { return new BoundedLinearExpression(Int64.MinValue, a, v); } - public static BoundedLinearExpression operator <=(long v, - LinearExpression a) + public static BoundedLinearExpression operator <=(long v, LinearExpr a) { return a >= v; } - public static BoundedLinearExpression operator <(LinearExpression a, - long v) + public static BoundedLinearExpression operator <(LinearExpr a, long v) { return new BoundedLinearExpression(Int64.MinValue, a, v - 1); } - public static BoundedLinearExpression operator <(long v, LinearExpression a) + public static BoundedLinearExpression operator <(long v, LinearExpr a) { return a > v; } - public static BoundedLinearExpression operator >=(LinearExpression a, - LinearExpression b) + public static BoundedLinearExpression operator >=(LinearExpr a, LinearExpr b) { return new BoundedLinearExpression(0, a - b, Int64.MaxValue); } - public static BoundedLinearExpression operator >(LinearExpression a, - LinearExpression b) + public static BoundedLinearExpression operator >(LinearExpr a, LinearExpr b) { return new BoundedLinearExpression(1, a - b, Int64.MaxValue); } - public static BoundedLinearExpression operator <=(LinearExpression a, - LinearExpression b) + public static BoundedLinearExpression operator <=(LinearExpr a, LinearExpr b) { return new BoundedLinearExpression(Int64.MinValue, a - b, 0); } - public static BoundedLinearExpression operator <(LinearExpression a, - LinearExpression b) + public static BoundedLinearExpression operator <(LinearExpr a, LinearExpr b) { return new BoundedLinearExpression(Int64.MinValue, a - b, -1); } - public static LinearExpression Prod(LinearExpression e, long v) + public static LinearExpr Prod(LinearExpr e, long v) { if (v == 1) { @@ -229,11 +217,11 @@ namespace Google.OrTools.Sat } } - public static long GetVarValueMap(LinearExpression e, + public static long GetVarValueMap(LinearExpr e, long initial_coeff, Dictionary dict) { - List exprs = new List(); + List exprs = new List(); List coeffs = new List(); exprs.Add(e); coeffs.Add(initial_coeff); @@ -241,7 +229,7 @@ namespace Google.OrTools.Sat while (exprs.Count > 0) { - LinearExpression expr = exprs[0]; + LinearExpr expr = exprs[0]; exprs.RemoveAt(0); long coeff = coeffs[0]; coeffs.RemoveAt(0); @@ -260,10 +248,13 @@ namespace Google.OrTools.Sat { SumArray a = (SumArray)expr; constant += coeff * a.Constant; - foreach (LinearExpression sub in a.Expressions) + foreach (LinearExpr sub in a.Expressions) { exprs.Add(sub); - coeffs.Add(coeff); + } + foreach (long c in a.Coefficients) + { + coeffs.Add(coeff * c); } } else if (expr is IntVar) @@ -294,15 +285,15 @@ namespace Google.OrTools.Sat } } - public class ProductCst : LinearExpression + public class ProductCst : LinearExpr { - public ProductCst(LinearExpression e, long v) + public ProductCst(LinearExpr e, long v) { expr_ = e; coeff_ = v; } - public LinearExpression Expr + public LinearExpr Expr { get { return expr_; } } @@ -312,64 +303,160 @@ namespace Google.OrTools.Sat get { return coeff_; } } - private LinearExpression expr_; + private LinearExpr expr_; private long coeff_; } - public class SumArray : LinearExpression + public class SumArray : LinearExpr { - public SumArray(LinearExpression a, LinearExpression b) + public SumArray(LinearExpr a, LinearExpr b) { - expressions_ = new List(); - expressions_.Add(a); - expressions_.Add(b); + Init(2); + AddExpr(a, 0); + AddExpr(b, 1); constant_ = 0L; } - public SumArray(LinearExpression a, long b) + public SumArray(LinearExpr a, long b) { - expressions_ = new List(); - expressions_.Add(a); + Init(1); + AddExpr(a, 0); constant_ = b; } - public SumArray(IEnumerable exprs) + public SumArray(IEnumerable exprs) { - expressions_ = new List(); - foreach (LinearExpression e in exprs) + int count = FindLength(exprs); + Init(count); + int index = 0; + foreach (LinearExpr e in exprs) { - if (e != null) - { - expressions_.Add(e); - } + AddExpr(e, index); + index++; } constant_ = 0L; } - public SumArray(IEnumerable exprs, long cte) + public SumArray(IEnumerable vars) { - expressions_ = new List(); - foreach (LinearExpression e in exprs) + int count = FindLength(vars); + Init(count); + int index = 0; + foreach (IntVar v in vars) { - if (e != null) - { - expressions_.Add(e); - } + AddExpr(v, index); + index++; } - constant_ = cte; + constant_ = 0L; + } + + public SumArray(IEnumerable vars, IEnumerable coeffs) + { + int count = FindLength(vars); + Init(count); + // Fill the coefficients; + int index = 0; + foreach (int c in coeffs) + { + coefficients_[index] = c; + index++; + } + // Add terms, reading the filled coefficients. + index = 0; + foreach (LinearExpr v in vars) + { + AddTerm(v, coefficients_[index], index); + index++; + } + constant_ = 0L; + } + + public SumArray(IEnumerable vars, IEnumerable coeffs) + { + int count = FindLength(vars); + Init(count); + // Fill the coefficients; + int index = 0; + foreach (int c in coeffs) + { + coefficients_[index] = c; + index++; + } + // Add terms, reading the filled coefficients. + index = 0; + foreach (LinearExpr v in vars) + { + AddTerm(v, coefficients_[index], index); + index++; + } + constant_ = 0L; } - public List Expressions + public void AddExpr(LinearExpr expr, int index) { + if (expr is ProductCst) + { + ProductCst p = (ProductCst)expr; + expressions_[index] = p.Expr; + coefficients_[index] = p.Coeff; + } + else + { + expressions_[index] = expr; + coefficients_[index] = 1; + } + } + + public void AddTerm(LinearExpr expr, long coeff, int index) { + if (expr is ProductCst) + { + ProductCst p = (ProductCst)expr; + expressions_[index] = p.Expr; + coefficients_[index] = p.Coeff * coeff; + } + else + { + expressions_[index] = expr; + coefficients_[index] = coeff; + } + } + + public LinearExpr[] Expressions { get { return expressions_; } } + public long[] Coefficients + { + get { return coefficients_; } + } + public long Constant { get { return constant_; } } + void Init(int size) { + expressions_ = new LinearExpr[size]; + coefficients_ = new long[size]; + } + + int FindLength(IEnumerable exprs) { + int count = 0; + foreach (LinearExpr e in exprs) { + count++; + } + return count; + } + + int FindLength(IEnumerable vars) { + int count = 0; + foreach (IntVar v in vars) { + count++; + } + return count; + } + public override string ShortString() { return String.Format("({0})", ToString()); @@ -378,16 +465,16 @@ namespace Google.OrTools.Sat public override string ToString() { string result = ""; - for (int i = 0; i < expressions_.Count; ++i) + for (int i = 0; i < expressions_.Length; ++i) { - bool negated = false; - LinearExpression expr = expressions_[i]; + LinearExpr expr = expressions_[i]; + long coeff = coefficients_[i]; if (i != 0) { - if (expr is ProductCst && ((ProductCst)expr).Coeff < 0) + if (coeff < 0) { result += String.Format(" - "); - negated = true; + coeff = -coeff; } else { @@ -395,42 +482,29 @@ namespace Google.OrTools.Sat } } - if (expr is IntVar) + if (coeff == 1) { result += expr.ShortString(); } - else if (expr is ProductCst) + else if (coeff == -1) { - ProductCst p = (ProductCst)expr; - long coeff = negated ? -p.Coeff : p.Coeff; - LinearExpression sub = p.Expr; - if (coeff == 1) - { - result += sub.ShortString(); - } - else if (coeff == -1) - { - result += String.Format("-{0}", coeff, sub.ShortString()); - } - else - { - result += String.Format("{0}*{1}", coeff, sub.ShortString()); - } + result += String.Format("-{0}", expr); } else { - result += String.Format("({0})", expr.ShortString()); + result += String.Format("{0}*{1}", coeff, expr); } } return result; } - private List expressions_; + private LinearExpr[] expressions_; + private long[] coefficients_; private long constant_; } - public class IntVar : LinearExpression, ILiteral + public class IntVar : LinearExpr, ILiteral { public IntVar(CpModelProto model, Domain domain, string name) { @@ -506,7 +580,7 @@ namespace Google.OrTools.Sat private NotBooleanVariable negation_; } - public class NotBooleanVariable : LinearExpression, ILiteral + public class NotBooleanVariable : LinearExpr, ILiteral { public NotBooleanVariable(IntVar boolvar) { @@ -542,7 +616,7 @@ namespace Google.OrTools.Sat VarDiffCst, } - public BoundedLinearExpression(long lb, LinearExpression expr, long ub) + public BoundedLinearExpression(long lb, LinearExpr expr, long ub) { left_ = expr; right_ = null; @@ -551,7 +625,7 @@ namespace Google.OrTools.Sat type_ = Type.BoundExpression; } - public BoundedLinearExpression(LinearExpression left, LinearExpression right, + public BoundedLinearExpression(LinearExpr left, LinearExpr right, bool equality) { left_ = left; @@ -561,7 +635,7 @@ namespace Google.OrTools.Sat type_ = equality ? Type.VarEqVar : Type.VarDiffVar; } - public BoundedLinearExpression(LinearExpression left, long v, bool equality) + public BoundedLinearExpression(LinearExpr left, long v, bool equality) { left_ = left; right_ = null; @@ -656,12 +730,12 @@ namespace Google.OrTools.Sat return new BoundedLinearExpression(v + 1, a.Left, a.Ub); } - public LinearExpression Left + public LinearExpr Left { get { return left_; } } - public LinearExpression Right + public LinearExpr Right { get { return right_; } } @@ -681,8 +755,8 @@ namespace Google.OrTools.Sat get { return type_; } } - private LinearExpression left_; - private LinearExpression right_; + private LinearExpr left_; + private LinearExpr right_; private long lb_; private long ub_; private Type type_; diff --git a/ortools/sat/csharp/SearchHelpers.cs b/ortools/sat/csharp/SearchHelpers.cs index ad3c4f933a..8741bfb716 100644 --- a/ortools/sat/csharp/SearchHelpers.cs +++ b/ortools/sat/csharp/SearchHelpers.cs @@ -19,9 +19,9 @@ namespace Google.OrTools.Sat public class CpSolverSolutionCallback : SolutionCallback { - public long Value(LinearExpression e) + public long Value(LinearExpr e) { - List exprs = new List(); + List exprs = new List(); List coeffs = new List(); exprs.Add(e); coeffs.Add(1L); @@ -29,7 +29,7 @@ namespace Google.OrTools.Sat while (exprs.Count > 0) { - LinearExpression expr = exprs[0]; + LinearExpr expr = exprs[0]; exprs.RemoveAt(0); long coeff = coeffs[0]; coeffs.RemoveAt(0); @@ -48,7 +48,7 @@ namespace Google.OrTools.Sat { SumArray a = (SumArray)expr; constant += coeff * a.Constant; - foreach (LinearExpression sub in a.Expressions) + foreach (LinearExpr sub in a.Expressions) { exprs.Add(sub); coeffs.Add(coeff); diff --git a/ortools/sat/samples/BinPackingProblemSat.cs b/ortools/sat/samples/BinPackingProblemSat.cs index 0bf1613f84..47e27295c6 100644 --- a/ortools/sat/samples/BinPackingProblemSat.cs +++ b/ortools/sat/samples/BinPackingProblemSat.cs @@ -78,7 +78,7 @@ public class BinPackingProblemSat { tmp[b] = x[i, b]; } - model.Add(tmp.Sum() == items[i, 1]); + model.Add(LinearExpr.Sum(tmp) == items[i, 1]); } // Links load and slack. @@ -92,7 +92,7 @@ public class BinPackingProblemSat } // Maximize sum of slacks. - model.Maximize(slacks.Sum()); + model.Maximize(LinearExpr.Sum(slacks)); // Solves and prints out the solution. CpSolver solver = new CpSolver(); diff --git a/ortools/sat/samples/RankingSampleSat.cs b/ortools/sat/samples/RankingSampleSat.cs index 1935eebce4..246af0ce91 100644 --- a/ortools/sat/samples/RankingSampleSat.cs +++ b/ortools/sat/samples/RankingSampleSat.cs @@ -54,7 +54,7 @@ public class RankingSampleSat // The following bool_or will enforce that for any two intervals: // i precedes j or j precedes i or at least one interval is not // performed. - model.AddBoolOr(tmp_array.ToArray()); + model.AddBoolOr(tmp_array); // Redundant constraint: it propagates early that at most one precedence // is true. model.AddImplication(precedences[i, j], precedences[j, i].Not()); @@ -68,7 +68,7 @@ public class RankingSampleSat for (int j = 0; j < num_tasks; ++j) { tmp_array[j] = (IntVar)precedences[j, i]; } - model.Add(ranks[i] == tmp_array.Sum() - 1); + model.Add(ranks[i] == LinearExpr.Sum(tmp_array) - 1); } } @@ -129,7 +129,7 @@ public class RankingSampleSat for (int t = 0; t < num_tasks; ++t) { presences_as_int_vars[t] = (IntVar)presences[t]; } - model.Minimize(2 * makespan - 7 * presences_as_int_vars.Sum()); + model.Minimize(2 * makespan - 7 * LinearExpr.Sum(presences_as_int_vars)); // Creates a solver and solves the model. CpSolver solver = new CpSolver();