Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
CpModel.cs
Go to the documentation of this file.
1// Copyright 2010-2025 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
14namespace Google.OrTools.Sat
15{
16using System;
17using System.Collections.Generic;
18using Google.OrTools.Util;
19
23public class CpModel
24{
25 public CpModel()
26 {
27 model_ = new CpModelProto();
28 constant_map_ = new Dictionary<long, int>();
29 var_value_map_ = new Dictionary<int, long>(10);
30 terms_ = new Queue<Term>(10);
31 }
32
33 // Getters.
34
41 {
42 get {
43 return model_;
44 }
45 }
46
47 int Negated(int index)
48 {
49 return -index - 1;
50 }
51
52 // Integer variables and constraints.
53
64 public IntVar NewIntVar(long lb, long ub, string name)
65 {
66 return new IntVar(model_, lb, ub, name);
67 }
68
78 public IntVar NewIntVarFromDomain(Domain domain, string name)
79 {
80 return new IntVar(model_, domain, name);
81 }
82
88 public IntVar NewConstant(long value)
89 {
90 return new IntVar(model_, ConvertConstant(value));
91 }
92
98 public BoolVar NewBoolVar(string name)
99 {
100 return new BoolVar(model_, name);
101 }
102
109 {
110 return true_literal_ ??= new BoolVar(model_, ConvertConstantWithName(1, "true"));
111 }
112
119 {
120 return TrueLiteral().Not();
121 }
122
123 private long FillLinearConstraint(LinearExpr expr, out LinearConstraintProto linear)
124 {
125 var dict = var_value_map_;
126 dict.Clear();
127 long constant = LinearExpr.GetVarValueMap(expr, dict, terms_);
128 var count = dict.Count;
129 linear = new LinearConstraintProto();
130 linear.Vars.Capacity = count;
131 linear.Vars.AddRange(dict.Keys);
132 linear.Coeffs.Capacity = count;
133 linear.Coeffs.AddRange(dict.Values);
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(LinearExpr index, IEnumerable<LinearExpr> exprs, LinearExpr target)
240 {
242 element.LinearIndex = GetLinearExpressionProto(index);
243 element.Exprs.TrySetCapacity(exprs);
244 foreach (LinearExpr expr in exprs)
245 {
246 element.Exprs.Add(GetLinearExpressionProto(expr));
247 }
248 element.LinearTarget = GetLinearExpressionProto(target);
249
250 Constraint ct = new Constraint(model_);
251 ct.Proto.Element = element;
252 return ct;
253 }
254
260 public Constraint AddElement(LinearExpr index, IEnumerable<long> values, LinearExpr target)
261 {
263 element.LinearIndex = GetLinearExpressionProto(index);
264 element.Exprs.TrySetCapacity(values);
265 foreach (long value in values)
266 {
267 element.Exprs.Add(GetLinearExpressionProto(value));
268 }
269 element.LinearTarget = GetLinearExpressionProto(target);
270
271 Constraint ct = new Constraint(model_);
272 ct.Proto.Element = element;
273 return ct;
274 }
275
281 public Constraint AddElement(LinearExpr index, IEnumerable<int> values, LinearExpr target)
282 {
284 element.LinearIndex = GetLinearExpressionProto(index);
285 element.Exprs.TrySetCapacity(values);
286 foreach (int value in values)
287 {
288 element.Exprs.Add(GetLinearExpressionProto(value));
289 }
290 element.LinearTarget = GetLinearExpressionProto(target);
291
292 Constraint ct = new Constraint(model_);
293 ct.Proto.Element = element;
294 return ct;
295 }
296
308 {
309 CircuitConstraint ct = new CircuitConstraint(model_);
310 ct.Proto.Circuit = new CircuitConstraintProto();
311 return ct;
312 }
313
326 {
328 ct.Proto.Routes = new RoutesConstraintProto();
329 return ct;
330 }
331
348 public TableConstraint AddAllowedAssignments(IEnumerable<LinearExpr> exprs)
349 {
351 table.Vars.TrySetCapacity(exprs);
352 foreach (LinearExpr expr in exprs)
353 {
354 table.Exprs.Add(GetLinearExpressionProto(expr));
355 }
356
357 TableConstraint ct = new TableConstraint(model_);
358 ct.Proto.Table = table;
359 return ct;
360 }
361
377 public TableConstraint AddForbiddenAssignments(IEnumerable<LinearExpr> exprs)
378 {
380 ct.Proto.Table.Negated = true;
381 return ct;
382 }
383
418 public AutomatonConstraint AddAutomaton(IEnumerable<LinearExpr> expressions, long starting_state,
419 IEnumerable<long> final_states)
420 {
422 automaton.Vars.TrySetCapacity(expressions);
423 foreach (LinearExpr expr in expressions)
424 {
425 automaton.Exprs.Add(GetLinearExpressionProto(expr));
426 }
427
428 automaton.StartingState = starting_state;
429 automaton.FinalStates.AddRange(final_states);
430
432 ct.Proto.Automaton = automaton;
433 return ct;
434 }
435
449 public Constraint AddInverse(IEnumerable<IntVar> direct, IEnumerable<IntVar> reverse)
450 {
452 inverse.FDirect.TrySetCapacity(direct);
453 foreach (IntVar var in direct)
454 {
455 inverse.FDirect.Add(var.Index);
456 }
457
458 inverse.FInverse.TrySetCapacity(reverse);
459 foreach (IntVar var in reverse)
460 {
461 inverse.FInverse.Add(var.Index);
462 }
463
464 Constraint ct = new Constraint(model_);
465 ct.Proto.Inverse = inverse;
466 return ct;
467 }
468
495 public ReservoirConstraint AddReservoirConstraint(long minLevel, long maxLevel)
496 {
498
499 res.MinLevel = minLevel;
500 res.MaxLevel = maxLevel;
501
502 ReservoirConstraint ct = new ReservoirConstraint(this, model_);
503 ct.Proto.Reservoir = res;
504 return ct;
505 }
506
512 public void AddMapDomain(IntVar var, IEnumerable<IntVar> bool_vars, long offset = 0)
513 {
514 int i = 0;
515 int var_index = var.Index;
516 foreach (IntVar bool_var in bool_vars)
517 {
518 int b_index = bool_var.Index;
519
521 lin1.Vars.Capacity = 1;
522 lin1.Vars.Add(var_index);
523 lin1.Coeffs.Capacity = 1;
524 lin1.Coeffs.Add(1L);
525 lin1.Domain.Capacity = 2;
526 lin1.Domain.Add(offset + i);
527 lin1.Domain.Add(offset + i);
529 ct1.Linear = lin1;
530 ct1.EnforcementLiteral.Add(b_index);
531 model_.Constraints.Add(ct1);
532
534 lin2.Vars.Capacity = 1;
535 lin2.Vars.Add(var_index);
536 lin2.Coeffs.Capacity = 1;
537 lin2.Coeffs.Add(1L);
538 lin2.Domain.Capacity = 4;
539 lin2.Domain.Add(Int64.MinValue);
540 lin2.Domain.Add(offset + i - 1);
541 lin2.Domain.Add(offset + i + 1);
542 lin2.Domain.Add(Int64.MaxValue);
544 ct2.Linear = lin2;
545 ct2.EnforcementLiteral.Add(-b_index - 1);
546 model_.Constraints.Add(ct2);
547
548 i++;
549 }
550 }
551
558 {
560 or.Literals.Capacity = 2;
561 or.Literals.Add(a.Not().GetIndex());
562 or.Literals.Add(b.GetIndex());
563
564 Constraint ct = new Constraint(model_);
565 ct.Proto.BoolOr = or;
566 return ct;
567 }
568
574 public Constraint AddBoolOr(IEnumerable<ILiteral> literals)
575 {
576 BoolArgumentProto bool_argument = new BoolArgumentProto();
577 bool_argument.Literals.TrySetCapacity(literals);
578 foreach (ILiteral lit in literals)
579 {
580 bool_argument.Literals.Add(lit.GetIndex());
581 }
582
583 Constraint ct = new Constraint(model_);
584 ct.Proto.BoolOr = bool_argument;
585 return ct;
586 }
587
593 public Constraint AddAtLeastOne(IEnumerable<ILiteral> literals)
594 {
595 return AddBoolOr(literals);
596 }
597
603 public Constraint AddAtMostOne(IEnumerable<ILiteral> literals)
604 {
605 BoolArgumentProto bool_argument = new BoolArgumentProto();
606 bool_argument.Literals.TrySetCapacity(literals);
607 foreach (ILiteral lit in literals)
608 {
609 bool_argument.Literals.Add(lit.GetIndex());
610 }
611
612 Constraint ct = new Constraint(model_);
613 ct.Proto.AtMostOne = bool_argument;
614 return ct;
615 }
616
622 public Constraint AddExactlyOne(IEnumerable<ILiteral> literals)
623 {
624 BoolArgumentProto bool_argument = new BoolArgumentProto();
625 bool_argument.Literals.TrySetCapacity(literals);
626 foreach (ILiteral lit in literals)
627 {
628 bool_argument.Literals.Add(lit.GetIndex());
629 }
630
631 Constraint ct = new Constraint(model_);
632 ct.Proto.ExactlyOne = bool_argument;
633 return ct;
634 }
635
641 public Constraint AddBoolAnd(IEnumerable<ILiteral> literals)
642 {
643 BoolArgumentProto bool_argument = new BoolArgumentProto();
644 bool_argument.Literals.TrySetCapacity(literals);
645 foreach (ILiteral lit in literals)
646 {
647 bool_argument.Literals.Add(lit.GetIndex());
648 }
649
650 Constraint ct = new Constraint(model_);
651 ct.Proto.BoolAnd = bool_argument;
652 return ct;
653 }
654
660 public Constraint AddBoolXor(IEnumerable<ILiteral> literals)
661 {
662 BoolArgumentProto bool_argument = new BoolArgumentProto();
663 bool_argument.Literals.TrySetCapacity(literals);
664 foreach (ILiteral lit in literals)
665 {
666 bool_argument.Literals.Add(lit.GetIndex());
667 }
668
669 Constraint ct = new Constraint(model_);
670 ct.Proto.BoolXor = bool_argument;
671 return ct;
672 }
673
679 public Constraint AddMinEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
680 {
682 lin.Exprs.TrySetCapacity(exprs);
683 foreach (LinearExpr expr in exprs)
684 {
685 lin.Exprs.Add(GetLinearExpressionProto(expr, /*negate=*/true));
686 }
687 lin.Target = GetLinearExpressionProto(target, /*negate=*/true);
688
689 Constraint ct = new Constraint(model_);
690 ct.Proto.LinMax = lin;
691 return ct;
692 }
693
699 public Constraint AddMaxEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
700 {
702 lin.Exprs.TrySetCapacity(exprs);
703 foreach (LinearExpr expr in exprs)
704 {
705 lin.Exprs.Add(GetLinearExpressionProto(expr));
706 }
707 lin.Target = GetLinearExpressionProto(target);
708
709 Constraint ct = new Constraint(model_);
710 ct.Proto.LinMax = lin;
711 return ct;
712 }
713
719 public Constraint AddDivisionEquality<T, N, D>(T target, N num, D denom)
720 {
722 div.Exprs.Capacity = 2;
723 div.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(num)));
724 div.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(denom)));
725 div.Target = GetLinearExpressionProto(GetLinearExpr(target));
726
727 Constraint ct = new Constraint(model_);
728 ct.Proto.IntDiv = div;
729 return ct;
730 }
731
738 {
740 abs.Exprs.Capacity = 2;
741 abs.Exprs.Add(GetLinearExpressionProto(expr));
742 abs.Exprs.Add(GetLinearExpressionProto(expr, /*negate=*/true));
743 abs.Target = GetLinearExpressionProto(target);
744
745 Constraint ct = new Constraint(model_);
746 ct.Proto.LinMax = abs;
747 return ct;
748 }
749
755 public Constraint AddModuloEquality<T, V, M>(T target, V v, M m)
756 {
758 mod.Exprs.Capacity = 2;
759 mod.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(v)));
760 mod.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(m)));
761 mod.Target = GetLinearExpressionProto(GetLinearExpr(target));
762
763 Constraint ct = new Constraint(model_);
764 ct.Proto.IntMod = mod;
765 return ct;
766 }
767
773 public Constraint AddMultiplicationEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
774 {
776 prod.Target = GetLinearExpressionProto(target);
777 prod.Exprs.TrySetCapacity(exprs);
778 foreach (LinearExpr expr in exprs)
779 {
780 prod.Exprs.Add(GetLinearExpressionProto(expr));
781 }
782
783 Constraint ct = new Constraint(model_);
784 ct.Proto.IntProd = prod;
785 return ct;
786 }
787
794 {
796 prod.Target = GetLinearExpressionProto(target);
797 prod.Exprs.Capacity = 2;
798 prod.Exprs.Add(GetLinearExpressionProto(left));
799 prod.Exprs.Add(GetLinearExpressionProto(right));
800
801 Constraint ct = new Constraint(model_);
802 ct.Proto.IntProd = prod;
803 return ct;
804 }
805
806 // Scheduling support
807
823 public IntervalVar NewIntervalVar<S, D, E>(S start, D size, E end, string name)
824 {
825 LinearExpr startExpr = GetLinearExpr(start);
826 LinearExpr sizeExpr = GetLinearExpr(size);
827 LinearExpr endExpr = GetLinearExpr(end);
828
829 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
830 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
831 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
832 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
833 }
834
850 public IntervalVar NewFixedSizeIntervalVar<S>(S start, long size, string name)
851 {
852 LinearExpr startExpr = GetLinearExpr(start);
853 LinearExpr sizeExpr = GetLinearExpr(size);
854 LinearExpr endExpr = LinearExpr.Sum(new LinearExpr[] { startExpr, sizeExpr });
855
856 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
857 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
858 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
859 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
860 }
861
880 public IntervalVar NewOptionalIntervalVar<S, D, E>(S start, D size, E end, ILiteral is_present, string name)
881 {
882 LinearExpr startExpr = GetLinearExpr(start);
883 LinearExpr sizeExpr = GetLinearExpr(size);
884 LinearExpr endExpr = GetLinearExpr(end);
885
886 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
887 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
888 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
889 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.GetIndex(), name);
890 }
891
910 public IntervalVar NewOptionalFixedSizeIntervalVar<S>(S start, long size, ILiteral is_present, string name)
911 {
912 LinearExpr startExpr = GetLinearExpr(start);
913 LinearExpr sizeExpr = GetLinearExpr(size);
914 LinearExpr endExpr = LinearExpr.Sum(new LinearExpr[] { startExpr, sizeExpr });
915
916 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
917 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
918 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
919 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.GetIndex(), name);
920 }
921
931 public Constraint AddNoOverlap(IEnumerable<IntervalVar> intervals)
932 {
934 no_overlap.Intervals.TrySetCapacity(intervals);
935 foreach (IntervalVar var in intervals)
936 {
937 no_overlap.Intervals.Add(var.GetIndex());
938 }
939
940 Constraint ct = new Constraint(model_);
941 ct.Proto.NoOverlap = no_overlap;
942 return ct;
943 }
944
962 {
964 ct.Proto.NoOverlap2D = new NoOverlap2DConstraintProto();
965 return ct;
966 }
967
988 {
990 LinearExpr capacityExpr = GetLinearExpr(capacity);
991 cumul.Capacity = GetLinearExpressionProto(capacityExpr);
992
993 CumulativeConstraint ct = new CumulativeConstraint(this, model_);
994 ct.Proto.Cumulative = cumul;
995 return ct;
996 }
997
998 // Objective.
999
1001 public void Minimize(LinearExpr obj)
1002 {
1003 SetObjective(obj, true);
1004 }
1005
1007 public void Maximize(LinearExpr obj)
1008 {
1009 SetObjective(obj, false);
1010 }
1011
1013 void ClearObjective()
1014 {
1015 model_.Objective = null;
1016 }
1017
1019 bool HasObjective()
1020 {
1021 return model_.Objective is not null || model_.FloatingPointObjective is not null;
1022 }
1023
1024 // Search Decision.
1025
1027 public void AddDecisionStrategy(IEnumerable<IntVar> vars,
1030 {
1032 ds.Variables.TrySetCapacity(vars);
1033 foreach (IntVar var in vars)
1034 {
1036 expr.Vars.Add(var.Index);
1037 expr.Coeffs.Add(1);
1038 ds.Exprs.Add(expr);
1039 }
1040 ds.VariableSelectionStrategy = var_str;
1041 ds.DomainReductionStrategy = dom_str;
1042 model_.SearchStrategy.Add(ds);
1043 }
1044
1046 public void AddHint(IntVar var, long value)
1047 {
1048 model_.SolutionHint ??= new PartialVariableAssignment();
1049 model_.SolutionHint.Vars.Add(var.GetIndex());
1050 model_.SolutionHint.Values.Add(value);
1051 }
1052
1054 public void AddHint(ILiteral lit, bool value)
1055 {
1056 model_.SolutionHint ??= new PartialVariableAssignment();
1057 int index = lit.GetIndex();
1058 if (index >= 0)
1059 {
1060 model_.SolutionHint.Vars.Add(index);
1061 model_.SolutionHint.Values.Add(value ? 1 : 0);
1062 }
1063 else
1064 {
1065 model_.SolutionHint.Vars.Add(Negated(index));
1066 model_.SolutionHint.Values.Add(value ? 0 : 1);
1067 }
1068 }
1069
1071 public void ClearHints()
1072 {
1073 model_.SolutionHint = null;
1074 }
1075
1077 public void AddAssumption(ILiteral lit)
1078 {
1079 model_.Assumptions.Add(lit.GetIndex());
1080 }
1081
1083 public void AddAssumptions(IEnumerable<ILiteral> literals)
1084 {
1085 foreach (ILiteral lit in literals)
1086 {
1087 AddAssumption(lit);
1088 }
1089 }
1090
1092 public void ClearAssumptions()
1093 {
1094 model_.Assumptions.Clear();
1095 }
1096
1097 // Internal methods.
1098
1099 void SetObjective(LinearExpr obj, bool minimize)
1100 {
1101 CpObjectiveProto objective = new CpObjectiveProto();
1102 if (obj is null)
1103 {
1104 objective.Offset = 0L;
1105 objective.ScalingFactor = minimize ? 1L : -1;
1106 }
1107 else if (obj is IntVar intVar)
1108 {
1109 objective.Offset = 0L;
1110 objective.Vars.Capacity = 1;
1111 objective.Vars.Add(intVar.Index);
1112
1113 objective.Coeffs.Capacity = 1;
1114 if (minimize)
1115 {
1116 objective.Coeffs.Add(1L);
1117 objective.ScalingFactor = 1L;
1118 }
1119 else
1120 {
1121 objective.Coeffs.Add(-1L);
1122 objective.ScalingFactor = -1L;
1123 }
1124 }
1125 else
1126 {
1127 var dict = var_value_map_;
1128 dict.Clear();
1129 long constant = LinearExpr.GetVarValueMap(obj, dict, terms_);
1130 var dictCount = dict.Count;
1131 objective.Vars.Capacity = dictCount;
1132 objective.Vars.AddRange(dict.Keys);
1133 objective.Coeffs.Capacity = dictCount;
1134 if (minimize)
1135 {
1136 objective.Coeffs.AddRange(dict.Values);
1137 objective.ScalingFactor = 1L;
1138 objective.Offset = constant;
1139 }
1140 else
1141 {
1142 foreach (var coeff in dict.Values)
1143 {
1144 objective.Coeffs.Add(-coeff);
1145 }
1146 objective.ScalingFactor = -1L;
1147 objective.Offset = -constant;
1148 }
1149 }
1150 model_.Objective = objective;
1151 }
1152
1154 public String ModelStats()
1155 {
1156 return CpSatHelper.ModelStats(model_);
1157 }
1158
1169 public Boolean ExportToFile(String file)
1170 {
1171 return CpSatHelper.WriteModelToFile(model_, file);
1172 }
1173
1179 public String Validate()
1180 {
1181 return CpSatHelper.ValidateModel(model_);
1182 }
1183
1184 private int ConvertConstant(long value)
1185 {
1186 if (constant_map_.TryGetValue(value, out var index))
1187 {
1188 return index;
1189 }
1190
1191 index = model_.Variables.Count;
1192 IntegerVariableProto var = new IntegerVariableProto();
1193 var.Domain.Capacity = 2;
1194 var.Domain.Add(value);
1195 var.Domain.Add(value);
1196 constant_map_.Add(value, index);
1197 model_.Variables.Add(var);
1198 return index;
1199 }
1200
1201 private int ConvertConstantWithName(long value, string name)
1202 {
1203 if (constant_map_.TryGetValue(value, out var index))
1204 {
1205 return index;
1206 }
1207
1208 index = model_.Variables.Count;
1209 IntegerVariableProto var = new IntegerVariableProto();
1210 var.Domain.Capacity = 2;
1211 var.Domain.Add(value);
1212 var.Domain.Add(value);
1213 var.Name = name;
1214 constant_map_.Add(value, index);
1215 model_.Variables.Add(var);
1216 return index;
1217 }
1218
1219 internal LinearExpr GetLinearExpr<X>(X x)
1220 {
1221 if (typeof(X) == typeof(IntVar))
1222 {
1223 return (IntVar)(Object)x;
1224 }
1225 if (typeof(X) == typeof(long) || typeof(X) == typeof(int) || typeof(X) == typeof(short))
1226 {
1227 return LinearExpr.Constant(Convert.ToInt64(x));
1228 }
1229 if (typeof(X) == typeof(LinearExpr))
1230 {
1231 return (LinearExpr)(Object)x;
1232 }
1233 throw new ArgumentException("Cannot convert argument to LinearExpr");
1234 }
1235
1236 internal LinearExpressionProto GetLinearExpressionProto(LinearExpr expr, bool negate = false)
1237 {
1238 var dict = var_value_map_;
1239 dict.Clear();
1240 long constant = LinearExpr.GetVarValueMap(expr, dict, terms_);
1241
1242 LinearExpressionProto linear = new LinearExpressionProto();
1243 var dictCount = dict.Count;
1244 linear.Vars.Capacity = dictCount;
1245 linear.Vars.AddRange(dict.Keys);
1246 linear.Coeffs.Capacity = dictCount;
1247 if (negate)
1248 {
1249 foreach (var coeff in dict.Values)
1250 {
1251 linear.Coeffs.Add(-coeff);
1252 }
1253 linear.Offset = -constant;
1254 }
1255 else
1256 {
1257 linear.Coeffs.AddRange(dict.Values);
1258 linear.Offset = constant;
1259 }
1260
1261 return linear;
1262 }
1263
1264 internal LinearExpressionProto GetLinearExpressionProto(long value)
1265 {
1266 LinearExpressionProto linear = new LinearExpressionProto();
1267 linear.Offset = value;
1268 return linear;
1269 }
1270
1271 private CpModelProto model_;
1272 private Dictionary<long, int> constant_map_;
1273 private Dictionary<int, long> var_value_map_;
1274 private BoolVar true_literal_;
1275 private Queue<Term> terms_;
1276}
1277
1278} // namespace Google.OrTools.Sat
All affine expressions must take different values.
pbc::RepeatedField< global::Google.OrTools.Sat.LinearExpressionProto > Exprs
This constraint forces a sequence of expressions to be accepted by an automaton.
pbc::RepeatedField< int > Vars
Legacy field.
Specialized automaton constraint.
Argument of the constraints of the form OP(literals).
pbc::RepeatedField< int > Literals
Holds a Boolean variable.
Holds a linear constraint: expression ∈ domain
The circuit constraint is defined on a graph where the arc presence are controlled by literals....
Specialized circuit constraint.
pbc::RepeatedField< int > EnforcementLiteral
The constraint will be enforced iff all literals listed here are true. If this is empty,...
Wrapper around a ConstraintProto.
A constraint programming problem.
pbc::RepeatedField< global::Google.OrTools.Sat.IntegerVariableProto > Variables
The associated Protos should be referred by their index in these fields.
NoOverlap2dConstraint AddNoOverlap2D()
Adds NoOverlap2D().
Definition CpModel.cs:961
Constraint AddAbsEquality(LinearExpr target, LinearExpr expr)
Adds target == abs(expr).
Definition CpModel.cs:737
ILiteral FalseLiteral()
Returns a constant false literal.
Definition CpModel.cs:118
CpModelProto Model
Getters.
Definition CpModel.cs:41
IntVar NewIntVar(long lb, long ub, string name)
Integer variables and constraints.
Definition CpModel.cs:64
Constraint AddAtLeastOne(IEnumerable< ILiteral > literals)
Same as AddBoolOr: ∑(literals) ≥ 1.
Definition CpModel.cs:593
void AddHint(ILiteral lit, bool value)
Adds variable hinting to the model.
Definition CpModel.cs:1054
Constraint AddElement(LinearExpr index, IEnumerable< LinearExpr > exprs, LinearExpr target)
Adds the element constraint: exprs[index] == target.
Definition CpModel.cs:239
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:880
AutomatonConstraint AddAutomaton(IEnumerable< LinearExpr > expressions, long starting_state, IEnumerable< long > final_states)
Adds an automaton constraint.
Definition CpModel.cs:418
BoolVar NewBoolVar(string name)
Creates a Boolean variable with given domain.
Definition CpModel.cs:98
void AddMapDomain(IntVar var, IEnumerable< IntVar > bool_vars, long offset=0)
Adds var == i + offset ⇔ bool_vars[i] == true for all i.
Definition CpModel.cs:512
Constraint AddMaxEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == Max(exprs).
Definition CpModel.cs:699
Constraint AddMultiplicationEquality(LinearExpr target, LinearExpr left, LinearExpr right)
Adds target == left * right.
Definition CpModel.cs:793
TableConstraint AddAllowedAssignments(IEnumerable< LinearExpr > exprs)
Adds AllowedAssignments(expressions).
Definition CpModel.cs:348
Constraint AddMinEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == Min(exprs).
Definition CpModel.cs:679
Constraint AddMultiplicationEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == ∏(exprs).
Definition CpModel.cs:773
Constraint AddExactlyOne(IEnumerable< ILiteral > literals)
Adds ExactlyOne(literals): ∑(literals) == 1.
Definition CpModel.cs:622
ILiteral TrueLiteral()
Returns a constant true literal.
Definition CpModel.cs:108
Constraint AddModuloEquality< T, V, M >(T target, V v, M m)
Adds target == v % m.
Definition CpModel.cs:755
void ClearHints()
Clears all hinting from the model.
Definition CpModel.cs:1071
String ModelStats()
Returns some statistics on model as a string.
Definition CpModel.cs:1154
void AddHint(IntVar var, long value)
Adds variable hinting to the model.
Definition CpModel.cs:1046
Constraint AddInverse(IEnumerable< IntVar > direct, IEnumerable< IntVar > reverse)
Adds Inverse(variables, inverseVariables).
Definition CpModel.cs:449
IntVar NewIntVarFromDomain(Domain domain, string name)
Creates an integer variable with given domain.
Definition CpModel.cs:78
void Minimize(LinearExpr obj)
Objective.
Definition CpModel.cs:1001
Constraint AddLinearConstraint(LinearExpr expr, long lb, long ub)
Adds lb ≤ expr ≤ ub.
Definition CpModel.cs:141
void AddDecisionStrategy(IEnumerable< IntVar > vars, DecisionStrategyProto.Types.VariableSelectionStrategy var_str, DecisionStrategyProto.Types.DomainReductionStrategy dom_str)
Search Decision.
Definition CpModel.cs:1027
Constraint AddLinearExpressionInDomain(LinearExpr expr, Domain domain)
Adds expr ∈ domain.
Definition CpModel.cs:158
IntVar NewConstant(long value)
Creates a constant variable.
Definition CpModel.cs:88
TableConstraint AddForbiddenAssignments(IEnumerable< LinearExpr > exprs)
Adds ForbiddenAssignments(variables).
Definition CpModel.cs:377
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:910
void ClearAssumptions()
Clears all assumptions from the model.
Definition CpModel.cs:1092
Constraint AddAtMostOne(IEnumerable< ILiteral > literals)
Adds AtMostOne(literals): ∑(literals) ≤ 1.
Definition CpModel.cs:603
Constraint AddDivisionEquality< T, N, D >(T target, N num, D denom)
Adds target == num / denom (integer division rounded towards 0).
Definition CpModel.cs:719
Constraint AddElement(LinearExpr index, IEnumerable< int > values, LinearExpr target)
Adds the element constraint: values[index] == target.
Definition CpModel.cs:281
String Validate()
Returns a non empty string explaining the issue if the model is invalid.
Definition CpModel.cs:1179
ReservoirConstraint AddReservoirConstraint(long minLevel, long maxLevel)
Adds a reservoir constraint with optional refill/emptying events.
Definition CpModel.cs:495
MultipleCircuitConstraint AddMultipleCircuit()
Adds and returns an empty multiple circuit constraint.
Definition CpModel.cs:325
CircuitConstraint AddCircuit()
Adds and returns an empty circuit constraint.
Definition CpModel.cs:307
IntervalVar NewIntervalVar< S, D, E >(S start, D size, E end, string name)
Scheduling support.
Definition CpModel.cs:823
Boolean ExportToFile(String file)
Write the model as a protocol buffer to file.
Definition CpModel.cs:1169
void Maximize(LinearExpr obj)
Adds a maximization objective of a linear expression.
Definition CpModel.cs:1007
Constraint AddElement(LinearExpr index, IEnumerable< long > values, LinearExpr target)
Adds the element constraint: values[index] == target.
Definition CpModel.cs:260
Constraint AddBoolXor(IEnumerable< ILiteral > literals)
Adds XOr(literals) == true.
Definition CpModel.cs:660
Constraint AddImplication(ILiteral a, ILiteral b)
Adds a ⇒ b.
Definition CpModel.cs:557
CumulativeConstraint AddCumulative< C >(C capacity)
Adds Cumulative(capacity).
Definition CpModel.cs:987
void AddAssumptions(IEnumerable< ILiteral > literals)
Adds multiple literals to the model as assumptions.
Definition CpModel.cs:1083
Constraint AddBoolAnd(IEnumerable< ILiteral > literals)
Adds And(literals) == true.
Definition CpModel.cs:641
Constraint Add(BoundedLinearExpression lin)
Adds a linear constraint to the model.
Definition CpModel.cs:192
Constraint AddAllDifferent(IEnumerable< LinearExpr > exprs)
Adds the constraint AllDifferent(exprs).
Definition CpModel.cs:220
Constraint AddBoolOr(IEnumerable< ILiteral > literals)
Adds Or(literals) == true.
Definition CpModel.cs:574
Constraint AddNoOverlap(IEnumerable< IntervalVar > intervals)
Definition CpModel.cs:931
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:850
void AddAssumption(ILiteral lit)
Adds a literal to the model as assumption.
Definition CpModel.cs:1077
pbc::RepeatedField< int > Vars
The linear terms of the objective to minimize. For a maximization problem, one can negate all coeffic...
pbc::RepeatedField< long > Coeffs
static string ModelStats(Google.OrTools.Sat.CpModelProto model_proto)
static string ValidateModel(Google.OrTools.Sat.CpModelProto model_proto)
static bool WriteModelToFile(Google.OrTools.Sat.CpModelProto model_proto, string filename)
The sum of the demands of the intervals at each interval point cannot exceed a capacity....
Specialized cumulative constraint.
Container for nested types declared in the DecisionStrategyProto message type.
DomainReductionStrategy
Once a variable (resp. affine expression) has been chosen, this enum describe what decision is taken ...
VariableSelectionStrategy
The order in which the variables (resp. affine expression) above should be considered....
Define the strategy to follow when the solver needs to take a new decision.
pbc::RepeatedField< int > Variables
The variables to be considered for the next decision. The order matter and is always used as a tie-br...
The constraint target = vars[index]. This enforces that index takes one of the value in [0,...
pbc::RepeatedField< global::Google.OrTools.Sat.LinearExpressionProto > Exprs
Holds a integer variable with a discrete domain.
The two arrays of variable each represent a function, the second is the inverse of the first: f_direc...
pbc::RepeatedField< global::Google.OrTools.Sat.LinearExpressionProto > Exprs
The linear sum vars[i] * coeffs[i] must fall in the given domain. The domain has the same format as t...
pbc::RepeatedField< long > Coeffs
Same size as vars.
pbc::RepeatedField< long > Domain
Holds a linear expression: sum (ai * xi) + b.
static LinearExpr Sum(IEnumerable< LinearExpr > exprs)
Creates Sum(exprs).
Some constraints supports linear expression instead of just using a reference to a variable....
pbc::RepeatedField< long > Coeffs
Specialized multiple circuit constraint.
The boxes defined by [start_x, end_x) * [start_y, end_y) cannot overlap. Furthermore,...
Specialized NoOverlap2D constraint.
All the intervals (index of IntervalConstraintProto) must be disjoint. More formally,...
This message encodes a partial (or full) assignment of the variables of a CpModelProto....
Maintain a reservoir level within bounds. The water level starts at 0, and at any time,...
Specialized reservoir constraint.
The "VRP" (Vehicle Routing Problem) constraint.
The values of the n-tuple formed by the given expression can only be one of the listed n-tuples in va...
pbc::RepeatedField< int > Vars
Legacy field.
Specialized assignment constraint.
long[] FlattenedIntervals()
Definition Domain.cs:99
Holds a Boolean variable or its negation.
int GetIndex()
Returns the logical index of the literal.
ILiteral Not()
Returns the Boolean negation of the literal.