DotNet Reference

.Net Reference

CpModel.cs
Go to the documentation of this file.
1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 namespace Google.OrTools.Sat
15 {
16 using System;
17 using System.Collections.Generic;
18 using Google.OrTools.Util;
19 
23 public class CpModel
24 {
25  public CpModel()
26  {
27  model_ = new CpModelProto();
28  constant_map_ = new Dictionary<long, int>();
29  }
30 
31  // Getters.
32 
38  public CpModelProto Model
39  {
40  get {
41  return model_;
42  }
43  }
44 
45  int Negated(int index)
46  {
47  return -index - 1;
48  }
49 
50  // Integer variables and constraints.
51 
62  public IntVar NewIntVar(long lb, long ub, string name)
63  {
64  return new IntVar(model_, lb, ub, name);
65  }
66 
76  public IntVar NewIntVarFromDomain(Domain domain, string name)
77  {
78  return new IntVar(model_, domain, name);
79  }
80 
86  public IntVar NewConstant(long value)
87  {
88  return new IntVar(model_, ConvertConstant(value));
89  }
90 
96  public BoolVar NewBoolVar(string name)
97  {
98  return new BoolVar(model_, name);
99  }
100 
107  {
108  return true_literal_ ??= new BoolVar(model_, ConvertConstant(1));
109  }
110 
117  {
118  return TrueLiteral().Not();
119  }
120 
121  private long FillLinearConstraint(LinearExpr expr, out LinearConstraintProto linear)
122  {
123  linear = new LinearConstraintProto();
124  Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>();
125  long constant = LinearExpr.GetVarValueMap(expr, 1L, dict);
126  var count = dict.Count;
127  linear.Vars.Capacity = count;
128  linear.Coeffs.Capacity = count;
129  foreach (KeyValuePair<IntVar, long> term in dict)
130  {
131  linear.Vars.Add(term.Key.Index);
132  linear.Coeffs.Add(term.Value);
133  }
134  return constant;
135  }
141  public Constraint AddLinearConstraint(LinearExpr expr, long lb, long ub)
142  {
143  long constant = FillLinearConstraint(expr, out var linear);
144  linear.Domain.Capacity = 2;
145  linear.Domain.Add(lb is Int64.MinValue or Int64.MaxValue ? lb : lb - constant);
146  linear.Domain.Add(ub is Int64.MinValue or Int64.MaxValue ? ub : ub - constant);
147 
148  Constraint ct = new Constraint(model_);
149  ct.Proto.Linear = linear;
150  return ct;
151  }
152 
159  {
160  long constant = FillLinearConstraint(expr, out var linear);
161  var array = domain.FlattenedIntervals();
162  linear.Domain.Capacity = array.Length;
163  foreach (long value in array)
164  {
165  linear.Domain.Add(value is Int64.MinValue or Int64.MaxValue ? value : value - constant);
166  }
167 
168  Constraint ct = new Constraint(model_);
169  ct.Proto.Linear = linear;
170  return ct;
171  }
172 
173  private Constraint AddLinearExpressionNotEqualCst(LinearExpr expr, long value)
174  {
175  long constant = FillLinearConstraint(expr, out var linear);
176  linear.Domain.Capacity = 4;
177  linear.Domain.Add(Int64.MinValue);
178  linear.Domain.Add(value - constant - 1);
179  linear.Domain.Add(value - constant + 1);
180  linear.Domain.Add(Int64.MaxValue);
181 
182  Constraint ct = new Constraint(model_);
183  ct.Proto.Linear = linear;
184  return ct;
185  }
186 
193  {
194  switch (lin.CtType)
195  {
196  case BoundedLinearExpression.Type.BoundExpression: {
197  return AddLinearConstraint(lin.Left, lin.Lb, lin.Ub);
198  }
199  case BoundedLinearExpression.Type.VarEqVar: {
200  return AddLinearConstraint(lin.Left - lin.Right, 0, 0);
201  }
202  case BoundedLinearExpression.Type.VarDiffVar: {
203  return AddLinearExpressionNotEqualCst(lin.Left - lin.Right, 0);
204  }
205  case BoundedLinearExpression.Type.VarEqCst: {
206  return AddLinearConstraint(lin.Left, lin.Lb, lin.Lb);
207  }
208  case BoundedLinearExpression.Type.VarDiffCst: {
209  return AddLinearExpressionNotEqualCst(lin.Left, lin.Lb);
210  }
211  }
212  return null;
213  }
214 
220  public Constraint AddAllDifferent(IEnumerable<LinearExpr> exprs)
221  {
223  alldiff.Exprs.TrySetCapacity(exprs);
224  foreach (LinearExpr expr in exprs)
225  {
226  alldiff.Exprs.Add(GetLinearExpressionProto(expr));
227  }
228 
229  Constraint ct = new Constraint(model_);
230  ct.Proto.AllDiff = alldiff;
231  return ct;
232  }
233 
239  public Constraint AddElement(IntVar index, IEnumerable<IntVar> vars, IntVar target)
240  {
242  element.Index = index.Index;
243  element.Vars.TrySetCapacity(vars);
244  foreach (IntVar var in vars)
245  {
246  element.Vars.Add(var.Index);
247  }
248  element.Target = target.Index;
249 
250  Constraint ct = new Constraint(model_);
251  ct.Proto.Element = element;
252  return ct;
253  }
254 
260  public Constraint AddElement(IntVar index, IEnumerable<long> values, IntVar target)
261  {
263  element.Index = index.Index;
264  element.Vars.TrySetCapacity(values);
265  foreach (long value in values)
266  {
267  element.Vars.Add(ConvertConstant(value));
268  }
269  element.Target = target.Index;
270 
271  Constraint ct = new Constraint(model_);
272  ct.Proto.Element = element;
273  return ct;
274  }
275 
281  public Constraint AddElement(IntVar index, IEnumerable<int> values, IntVar target)
282  {
284  element.Index = index.Index;
285  element.Vars.TrySetCapacity(values);
286  foreach (int value in values)
287  {
288  element.Vars.Add(ConvertConstant(value));
289  }
290  element.Target = target.Index;
291 
292  Constraint ct = new Constraint(model_);
293  ct.Proto.Element = element;
294  return ct;
295  }
296 
308  {
309  CircuitConstraint ct = new CircuitConstraint(model_);
311  return ct;
312  }
313 
326  {
329  return ct;
330  }
331 
347  public TableConstraint AddAllowedAssignments(IEnumerable<IntVar> vars)
348  {
350  table.Vars.TrySetCapacity(vars);
351  foreach (IntVar var in vars)
352  {
353  table.Vars.Add(var.Index);
354  }
355 
356  TableConstraint ct = new TableConstraint(model_);
357  ct.Proto.Table = table;
358  return ct;
359  }
360 
375  public TableConstraint AddForbiddenAssignments(IEnumerable<IntVar> vars)
376  {
378  ct.Proto.Table.Negated = true;
379  return ct;
380  }
381 
415  public AutomatonConstraint AddAutomaton(IEnumerable<IntVar> vars, long starting_state,
416  IEnumerable<long> final_states)
417  {
419  aut.Vars.TrySetCapacity(vars);
420  foreach (IntVar var in vars)
421  {
422  aut.Vars.Add(var.Index);
423  }
424 
425  aut.StartingState = starting_state;
426  aut.FinalStates.AddRange(final_states);
427 
428  AutomatonConstraint ct = new AutomatonConstraint(model_);
429  ct.Proto.Automaton = aut;
430  return ct;
431  }
432 
446  public Constraint AddInverse(IEnumerable<IntVar> direct, IEnumerable<IntVar> reverse)
447  {
449  inverse.FDirect.TrySetCapacity(direct);
450  foreach (IntVar var in direct)
451  {
452  inverse.FDirect.Add(var.Index);
453  }
454 
455  inverse.FInverse.TrySetCapacity(reverse);
456  foreach (IntVar var in reverse)
457  {
458  inverse.FInverse.Add(var.Index);
459  }
460 
461  Constraint ct = new Constraint(model_);
462  ct.Proto.Inverse = inverse;
463  return ct;
464  }
465 
492  public ReservoirConstraint AddReservoirConstraint(long minLevel, long maxLevel)
493  {
495 
496  res.MinLevel = minLevel;
497  res.MaxLevel = maxLevel;
498 
499  ReservoirConstraint ct = new ReservoirConstraint(this, model_);
500  ct.Proto.Reservoir = res;
501  return ct;
502  }
503 
504  public void AddMapDomain(IntVar var, IEnumerable<IntVar> bool_vars, long offset = 0)
505  {
506  int i = 0;
507  int var_index = var.Index;
508  foreach (IntVar bool_var in bool_vars)
509  {
510  int b_index = bool_var.Index;
511 
513  lin1.Vars.Capacity = 1;
514  lin1.Vars.Add(var_index);
515  lin1.Coeffs.Capacity = 1;
516  lin1.Coeffs.Add(1L);
517  lin1.Domain.Capacity = 2;
518  lin1.Domain.Add(offset + i);
519  lin1.Domain.Add(offset + i);
520  ConstraintProto ct1 = new ConstraintProto();
521  ct1.Linear = lin1;
522  ct1.EnforcementLiteral.Add(b_index);
523  model_.Constraints.Add(ct1);
524 
526  lin1.Vars.Capacity = 1;
527  lin2.Vars.Add(var_index);
528  lin1.Coeffs.Capacity = 1;
529  lin2.Coeffs.Add(1L);
530  lin1.Domain.Capacity = 4;
531  lin2.Domain.Add(Int64.MinValue);
532  lin2.Domain.Add(offset + i - 1);
533  lin2.Domain.Add(offset + i + 1);
534  lin2.Domain.Add(Int64.MaxValue);
535  ConstraintProto ct2 = new ConstraintProto();
536  ct2.Linear = lin2;
537  ct2.EnforcementLiteral.Add(-b_index - 1);
538  model_.Constraints.Add(ct2);
539 
540  i++;
541  }
542  }
543 
550  {
552  or.Literals.Capacity = 2;
553  or.Literals.Add(a.Not().GetIndex());
554  or.Literals.Add(b.GetIndex());
555 
556  Constraint ct = new Constraint(model_);
557  ct.Proto.BoolOr = or;
558  return ct;
559  }
560 
566  public Constraint AddBoolOr(IEnumerable<ILiteral> literals)
567  {
568  BoolArgumentProto bool_argument = new BoolArgumentProto();
569  bool_argument.Literals.TrySetCapacity(literals);
570  foreach (ILiteral lit in literals)
571  {
572  bool_argument.Literals.Add(lit.GetIndex());
573  }
574 
575  Constraint ct = new Constraint(model_);
576  ct.Proto.BoolOr = bool_argument;
577  return ct;
578  }
579 
585  public Constraint AddAtLeastOne(IEnumerable<ILiteral> literals)
586  {
587  return AddBoolOr(literals);
588  }
589 
595  public Constraint AddAtMostOne(IEnumerable<ILiteral> literals)
596  {
597  BoolArgumentProto bool_argument = new BoolArgumentProto();
598  bool_argument.Literals.TrySetCapacity(literals);
599  foreach (ILiteral lit in literals)
600  {
601  bool_argument.Literals.Add(lit.GetIndex());
602  }
603 
604  Constraint ct = new Constraint(model_);
605  ct.Proto.AtMostOne = bool_argument;
606  return ct;
607  }
608 
614  public Constraint AddExactlyOne(IEnumerable<ILiteral> literals)
615  {
616  BoolArgumentProto bool_argument = new BoolArgumentProto();
617  bool_argument.Literals.TrySetCapacity(literals);
618  foreach (ILiteral lit in literals)
619  {
620  bool_argument.Literals.Add(lit.GetIndex());
621  }
622 
623  Constraint ct = new Constraint(model_);
624  ct.Proto.ExactlyOne = bool_argument;
625  return ct;
626  }
627 
633  public Constraint AddBoolAnd(IEnumerable<ILiteral> literals)
634  {
635  BoolArgumentProto bool_argument = new BoolArgumentProto();
636  bool_argument.Literals.TrySetCapacity(literals);
637  foreach (ILiteral lit in literals)
638  {
639  bool_argument.Literals.Add(lit.GetIndex());
640  }
641 
642  Constraint ct = new Constraint(model_);
643  ct.Proto.BoolAnd = bool_argument;
644  return ct;
645  }
646 
652  public Constraint AddBoolXor(IEnumerable<ILiteral> literals)
653  {
654  BoolArgumentProto bool_argument = new BoolArgumentProto();
655  bool_argument.Literals.TrySetCapacity(literals);
656  foreach (ILiteral lit in literals)
657  {
658  bool_argument.Literals.Add(lit.GetIndex());
659  }
660 
661  Constraint ct = new Constraint(model_);
662  ct.Proto.BoolXor = bool_argument;
663  return ct;
664  }
665 
671  public Constraint AddMinEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
672  {
674  lin.Exprs.TrySetCapacity(exprs);
675  foreach (LinearExpr expr in exprs)
676  {
677  lin.Exprs.Add(GetLinearExpressionProto(expr, /*negate=*/true));
678  }
679  lin.Target = GetLinearExpressionProto(target, /*negate=*/true);
680 
681  Constraint ct = new Constraint(model_);
682  ct.Proto.LinMax = lin;
683  return ct;
684  }
685 
691  public Constraint AddMaxEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
692  {
694  lin.Exprs.TrySetCapacity(exprs);
695  foreach (LinearExpr expr in exprs)
696  {
697  lin.Exprs.Add(GetLinearExpressionProto(expr));
698  }
699  lin.Target = GetLinearExpressionProto(target);
700 
701  Constraint ct = new Constraint(model_);
702  ct.Proto.LinMax = lin;
703  return ct;
704  }
705 
711  public Constraint AddDivisionEquality<T, N, D>(T target, N num, D denom)
712  {
714  div.Exprs.Capacity = 2;
715  div.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(num)));
716  div.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(denom)));
717  div.Target = GetLinearExpressionProto(GetLinearExpr(target));
718 
719  Constraint ct = new Constraint(model_);
720  ct.Proto.IntDiv = div;
721  return ct;
722  }
723 
730  {
732  abs.Exprs.Capacity = 2;
733  abs.Exprs.Add(GetLinearExpressionProto(expr));
734  abs.Exprs.Add(GetLinearExpressionProto(expr, /*negate=*/true));
735  abs.Target = GetLinearExpressionProto(target);
736 
737  Constraint ct = new Constraint(model_);
738  ct.Proto.LinMax = abs;
739  return ct;
740  }
741 
747  public Constraint AddModuloEquality<T, V, M>(T target, V v, M m)
748  {
750  mod.Exprs.Capacity = 2;
751  mod.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(v)));
752  mod.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(m)));
753  mod.Target = GetLinearExpressionProto(GetLinearExpr(target));
754 
755  Constraint ct = new Constraint(model_);
756  ct.Proto.IntMod = mod;
757  return ct;
758  }
759 
765  public Constraint AddMultiplicationEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
766  {
768  prod.Target = GetLinearExpressionProto(target);
769  prod.Exprs.TrySetCapacity(exprs);
770  foreach (LinearExpr expr in exprs)
771  {
772  prod.Exprs.Add(GetLinearExpressionProto(expr));
773  }
774 
775  Constraint ct = new Constraint(model_);
776  ct.Proto.IntProd = prod;
777  return ct;
778  }
779 
786  {
788  prod.Target = GetLinearExpressionProto(target);
789  prod.Exprs.Capacity = 2;
790  prod.Exprs.Add(GetLinearExpressionProto(left));
791  prod.Exprs.Add(GetLinearExpressionProto(right));
792 
793  Constraint ct = new Constraint(model_);
794  ct.Proto.IntProd = prod;
795  return ct;
796  }
797 
798  // Scheduling support
799 
815  public IntervalVar NewIntervalVar<S, D, E>(S start, D size, E end, string name)
816  {
817  LinearExpr startExpr = GetLinearExpr(start);
818  LinearExpr sizeExpr = GetLinearExpr(size);
819  LinearExpr endExpr = GetLinearExpr(end);
820  Add(startExpr + sizeExpr == endExpr);
821 
822  LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
823  LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
825  return new IntervalVar(model_, startProto, sizeProto, endProto, name);
826  }
827 
843  public IntervalVar NewFixedSizeIntervalVar<S>(S start, long size, string name)
844  {
845  LinearExpr startExpr = GetLinearExpr(start);
846  LinearExpr sizeExpr = GetLinearExpr(size);
847  LinearExpr endExpr = LinearExpr.Sum(new LinearExpr[] { startExpr, sizeExpr });
848 
849  LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
850  LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
852  return new IntervalVar(model_, startProto, sizeProto, endProto, name);
853  }
854 
873  public IntervalVar NewOptionalIntervalVar<S, D, E>(S start, D size, E end, ILiteral is_present, string name)
874  {
875  LinearExpr startExpr = GetLinearExpr(start);
876  LinearExpr sizeExpr = GetLinearExpr(size);
877  LinearExpr endExpr = GetLinearExpr(end);
878  Add(startExpr + sizeExpr == endExpr).OnlyEnforceIf(is_present);
879 
880  LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
881  LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
883  return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.GetIndex(), name);
884  }
885 
904  public IntervalVar NewOptionalFixedSizeIntervalVar<S>(S start, long size, ILiteral is_present, string name)
905  {
906  LinearExpr startExpr = GetLinearExpr(start);
907  LinearExpr sizeExpr = GetLinearExpr(size);
908  LinearExpr endExpr = LinearExpr.Sum(new LinearExpr[] { startExpr, sizeExpr });
909 
910  LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
911  LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
913  return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.GetIndex(), name);
914  }
915 
925  public Constraint AddNoOverlap(IEnumerable<IntervalVar> intervals)
926  {
928  no_overlap.Intervals.TrySetCapacity(intervals);
929  foreach (IntervalVar var in intervals)
930  {
931  no_overlap.Intervals.Add(var.GetIndex());
932  }
933 
934  Constraint ct = new Constraint(model_);
935  ct.Proto.NoOverlap = no_overlap;
936  return ct;
937  }
938 
956  {
959  return ct;
960  }
961 
982  {
984  LinearExpr capacityExpr = GetLinearExpr(capacity);
985  cumul.Capacity = GetLinearExpressionProto(capacityExpr);
986 
987  CumulativeConstraint ct = new CumulativeConstraint(this, model_);
988  ct.Proto.Cumulative = cumul;
989  return ct;
990  }
991 
992  // Objective.
993 
995  public void Minimize(LinearExpr obj)
996  {
997  SetObjective(obj, true);
998  }
999 
1001  public void Maximize(LinearExpr obj)
1002  {
1003  SetObjective(obj, false);
1004  }
1005 
1007  void ClearObjective()
1008  {
1009  model_.Objective = null;
1010  }
1011 
1013  bool HasObjective()
1014  {
1015  return model_.Objective is not null;
1016  }
1017 
1018  // Search Decision.
1019 
1021  public void AddDecisionStrategy(IEnumerable<IntVar> vars,
1024  {
1026  ds.Variables.TrySetCapacity(vars);
1027  foreach (IntVar var in vars)
1028  {
1029  ds.Variables.Add(var.Index);
1030  }
1031  ds.VariableSelectionStrategy = var_str;
1032  ds.DomainReductionStrategy = dom_str;
1033  model_.SearchStrategy.Add(ds);
1034  }
1035 
1037  public void AddHint(IntVar var, long value)
1038  {
1039  model_.SolutionHint ??= new PartialVariableAssignment();
1040  model_.SolutionHint.Vars.Add(var.GetIndex());
1041  model_.SolutionHint.Values.Add(value);
1042  }
1043 
1045  public void ClearHints()
1046  {
1047  model_.SolutionHint = null;
1048  }
1049 
1051  public void AddAssumption(ILiteral lit)
1052  {
1053  model_.Assumptions.Add(lit.GetIndex());
1054  }
1055 
1057  public void AddAssumptions(IEnumerable<ILiteral> literals)
1058  {
1059  foreach (ILiteral lit in literals)
1060  {
1061  AddAssumption(lit);
1062  }
1063  }
1064 
1066  public void ClearAssumptions()
1067  {
1068  model_.Assumptions.Clear();
1069  }
1070 
1071  // Internal methods.
1072 
1073  void SetObjective(LinearExpr obj, bool minimize)
1074  {
1075  CpObjectiveProto objective = new CpObjectiveProto();
1076  if (obj is null)
1077  {
1078  objective.Offset = 0L;
1079  objective.ScalingFactor = minimize ? 1L : -1;
1080  }
1081  else if (obj is IntVar intVar)
1082  {
1083  objective.Offset = 0L;
1084  objective.Vars.Capacity = 1;
1085  objective.Vars.Add(intVar.Index);
1086 
1087  objective.Coeffs.Capacity = 1;
1088  if (minimize)
1089  {
1090  objective.Coeffs.Add(1L);
1091  objective.ScalingFactor = 1L;
1092  }
1093  else
1094  {
1095  objective.Coeffs.Add(-1L);
1096  objective.ScalingFactor = -1L;
1097  }
1098  }
1099  else
1100  {
1101  Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>();
1102  long constant = LinearExpr.GetVarValueMap(obj, 1L, dict);
1103  if (minimize)
1104  {
1105  objective.ScalingFactor = 1L;
1106  objective.Offset = constant;
1107  }
1108  else
1109  {
1110  objective.ScalingFactor = -1L;
1111  objective.Offset = -constant;
1112  }
1113 
1114  var dictCount = dict.Count;
1115  objective.Vars.Capacity = dictCount;
1116  objective.Coeffs.Capacity = dictCount;
1117  foreach (KeyValuePair<IntVar, long> it in dict)
1118  {
1119  objective.Vars.Add(it.Key.Index);
1120  objective.Coeffs.Add(minimize ? it.Value : -it.Value);
1121  }
1122  }
1123  model_.Objective = objective;
1124  }
1125 
1127  public String ModelStats()
1128  {
1129  return CpSatHelper.ModelStats(model_);
1130  }
1131 
1142  public Boolean ExportToFile(String file)
1143  {
1144  return CpSatHelper.WriteModelToFile(model_, file);
1145  }
1146 
1152  public String Validate()
1153  {
1154  return CpSatHelper.ValidateModel(model_);
1155  }
1156 
1157  private int ConvertConstant(long value)
1158  {
1159  if (constant_map_.TryGetValue(value, out var index))
1160  {
1161  return index;
1162  }
1163 
1164  index = model_.Variables.Count;
1165  IntegerVariableProto var = new IntegerVariableProto();
1166  var.Domain.Capacity = 2;
1167  var.Domain.Add(value);
1168  var.Domain.Add(value);
1169  constant_map_.Add(value, index);
1170  model_.Variables.Add(var);
1171  return index;
1172  }
1173 
1175  {
1176  if (typeof(X) == typeof(IntVar))
1177  {
1178  return (IntVar)(Object)x;
1179  }
1180  if (typeof(X) == typeof(long) || typeof(X) == typeof(int) || typeof(X) == typeof(short))
1181  {
1182  return LinearExpr.Constant(Convert.ToInt64(x));
1183  }
1184  if (typeof(X) == typeof(LinearExpr))
1185  {
1186  return (LinearExpr)(Object)x;
1187  }
1188  throw new ArgumentException("Cannot convert argument to LinearExpr");
1189  }
1190 
1192  {
1193  Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>();
1194  long constant = LinearExpr.GetVarValueMap(expr, 1L, dict);
1195  long mult = negate ? -1 : 1;
1196 
1198  var dictCount = dict.Count;
1199  linear.Vars.Capacity = dictCount;
1200  linear.Coeffs.Capacity = dictCount;
1201  foreach (KeyValuePair<IntVar, long> term in dict)
1202  {
1203  linear.Vars.Add(term.Key.Index);
1204  linear.Coeffs.Add(term.Value * mult);
1205  }
1206  linear.Offset = constant * mult;
1207  return linear;
1208  }
1209 
1210  private CpModelProto model_;
1211  private Dictionary<long, int> constant_map_;
1212  private BoolVar true_literal_;
1213 }
1214 
1215 } // namespace Google.OrTools.Sat
pbc::RepeatedField< int > Literals
Definition: CpModel.pb.cs:561
Constraint AddAtLeastOne(IEnumerable< ILiteral > literals)
Same as AddBoolOr: ∑(literals) ≥ 1.
Definition: CpModel.cs:585
void Maximize(LinearExpr obj)
Adds a maximization objective of a linear expression.
Definition: CpModel.cs:1001
static long GetVarValueMap(LinearExpr e, long initial_coeff, Dictionary< IntVar, long > dict)
ILiteral Not()
Returns the Boolean negation of the literal.
Some constraints supports linear expression instead of just using a reference to a variable.
Definition: CpModel.pb.cs:695
static LinearExpr Constant(long value)
Creates a constant expression.
IntervalVar NewIntervalVar< S, D, E >(S start, D size, E end, string name)
Creates an interval variable from three affine expressions start, size, and end.
Definition: CpModel.cs:815
Constraint AddLinearExpressionInDomain(LinearExpr expr, Domain domain)
Adds expr ∈ domain.
Definition: CpModel.cs:158
Constraint AddDivisionEquality< T, N, D >(T target, N num, D denom)
Adds target == num / denom (integer division rounded towards 0).
Definition: CpModel.cs:711
pbc::RepeatedField< long > Coeffs
Definition: CpModel.pb.cs:6449
pbc::RepeatedField< int > Vars
The linear terms of the objective to minimize.
Definition: CpModel.pb.cs:6438
global::Google.OrTools.Sat.LinearArgumentProto?? IntMod
The int_mod constraint forces the target to equal exprs[0] % exprs[1].
Definition: CpModel.pb.cs:5053
global::Google.OrTools.Sat.LinearExpressionProto Target
Definition: CpModel.pb.cs:990
Constraint AddNoOverlap(IEnumerable< IntervalVar > intervals)
Adds NoOverlap(intervalVars).
Definition: CpModel.cs:925
Define the strategy to follow when the solver needs to take a new decision.
Definition: CpModel.pb.cs:7125
IntVar NewIntVarFromDomain(Domain domain, string name)
Creates an integer variable with given domain.
Definition: CpModel.cs:76
NoOverlap2dConstraint AddNoOverlap2D()
Adds NoOverlap2D().
Definition: CpModel.cs:955
pbc::RepeatedField< global::Google.OrTools.Sat.LinearExpressionProto > Exprs
Definition: CpModel.pb.cs:1004
Constraint AddMinEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == Min(exprs).
Definition: CpModel.cs:671
int GetIndex()
Returns the logical index of the literal.
double Offset
The displayed objective is always: scaling_factor * (sum(coefficients[i] * objective_vars[i]) + offse...
Definition: CpModel.pb.cs:6467
Constraint AddImplication(ILiteral a, ILiteral b)
Adds a ⇒ b.
Definition: CpModel.cs:549
void ClearAssumptions()
Clears all assumptions from the model.
Definition: CpModel.cs:1066
ILiteral FalseLiteral()
Returns a constant false literal.
Definition: CpModel.cs:116
The circuit constraint is defined on a graph where the arc presence are controlled by literals.
Definition: CpModel.pb.cs:3199
Constraint AddElement(IntVar index, IEnumerable< long > values, IntVar target)
Adds the element constraint: values[index] == target.
Definition: CpModel.cs:260
Constraint AddExactlyOne(IEnumerable< ILiteral > literals)
Adds ExactlyOne(literals): ∑(literals) == 1.
Definition: CpModel.cs:614
Holds a linear constraint: expression ∈ domain
VariableSelectionStrategy
The order in which the variables above should be considered.
Definition: CpModel.pb.cs:7419
static string ValidateModel(Google.OrTools.Sat.CpModelProto model_proto)
Definition: CpSatHelper.cs:59
ReservoirConstraint AddReservoirConstraint(long minLevel, long maxLevel)
Adds a reservoir constraint with optional refill/emptying events.
Definition: CpModel.cs:492
global::Google.OrTools.Sat.PartialVariableAssignment SolutionHint
Solution hint.
Definition: CpModel.pb.cs:8813
pbc::RepeatedField< int > Vars
The sequence of variables.
Definition: CpModel.pb.cs:4365
IntVar NewConstant(long value)
Creates a constant variable.
Definition: CpModel.cs:86
Specialized NoOverlap2D constraint.
Definition: Constraints.cs:406
static string ModelStats(Google.OrTools.Sat.CpModelProto model_proto)
Definition: CpSatHelper.cs:49
Holds a integer variable with a discrete domain.
Constraint AddLinearConstraint(LinearExpr expr, long lb, long ub)
Adds lb ≤ expr ≤ ub.
Definition: CpModel.cs:141
Holds a Boolean variable or its negation.
Specialized multiple circuit constraint.
Definition: Constraints.cs:118
pbc::RepeatedField< int > Vars
Definition: CpModel.pb.cs:3827
ILiteral TrueLiteral()
Returns a constant true literal.
Definition: CpModel.cs:106
bool Negated
If true, the meaning is "negated", that is we forbid any of the given tuple from a feasible assignmen...
Definition: CpModel.pb.cs:3851
Constraint AddInverse(IEnumerable< IntVar > direct, IEnumerable< IntVar > reverse)
Adds Inverse(variables, inverseVariables).
Definition: CpModel.cs:446
pbc::RepeatedField< int > EnforcementLiteral
The constraint will be enforced iff all literals listed here are true.
Definition: CpModel.pb.cs:4923
Container for nested types declared in the DecisionStrategyProto message type.
Definition: CpModel.pb.cs:7412
Constraint Add(BoundedLinearExpression lin)
Adds a linear constraint to the model.
Definition: CpModel.cs:192
global::Google.OrTools.Sat.AllDifferentConstraintProto?? AllDiff
The all_diff constraint forces all variables to take different values.
Definition: CpModel.pb.cs:5124
global::Google.OrTools.Sat.LinearConstraintProto?? Linear
The linear constraint enforces a linear inequality among the variables, such as 0 <= x + 2y <= 10.
Definition: CpModel.pb.cs:5109
Wrapper around a ConstraintProto.
Definition: Constraints.cs:28
CircuitConstraint AddCircuit()
Adds and returns an empty circuit constraint.
Definition: CpModel.cs:307
The sum of the demands of the intervals at each interval point cannot exceed a capacity.
Definition: CpModel.pb.cs:2602
global::Google.OrTools.Sat.LinearArgumentProto?? LinMax
The lin_max constraint forces the target to equal the maximum of all linear expressions.
Definition: CpModel.pb.cs:5093
The linear sum vars[i] * coeffs[i] must fall in the given domain.
Definition: CpModel.pb.cs:1353
int GetIndex()
Returns the index of the variable in the underlying CpModelProto.
global::Google.OrTools.Sat.CumulativeConstraintProto?? Cumulative
The cumulative constraint ensures that for any integer point, the sum of the demands of the intervals...
Definition: CpModel.pb.cs:5301
Constraint AddAbsEquality(LinearExpr target, LinearExpr expr)
Adds target == abs(expr).
Definition: CpModel.cs:729
static bool WriteModelToFile(Google.OrTools.Sat.CpModelProto model_proto, string filename)
Definition: CpSatHelper.cs:69
pbc::RepeatedField< global::Google.OrTools.Sat.ConstraintProto > Constraints
Definition: CpModel.pb.cs:8727
All affine expressions must take different values.
Definition: CpModel.pb.cs:1167
BoolVar NewBoolVar(string name)
Creates an Boolean variable with given domain.
Definition: CpModel.cs:96
IntervalVar NewFixedSizeIntervalVar< S >(S start, long size, string name)
Creates an interval variable from an affine expression start, and a fixed size.
Definition: CpModel.cs:843
global::Google.OrTools.Sat.TableConstraintProto?? Table
The table constraint enforces what values a tuple of variables may take.
Definition: CpModel.pb.cs:5187
CumulativeConstraint AddCumulative< C >(C capacity)
Adds Cumulative(capacity).
Definition: CpModel.cs:981
global::Google.OrTools.Sat.BoolArgumentProto?? BoolOr
The bool_or constraint forces at least one literal to be true.
Definition: CpModel.pb.cs:4934
global::Google.OrTools.Sat.ElementConstraintProto?? Element
The element constraint forces the variable with the given index to be equal to the target.
Definition: CpModel.pb.cs:5140
global::Google.OrTools.Sat.LinearArgumentProto?? IntProd
The int_prod constraint forces the target to equal the product of all variables.
Definition: CpModel.pb.cs:5076
The constraint target = vars[index].
Definition: CpModel.pb.cs:1596
pbc::RepeatedField< int > Vars
Definition: CpModel.pb.cs:1406
pbc::RepeatedField< long > Domain
Definition: CpModel.pb.cs:1431
The values of the n-tuple formed by the given variables can only be one of the listed n-tuples in val...
Definition: CpModel.pb.cs:3774
void AddMapDomain(IntVar var, IEnumerable< IntVar > bool_vars, long offset=0)
Definition: CpModel.cs:504
global::Google.OrTools.Sat.AutomatonConstraintProto?? Automaton
The automaton constraint forces a sequence of variables to be accepted by an automaton.
Definition: CpModel.pb.cs:5203
void Minimize(LinearExpr obj)
Adds a minimization objective of a linear expression.
Definition: CpModel.cs:995
Specialized circuit constraint.
Definition: Constraints.cs:84
Constraint AddModuloEquality< T, V, M >(T target, V v, M m)
Adds target == v % m.
Definition: CpModel.cs:747
LinearExpr GetLinearExpr< X >(X x)
Definition: CpModel.cs:1174
Constraint AddBoolAnd(IEnumerable< ILiteral > literals)
Adds And(literals) == true.
Definition: CpModel.cs:633
TableConstraint AddAllowedAssignments(IEnumerable< IntVar > vars)
Adds AllowedAssignments(variables).
Definition: CpModel.cs:347
global::Google.OrTools.Sat.NoOverlapConstraintProto?? NoOverlap
The no_overlap constraint prevents a set of intervals from overlapping; in scheduling,...
Definition: CpModel.pb.cs:5269
Wrapper class around the cp_model proto.
Definition: CpModel.cs:23
Specialized cumulative constraint.
Definition: Constraints.cs:364
global::Google.OrTools.Sat.BoolArgumentProto?? BoolAnd
The bool_and constraint forces all of the literals to be true.
Definition: CpModel.pb.cs:4953
Maintain a reservoir level within bounds.
Definition: CpModel.pb.cs:2874
pbc::RepeatedField< int > Vars
Definition: CpModel.pb.cs:748
A constraint programming problem.
Definition: CpModel.pb.cs:8639
global::Google.OrTools.Sat.BoolArgumentProto?? BoolXor
The bool_xor constraint forces an odd number of the literals to be true.
Definition: CpModel.pb.cs:5019
global::Google.OrTools.Sat.ReservoirConstraintProto?? Reservoir
The reservoir constraint forces the sum of a set of active demands to always be between a specified m...
Definition: CpModel.pb.cs:5236
TableConstraint AddForbiddenAssignments(IEnumerable< IntVar > vars)
Adds ForbiddenAssignments(variables).
Definition: CpModel.cs:375
global::Google.OrTools.Sat.RoutesConstraintProto?? Routes
The routes constraint implements the vehicle routing problem.
Definition: CpModel.pb.cs:5171
global::Google.OrTools.Sat.BoolArgumentProto?? AtMostOne
The at_most_one constraint enforces that no more than one literal is true at the same time.
Definition: CpModel.pb.cs:4978
pbc::RepeatedField< global::Google.OrTools.Sat.IntegerVariableProto > Variables
The associated Protos should be referred by their index in these fields.
Definition: CpModel.pb.cs:8716
pbc::RepeatedField< int > Variables
The variables to be considered for the next decision.
Definition: CpModel.pb.cs:7184
Constraint AddMaxEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == Max(exprs).
Definition: CpModel.cs:691
global::Google.OrTools.Sat.NoOverlap2DConstraintProto?? NoOverlap2D
The no_overlap_2d constraint prevents a set of boxes from overlapping.
Definition: CpModel.pb.cs:5284
ConstraintProto Proto
The underlying constraint proto.
Definition: Constraints.cs:62
int GetIndex()
The Index of the interval in the model proto
global::Google.OrTools.Sat.LinearExpressionProto Capacity
Definition: CpModel.pb.cs:2653
pbc::RepeatedField< global::Google.OrTools.Sat.LinearExpressionProto > Exprs
Definition: CpModel.pb.cs:1218
Holds a linear expression: sum (ai * xi) + b.
global::Google.OrTools.Sat.LinearArgumentProto?? IntDiv
The int_div constraint forces the target to equal exprs[0] / exprs[1].
Definition: CpModel.pb.cs:5036
Constraint AddMultiplicationEquality(LinearExpr target, LinearExpr left, LinearExpr right)
Adds target == left * right.
Definition: CpModel.cs:785
void AddAssumptions(IEnumerable< ILiteral > literals)
Adds multiple literals to the model as assumptions.
Definition: CpModel.cs:1057
LinearExpressionProto GetLinearExpressionProto(LinearExpr expr, bool negate=false)
Definition: CpModel.cs:1191
Holds a Boolean variable.
Constraint AddElement(IntVar index, IEnumerable< int > values, IntVar target)
Adds the element constraint: values[index] == target.
Definition: CpModel.cs:281
Specialized automaton constraint.
Definition: Constraints.cs:275
Specialized reservoir constraint.
Definition: Constraints.cs:306
Constraint AddMultiplicationEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == ∏(exprs).
Definition: CpModel.cs:765
IntVar NewIntVar(long lb, long ub, string name)
Creates an integer variable with domain [lb, ub].
Definition: CpModel.cs:62
pbc::RepeatedField< long > Coeffs
Definition: CpModel.pb.cs:759
The two arrays of variable each represent a function, the second is the inverse of the first: f_direc...
Definition: CpModel.pb.cs:4027
Argument of the constraints of the form OP(literals).
Definition: CpModel.pb.cs:510
Constraint AddBoolOr(IEnumerable< ILiteral > literals)
Adds Or(literals) == true.
Definition: CpModel.cs:566
global::Google.OrTools.Sat.CircuitConstraintProto?? Circuit
The circuit constraint takes a graph and forces the arcs present (with arc presence indicated by a li...
Definition: CpModel.pb.cs:5156
pbc::RepeatedField< long > Coeffs
Same size as vars.
Definition: CpModel.pb.cs:1420
int Index
Returns the index of the variable in the underlying CpModelProto.
void OnlyEnforceIf(ILiteral lit)
Adds a literal to the constraint.
Definition: Constraints.cs:38
pbc::RepeatedField< int > Assumptions
A list of literals.
Definition: CpModel.pb.cs:8842
DomainReductionStrategy
Once a variable has been chosen, this enum describe what decision is taken on its domain.
Definition: CpModel.pb.cs:7433
pbc::RepeatedField< int > FDirect
Definition: CpModel.pb.cs:4079
MultipleCircuitConstraint AddMultipleCircuit()
Adds and returns an empty multiple circuit constraint.
Definition: CpModel.cs:325
void AddDecisionStrategy(IEnumerable< IntVar > vars, DecisionStrategyProto.Types.VariableSelectionStrategy var_str, DecisionStrategyProto.Types.DomainReductionStrategy dom_str)
Adds DecisionStrategy(variables, var_str, dom_str).
Definition: CpModel.cs:1021
Constraint AddAllDifferent(IEnumerable< LinearExpr > exprs)
Adds the constraint AllDifferent(exprs).
Definition: CpModel.cs:220
All the intervals (index of IntervalConstraintProto) must be disjoint.
Definition: CpModel.pb.cs:2160
pbc::RepeatedField< global::Google.OrTools.Sat.DecisionStrategyProto > SearchStrategy
Defines the strategy that the solver should follow when the search_branching parameter is set to FIXE...
Definition: CpModel.pb.cs:8791
AutomatonConstraint AddAutomaton(IEnumerable< IntVar > vars, long starting_state, IEnumerable< long > final_states)
Adds an automaton constraint.
Definition: CpModel.cs:415
void AddAssumption(ILiteral lit)
Adds a literal to the model as assumption.
Definition: CpModel.cs:1051
IntervalVar NewOptionalIntervalVar< S, D, E >(S start, D size, E end, ILiteral is_present, string name)
Creates an optional interval variable from three affine expressions start, size, and end,...
Definition: CpModel.cs:873
The "VRP" (Vehicle Routing Problem) constraint.
Definition: CpModel.pb.cs:3457
CpModelProto Model
The underlying CpModelProto.
Definition: CpModel.cs:39
The boxes defined by [start_x, end_x) * [start_y, end_y) cannot overlap.
Definition: CpModel.pb.cs:2345
void ClearHints()
Clears all hinting from the model.
Definition: CpModel.cs:1045
Specialized assignment constraint.
Definition: Constraints.cs:151
IntervalVar NewOptionalFixedSizeIntervalVar< S >(S start, long size, ILiteral is_present, string name)
Creates an optional interval variable from an affine expression start, a fixed size,...
Definition: CpModel.cs:904
Boolean ExportToFile(String file)
Write the model as a protocol buffer to file.
Definition: CpModel.cs:1142
Constraint AddAtMostOne(IEnumerable< ILiteral > literals)
Adds AtMostOne(literals): ∑(literals) ≤ 1.
Definition: CpModel.cs:595
This constraint forces a sequence of variables to be accepted by an automaton.
Definition: CpModel.pb.cs:4239
void AddHint(IntVar var, long value)
Adds variable hinting to the model.
Definition: CpModel.cs:1037
String Validate()
Returns a non empty string explaining the issue if the model is invalid.
Definition: CpModel.cs:1152
global::Google.OrTools.Sat.CpObjectiveProto Objective
The objective to minimize.
Definition: CpModel.pb.cs:8739
static LinearExpr Sum(IEnumerable< LinearExpr > exprs)
Creates Sum(exprs).
global::Google.OrTools.Sat.BoolArgumentProto?? ExactlyOne
The exactly_one constraint force exactly one literal to true and no more.
Definition: CpModel.pb.cs:5004
Constraint AddBoolXor(IEnumerable< ILiteral > literals)
Adds XOr(literals) == true.
Definition: CpModel.cs:652
String ModelStats()
Returns some statistics on model as a string.
Definition: CpModel.cs:1127
global::Google.OrTools.Sat.InverseConstraintProto?? Inverse
The inverse constraint forces two arrays to be inverses of each other: the values of one are the indi...
Definition: CpModel.pb.cs:5219
This message encodes a partial (or full) assignment of the variables of a CpModelProto.
Definition: CpModel.pb.cs:7720
Constraint AddElement(IntVar index, IEnumerable< IntVar > vars, IntVar target)
Adds the element constraint: variables[index] == target.
Definition: CpModel.cs:239