Google OR-Tools v9.11
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-2024 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;
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(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_);
310 ct.Proto.Circuit = new CircuitConstraintProto();
311 return ct;
312 }
313
326 {
328 ct.Proto.Routes = new RoutesConstraintProto();
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
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
509 public void AddMapDomain(IntVar var, IEnumerable<IntVar> bool_vars, long offset = 0)
510 {
511 int i = 0;
512 int var_index = var.Index;
513 foreach (IntVar bool_var in bool_vars)
514 {
515 int b_index = bool_var.Index;
516
518 lin1.Vars.Capacity = 1;
519 lin1.Vars.Add(var_index);
520 lin1.Coeffs.Capacity = 1;
521 lin1.Coeffs.Add(1L);
522 lin1.Domain.Capacity = 2;
523 lin1.Domain.Add(offset + i);
524 lin1.Domain.Add(offset + i);
526 ct1.Linear = lin1;
527 ct1.EnforcementLiteral.Add(b_index);
528 model_.Constraints.Add(ct1);
529
531 lin2.Vars.Capacity = 1;
532 lin2.Vars.Add(var_index);
533 lin2.Coeffs.Capacity = 1;
534 lin2.Coeffs.Add(1L);
535 lin2.Domain.Capacity = 4;
536 lin2.Domain.Add(Int64.MinValue);
537 lin2.Domain.Add(offset + i - 1);
538 lin2.Domain.Add(offset + i + 1);
539 lin2.Domain.Add(Int64.MaxValue);
541 ct2.Linear = lin2;
542 ct2.EnforcementLiteral.Add(-b_index - 1);
543 model_.Constraints.Add(ct2);
544
545 i++;
546 }
547 }
548
555 {
557 or.Literals.Capacity = 2;
558 or.Literals.Add(a.Not().GetIndex());
559 or.Literals.Add(b.GetIndex());
560
561 Constraint ct = new Constraint(model_);
562 ct.Proto.BoolOr = or;
563 return ct;
564 }
565
571 public Constraint AddBoolOr(IEnumerable<ILiteral> literals)
572 {
573 BoolArgumentProto bool_argument = new BoolArgumentProto();
574 bool_argument.Literals.TrySetCapacity(literals);
575 foreach (ILiteral lit in literals)
576 {
577 bool_argument.Literals.Add(lit.GetIndex());
578 }
579
580 Constraint ct = new Constraint(model_);
581 ct.Proto.BoolOr = bool_argument;
582 return ct;
583 }
584
590 public Constraint AddAtLeastOne(IEnumerable<ILiteral> literals)
591 {
592 return AddBoolOr(literals);
593 }
594
600 public Constraint AddAtMostOne(IEnumerable<ILiteral> literals)
601 {
602 BoolArgumentProto bool_argument = new BoolArgumentProto();
603 bool_argument.Literals.TrySetCapacity(literals);
604 foreach (ILiteral lit in literals)
605 {
606 bool_argument.Literals.Add(lit.GetIndex());
607 }
608
609 Constraint ct = new Constraint(model_);
610 ct.Proto.AtMostOne = bool_argument;
611 return ct;
612 }
613
619 public Constraint AddExactlyOne(IEnumerable<ILiteral> literals)
620 {
621 BoolArgumentProto bool_argument = new BoolArgumentProto();
622 bool_argument.Literals.TrySetCapacity(literals);
623 foreach (ILiteral lit in literals)
624 {
625 bool_argument.Literals.Add(lit.GetIndex());
626 }
627
628 Constraint ct = new Constraint(model_);
629 ct.Proto.ExactlyOne = bool_argument;
630 return ct;
631 }
632
638 public Constraint AddBoolAnd(IEnumerable<ILiteral> literals)
639 {
640 BoolArgumentProto bool_argument = new BoolArgumentProto();
641 bool_argument.Literals.TrySetCapacity(literals);
642 foreach (ILiteral lit in literals)
643 {
644 bool_argument.Literals.Add(lit.GetIndex());
645 }
646
647 Constraint ct = new Constraint(model_);
648 ct.Proto.BoolAnd = bool_argument;
649 return ct;
650 }
651
657 public Constraint AddBoolXor(IEnumerable<ILiteral> literals)
658 {
659 BoolArgumentProto bool_argument = new BoolArgumentProto();
660 bool_argument.Literals.TrySetCapacity(literals);
661 foreach (ILiteral lit in literals)
662 {
663 bool_argument.Literals.Add(lit.GetIndex());
664 }
665
666 Constraint ct = new Constraint(model_);
667 ct.Proto.BoolXor = bool_argument;
668 return ct;
669 }
670
676 public Constraint AddMinEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
677 {
679 lin.Exprs.TrySetCapacity(exprs);
680 foreach (LinearExpr expr in exprs)
681 {
682 lin.Exprs.Add(GetLinearExpressionProto(expr, /*negate=*/true));
683 }
684 lin.Target = GetLinearExpressionProto(target, /*negate=*/true);
685
686 Constraint ct = new Constraint(model_);
687 ct.Proto.LinMax = lin;
688 return ct;
689 }
690
696 public Constraint AddMaxEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
697 {
699 lin.Exprs.TrySetCapacity(exprs);
700 foreach (LinearExpr expr in exprs)
701 {
702 lin.Exprs.Add(GetLinearExpressionProto(expr));
703 }
704 lin.Target = GetLinearExpressionProto(target);
705
706 Constraint ct = new Constraint(model_);
707 ct.Proto.LinMax = lin;
708 return ct;
709 }
710
716 public Constraint AddDivisionEquality<T, N, D>(T target, N num, D denom)
717 {
719 div.Exprs.Capacity = 2;
720 div.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(num)));
721 div.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(denom)));
722 div.Target = GetLinearExpressionProto(GetLinearExpr(target));
723
724 Constraint ct = new Constraint(model_);
725 ct.Proto.IntDiv = div;
726 return ct;
727 }
728
735 {
737 abs.Exprs.Capacity = 2;
738 abs.Exprs.Add(GetLinearExpressionProto(expr));
739 abs.Exprs.Add(GetLinearExpressionProto(expr, /*negate=*/true));
740 abs.Target = GetLinearExpressionProto(target);
741
742 Constraint ct = new Constraint(model_);
743 ct.Proto.LinMax = abs;
744 return ct;
745 }
746
752 public Constraint AddModuloEquality<T, V, M>(T target, V v, M m)
753 {
755 mod.Exprs.Capacity = 2;
756 mod.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(v)));
757 mod.Exprs.Add(GetLinearExpressionProto(GetLinearExpr(m)));
758 mod.Target = GetLinearExpressionProto(GetLinearExpr(target));
759
760 Constraint ct = new Constraint(model_);
761 ct.Proto.IntMod = mod;
762 return ct;
763 }
764
770 public Constraint AddMultiplicationEquality(LinearExpr target, IEnumerable<LinearExpr> exprs)
771 {
773 prod.Target = GetLinearExpressionProto(target);
774 prod.Exprs.TrySetCapacity(exprs);
775 foreach (LinearExpr expr in exprs)
776 {
777 prod.Exprs.Add(GetLinearExpressionProto(expr));
778 }
779
780 Constraint ct = new Constraint(model_);
781 ct.Proto.IntProd = prod;
782 return ct;
783 }
784
791 {
793 prod.Target = GetLinearExpressionProto(target);
794 prod.Exprs.Capacity = 2;
795 prod.Exprs.Add(GetLinearExpressionProto(left));
796 prod.Exprs.Add(GetLinearExpressionProto(right));
797
798 Constraint ct = new Constraint(model_);
799 ct.Proto.IntProd = prod;
800 return ct;
801 }
802
803 // Scheduling support
804
820 public IntervalVar NewIntervalVar<S, D, E>(S start, D size, E end, string name)
821 {
822 LinearExpr startExpr = GetLinearExpr(start);
823 LinearExpr sizeExpr = GetLinearExpr(size);
824 LinearExpr endExpr = GetLinearExpr(end);
825
826 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
827 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
828 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
829 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
830 }
831
847 public IntervalVar NewFixedSizeIntervalVar<S>(S start, long size, string name)
848 {
849 LinearExpr startExpr = GetLinearExpr(start);
850 LinearExpr sizeExpr = GetLinearExpr(size);
851 LinearExpr endExpr = LinearExpr.Sum(new LinearExpr[] { startExpr, sizeExpr });
852
853 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
854 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
855 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
856 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
857 }
858
877 public IntervalVar NewOptionalIntervalVar<S, D, E>(S start, D size, E end, ILiteral is_present, string name)
878 {
879 LinearExpr startExpr = GetLinearExpr(start);
880 LinearExpr sizeExpr = GetLinearExpr(size);
881 LinearExpr endExpr = GetLinearExpr(end);
882
883 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
884 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
885 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
886 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.GetIndex(), name);
887 }
888
907 public IntervalVar NewOptionalFixedSizeIntervalVar<S>(S start, long size, ILiteral is_present, string name)
908 {
909 LinearExpr startExpr = GetLinearExpr(start);
910 LinearExpr sizeExpr = GetLinearExpr(size);
911 LinearExpr endExpr = LinearExpr.Sum(new LinearExpr[] { startExpr, sizeExpr });
912
913 LinearExpressionProto startProto = GetLinearExpressionProto(startExpr);
914 LinearExpressionProto sizeProto = GetLinearExpressionProto(sizeExpr);
915 LinearExpressionProto endProto = GetLinearExpressionProto(endExpr);
916 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.GetIndex(), name);
917 }
918
928 public Constraint AddNoOverlap(IEnumerable<IntervalVar> intervals)
929 {
931 no_overlap.Intervals.TrySetCapacity(intervals);
932 foreach (IntervalVar var in intervals)
933 {
934 no_overlap.Intervals.Add(var.GetIndex());
935 }
936
937 Constraint ct = new Constraint(model_);
938 ct.Proto.NoOverlap = no_overlap;
939 return ct;
940 }
941
959 {
961 ct.Proto.NoOverlap2D = new NoOverlap2DConstraintProto();
962 return ct;
963 }
964
985 {
987 LinearExpr capacityExpr = GetLinearExpr(capacity);
988 cumul.Capacity = GetLinearExpressionProto(capacityExpr);
989
990 CumulativeConstraint ct = new CumulativeConstraint(this, model_);
991 ct.Proto.Cumulative = cumul;
992 return ct;
993 }
994
995 // Objective.
996
998 public void Minimize(LinearExpr obj)
999 {
1000 SetObjective(obj, true);
1001 }
1002
1004 public void Maximize(LinearExpr obj)
1005 {
1006 SetObjective(obj, false);
1007 }
1008
1010 void ClearObjective()
1011 {
1012 model_.Objective = null;
1013 }
1014
1016 bool HasObjective()
1017 {
1018 return model_.Objective is not null || model_.FloatingPointObjective is not null;
1019 }
1020
1021 // Search Decision.
1022
1024 public void AddDecisionStrategy(IEnumerable<IntVar> vars,
1027 {
1029 ds.Variables.TrySetCapacity(vars);
1030 foreach (IntVar var in vars)
1031 {
1033 expr.Vars.Add(var.Index);
1034 expr.Coeffs.Add(1);
1035 ds.Exprs.Add(expr);
1036 }
1037 ds.VariableSelectionStrategy = var_str;
1038 ds.DomainReductionStrategy = dom_str;
1039 model_.SearchStrategy.Add(ds);
1040 }
1041
1043 public void AddHint(IntVar var, long value)
1044 {
1045 model_.SolutionHint ??= new PartialVariableAssignment();
1046 model_.SolutionHint.Vars.Add(var.GetIndex());
1047 model_.SolutionHint.Values.Add(value);
1048 }
1049
1051 public void AddHint(ILiteral lit, bool value)
1052 {
1053 model_.SolutionHint ??= new PartialVariableAssignment();
1054 int index = lit.GetIndex();
1055 if (index >= 0)
1056 {
1057 model_.SolutionHint.Vars.Add(index);
1058 model_.SolutionHint.Values.Add(value ? 1 : 0);
1059 }
1060 else
1061 {
1062 model_.SolutionHint.Vars.Add(Negated(index));
1063 model_.SolutionHint.Values.Add(value ? 0 : 1);
1064 }
1065 }
1066
1068 public void ClearHints()
1069 {
1070 model_.SolutionHint = null;
1071 }
1072
1074 public void AddAssumption(ILiteral lit)
1075 {
1076 model_.Assumptions.Add(lit.GetIndex());
1077 }
1078
1080 public void AddAssumptions(IEnumerable<ILiteral> literals)
1081 {
1082 foreach (ILiteral lit in literals)
1083 {
1084 AddAssumption(lit);
1085 }
1086 }
1087
1089 public void ClearAssumptions()
1090 {
1091 model_.Assumptions.Clear();
1092 }
1093
1094 // Internal methods.
1095
1096 void SetObjective(LinearExpr obj, bool minimize)
1097 {
1098 CpObjectiveProto objective = new CpObjectiveProto();
1099 if (obj is null)
1100 {
1101 objective.Offset = 0L;
1102 objective.ScalingFactor = minimize ? 1L : -1;
1103 }
1104 else if (obj is IntVar intVar)
1105 {
1106 objective.Offset = 0L;
1107 objective.Vars.Capacity = 1;
1108 objective.Vars.Add(intVar.Index);
1109
1110 objective.Coeffs.Capacity = 1;
1111 if (minimize)
1112 {
1113 objective.Coeffs.Add(1L);
1114 objective.ScalingFactor = 1L;
1115 }
1116 else
1117 {
1118 objective.Coeffs.Add(-1L);
1119 objective.ScalingFactor = -1L;
1120 }
1121 }
1122 else
1123 {
1124 var dict = var_value_map_;
1125 dict.Clear();
1126 long constant = LinearExpr.GetVarValueMap(obj, dict, terms_);
1127 var dictCount = dict.Count;
1128 objective.Vars.Capacity = dictCount;
1129 objective.Vars.AddRange(dict.Keys);
1130 objective.Coeffs.Capacity = dictCount;
1131 if (minimize)
1132 {
1133 objective.Coeffs.AddRange(dict.Values);
1134 objective.ScalingFactor = 1L;
1135 objective.Offset = constant;
1136 }
1137 else
1138 {
1139 foreach (var coeff in dict.Values)
1140 {
1141 objective.Coeffs.Add(-coeff);
1142 }
1143 objective.ScalingFactor = -1L;
1144 objective.Offset = -constant;
1145 }
1146 }
1147 model_.Objective = objective;
1148 }
1149
1151 public String ModelStats()
1152 {
1153 return CpSatHelper.ModelStats(model_);
1154 }
1155
1166 public Boolean ExportToFile(String file)
1167 {
1168 return CpSatHelper.WriteModelToFile(model_, file);
1169 }
1170
1176 public String Validate()
1177 {
1178 return CpSatHelper.ValidateModel(model_);
1179 }
1180
1181 private int ConvertConstant(long value)
1182 {
1183 if (constant_map_.TryGetValue(value, out var index))
1184 {
1185 return index;
1186 }
1187
1188 index = model_.Variables.Count;
1189 IntegerVariableProto var = new IntegerVariableProto();
1190 var.Domain.Capacity = 2;
1191 var.Domain.Add(value);
1192 var.Domain.Add(value);
1193 constant_map_.Add(value, index);
1194 model_.Variables.Add(var);
1195 return index;
1196 }
1197
1198 private int ConvertConstantWithName(long value, string name)
1199 {
1200 if (constant_map_.TryGetValue(value, out var index))
1201 {
1202 return index;
1203 }
1204
1205 index = model_.Variables.Count;
1206 IntegerVariableProto var = new IntegerVariableProto();
1207 var.Domain.Capacity = 2;
1208 var.Domain.Add(value);
1209 var.Domain.Add(value);
1210 var.Name = name;
1211 constant_map_.Add(value, index);
1212 model_.Variables.Add(var);
1213 return index;
1214 }
1215
1216 internal LinearExpr GetLinearExpr<X>(X x)
1217 {
1218 if (typeof(X) == typeof(IntVar))
1219 {
1220 return (IntVar)(Object)x;
1221 }
1222 if (typeof(X) == typeof(long) || typeof(X) == typeof(int) || typeof(X) == typeof(short))
1223 {
1224 return LinearExpr.Constant(Convert.ToInt64(x));
1225 }
1226 if (typeof(X) == typeof(LinearExpr))
1227 {
1228 return (LinearExpr)(Object)x;
1229 }
1230 throw new ArgumentException("Cannot convert argument to LinearExpr");
1231 }
1232
1233 internal LinearExpressionProto GetLinearExpressionProto(LinearExpr expr, bool negate = false)
1234 {
1235 var dict = var_value_map_;
1236 dict.Clear();
1237 long constant = LinearExpr.GetVarValueMap(expr, dict, terms_);
1238
1239 LinearExpressionProto linear = new LinearExpressionProto();
1240 var dictCount = dict.Count;
1241 linear.Vars.Capacity = dictCount;
1242 linear.Vars.AddRange(dict.Keys);
1243 linear.Coeffs.Capacity = dictCount;
1244 if (negate)
1245 {
1246 foreach (var coeff in dict.Values)
1247 {
1248 linear.Coeffs.Add(-coeff);
1249 }
1250 linear.Offset = -constant;
1251 }
1252 else
1253 {
1254 linear.Coeffs.AddRange(dict.Values);
1255 linear.Offset = constant;
1256 }
1257
1258 return linear;
1259 }
1260
1261 private CpModelProto model_;
1262 private Dictionary<long, int> constant_map_;
1263 private Dictionary<int, long> var_value_map_;
1264 private BoolVar true_literal_;
1265 private Queue<Term> terms_;
1266}
1267
1268} // 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 variables to be accepted by an automaton.
pbc::RepeatedField< int > Vars
The sequence of variables. The automaton is ran for vars_size() "steps" and the value of vars[i] corr...
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.
global::Google.OrTools.Sat.PartialVariableAssignment SolutionHint
Solution hint.
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...
pbc::RepeatedField< global::Google.OrTools.Sat.ConstraintProto > Constraints
pbc::RepeatedField< int > Assumptions
A list of literals. The model will be solved assuming all these literals are true....
Wrapper class around the cp_model proto.
Definition CpModel.cs:24
NoOverlap2dConstraint AddNoOverlap2D()
Adds NoOverlap2D().
Definition CpModel.cs:958
Constraint AddAbsEquality(LinearExpr target, LinearExpr expr)
Adds target == abs(expr).
Definition CpModel.cs:734
AutomatonConstraint AddAutomaton(IEnumerable< IntVar > vars, long starting_state, IEnumerable< long > final_states)
Adds an automaton constraint.
Definition CpModel.cs:415
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:590
void AddHint(ILiteral lit, bool value)
Adds variable hinting to the model.
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:877
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:509
Constraint AddMaxEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == Max(exprs).
Definition CpModel.cs:696
Constraint AddMultiplicationEquality(LinearExpr target, LinearExpr left, LinearExpr right)
Adds target == left * right.
Definition CpModel.cs:790
Constraint AddMinEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == Min(exprs).
Definition CpModel.cs:676
Constraint AddMultiplicationEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == ∏(exprs).
Definition CpModel.cs:770
Constraint AddExactlyOne(IEnumerable< ILiteral > literals)
Adds ExactlyOne(literals): ∑(literals) == 1.
Definition CpModel.cs:619
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:752
void ClearHints()
Clears all hinting from the model.
Definition CpModel.cs:1068
String ModelStats()
Returns some statistics on model as a string.
Definition CpModel.cs:1151
void AddHint(IntVar var, long value)
Adds variable hinting to the model.
Definition CpModel.cs:1043
Constraint AddInverse(IEnumerable< IntVar > direct, IEnumerable< IntVar > reverse)
Adds Inverse(variables, inverseVariables).
Definition CpModel.cs:446
Constraint AddElement(IntVar index, IEnumerable< long > values, IntVar target)
Adds the element constraint: values[index] == target.
Definition CpModel.cs:260
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:998
Constraint AddElement(IntVar index, IEnumerable< int > values, IntVar target)
Adds the element constraint: values[index] == target.
Definition CpModel.cs:281
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:1024
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< IntVar > vars)
Adds ForbiddenAssignments(variables).
Definition CpModel.cs:375
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:907
void ClearAssumptions()
Clears all assumptions from the model.
Definition CpModel.cs:1089
Constraint AddAtMostOne(IEnumerable< ILiteral > literals)
Adds AtMostOne(literals): ∑(literals) ≤ 1.
Definition CpModel.cs:600
Constraint AddElement(IntVar index, IEnumerable< IntVar > vars, IntVar target)
Adds the element constraint: variables[index] == target.
Definition CpModel.cs:239
Constraint AddDivisionEquality< T, N, D >(T target, N num, D denom)
Adds target == num / denom (integer division rounded towards 0).
Definition CpModel.cs:716
String Validate()
Returns a non empty string explaining the issue if the model is invalid.
Definition CpModel.cs:1176
ReservoirConstraint AddReservoirConstraint(long minLevel, long maxLevel)
Adds a reservoir constraint with optional refill/emptying events.
Definition CpModel.cs:492
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:820
Boolean ExportToFile(String file)
Write the model as a protocol buffer to file.
Definition CpModel.cs:1166
void Maximize(LinearExpr obj)
Adds a maximization objective of a linear expression.
Definition CpModel.cs:1004
Constraint AddBoolXor(IEnumerable< ILiteral > literals)
Adds XOr(literals) == true.
Definition CpModel.cs:657
Constraint AddImplication(ILiteral a, ILiteral b)
Adds a ⇒ b.
Definition CpModel.cs:554
CumulativeConstraint AddCumulative< C >(C capacity)
Adds Cumulative(capacity).
Definition CpModel.cs:984
void AddAssumptions(IEnumerable< ILiteral > literals)
Adds multiple literals to the model as assumptions.
Definition CpModel.cs:1080
Constraint AddBoolAnd(IEnumerable< ILiteral > literals)
Adds And(literals) == true.
Definition CpModel.cs:638
Constraint Add(BoundedLinearExpression lin)
Adds a linear constraint to the model.
Definition CpModel.cs:192
TableConstraint AddAllowedAssignments(IEnumerable< IntVar > vars)
Adds AllowedAssignments(variables).
Definition CpModel.cs:347
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:571
Constraint AddNoOverlap(IEnumerable< IntervalVar > intervals)
Definition CpModel.cs:928
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:847
void AddAssumption(ILiteral lit)
Adds a literal to the model as assumption.
Definition CpModel.cs:1074
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,...
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 variables can only be one of the listed n-tuples in val...
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.