17using System.Collections.Generic;
28 constant_map_ =
new Dictionary<long, int>();
29 var_value_map_ =
new Dictionary<int, long>(10);
30 terms_ =
new Queue<Term>(10);
47 int Negated(
int index)
66 return new IntVar(model_, lb, ub, name);
80 return new IntVar(model_, domain, name);
90 return new IntVar(model_, ConvertConstant(value));
100 return new BoolVar(model_, name);
110 return true_literal_ ??=
new BoolVar(model_, ConvertConstantWithName(1,
"true"));
125 var dict = var_value_map_;
127 long constant =
LinearExpr.GetVarValueMap(expr, dict, terms_);
128 var count = dict.Count;
130 linear.Vars.Capacity = count;
131 linear.Vars.AddRange(dict.Keys);
132 linear.Coeffs.Capacity = count;
133 linear.Coeffs.AddRange(dict.Values);
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);
149 ct.Proto.Linear = linear;
160 long constant = FillLinearConstraint(expr, out var linear);
162 linear.Domain.Capacity = array.Length;
163 foreach (
long value
in array)
165 linear.Domain.Add(value is Int64.MinValue or Int64.MaxValue ? value : value - constant);
169 ct.Proto.Linear = linear;
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);
183 ct.Proto.Linear = linear;
203 return AddLinearExpressionNotEqualCst(lin.
Left - lin.
Right, 0);
209 return AddLinearExpressionNotEqualCst(lin.
Left, lin.
Lb);
223 alldiff.
Exprs.TrySetCapacity(exprs);
226 alldiff.Exprs.Add(GetLinearExpressionProto(expr));
230 ct.Proto.AllDiff = alldiff;
242 element.Index = index.
Index;
243 element.
Vars.TrySetCapacity(vars);
244 foreach (
IntVar var
in vars)
246 element.Vars.Add(var.
Index);
248 element.Target = target.Index;
251 ct.Proto.Element = element;
263 element.Index = index.
Index;
264 element.
Vars.TrySetCapacity(values);
265 foreach (
long value
in values)
267 element.Vars.Add(ConvertConstant(value));
269 element.Target = target.Index;
272 ct.Proto.Element = element;
284 element.Index = index.
Index;
285 element.
Vars.TrySetCapacity(values);
286 foreach (
int value
in values)
288 element.Vars.Add(ConvertConstant(value));
290 element.Target = target.Index;
293 ct.Proto.Element = element;
350 table.
Vars.TrySetCapacity(vars);
351 foreach (
IntVar var
in vars)
353 table.Vars.Add(var.
Index);
357 ct.Proto.Table = table;
378 ct.Proto.Table.Negated =
true;
416 IEnumerable<long> final_states)
419 aut.
Vars.TrySetCapacity(vars);
420 foreach (
IntVar var
in vars)
422 aut.Vars.Add(var.
Index);
425 aut.StartingState = starting_state;
426 aut.FinalStates.AddRange(final_states);
429 ct.Proto.Automaton = aut;
449 inverse.
FDirect.TrySetCapacity(direct);
450 foreach (
IntVar var
in direct)
452 inverse.FDirect.Add(var.
Index);
455 inverse.FInverse.TrySetCapacity(reverse);
456 foreach (
IntVar var
in reverse)
458 inverse.FInverse.Add(var.
Index);
462 ct.Proto.Inverse = inverse;
496 res.MinLevel = minLevel;
497 res.MaxLevel = maxLevel;
500 ct.Proto.Reservoir = res;
512 int var_index = var.
Index;
513 foreach (
IntVar bool_var
in bool_vars)
515 int b_index = bool_var.
Index;
518 lin1.Vars.Capacity = 1;
519 lin1.
Vars.Add(var_index);
520 lin1.Coeffs.Capacity = 1;
522 lin1.Domain.Capacity = 2;
523 lin1.
Domain.Add(offset + i);
524 lin1.
Domain.Add(offset + i);
531 lin2.Vars.Capacity = 1;
532 lin2.
Vars.Add(var_index);
533 lin2.Coeffs.Capacity = 1;
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);
557 or.Literals.Capacity = 2;
562 ct.Proto.BoolOr = or;
574 bool_argument.
Literals.TrySetCapacity(literals);
577 bool_argument.Literals.Add(lit.
GetIndex());
581 ct.Proto.BoolOr = bool_argument;
603 bool_argument.
Literals.TrySetCapacity(literals);
606 bool_argument.Literals.Add(lit.
GetIndex());
610 ct.Proto.AtMostOne = bool_argument;
622 bool_argument.
Literals.TrySetCapacity(literals);
625 bool_argument.Literals.Add(lit.
GetIndex());
629 ct.Proto.ExactlyOne = bool_argument;
641 bool_argument.
Literals.TrySetCapacity(literals);
644 bool_argument.Literals.Add(lit.
GetIndex());
648 ct.Proto.BoolAnd = bool_argument;
660 bool_argument.
Literals.TrySetCapacity(literals);
663 bool_argument.Literals.Add(lit.
GetIndex());
667 ct.Proto.BoolXor = bool_argument;
679 lin.
Exprs.TrySetCapacity(exprs);
682 lin.Exprs.Add(GetLinearExpressionProto(expr,
true));
684 lin.Target = GetLinearExpressionProto(target,
true);
687 ct.Proto.LinMax = lin;
699 lin.
Exprs.TrySetCapacity(exprs);
702 lin.Exprs.Add(GetLinearExpressionProto(expr));
704 lin.Target = GetLinearExpressionProto(target);
707 ct.Proto.LinMax = lin;
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));
725 ct.Proto.IntDiv = div;
737 abs.Exprs.Capacity = 2;
738 abs.
Exprs.Add(GetLinearExpressionProto(expr));
739 abs.
Exprs.Add(GetLinearExpressionProto(expr,
true));
740 abs.Target = GetLinearExpressionProto(target);
743 ct.Proto.LinMax = abs;
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));
761 ct.Proto.IntMod = mod;
773 prod.Target = GetLinearExpressionProto(target);
774 prod.
Exprs.TrySetCapacity(exprs);
777 prod.Exprs.Add(GetLinearExpressionProto(expr));
781 ct.Proto.IntProd = prod;
793 prod.Target = GetLinearExpressionProto(target);
794 prod.Exprs.Capacity = 2;
795 prod.
Exprs.Add(GetLinearExpressionProto(left));
796 prod.
Exprs.Add(GetLinearExpressionProto(right));
799 ct.Proto.IntProd = prod;
829 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
856 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
886 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.
GetIndex(), name);
916 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.
GetIndex(), name);
931 no_overlap.
Intervals.TrySetCapacity(intervals);
934 no_overlap.Intervals.Add(var.
GetIndex());
938 ct.Proto.NoOverlap = no_overlap;
987 LinearExpr capacityExpr = GetLinearExpr(capacity);
988 cumul.Capacity = GetLinearExpressionProto(capacityExpr);
991 ct.Proto.Cumulative = cumul;
1000 SetObjective(obj,
true);
1006 SetObjective(obj,
false);
1010 void ClearObjective()
1012 model_.Objective =
null;
1018 return model_.Objective is not
null || model_.FloatingPointObjective is not
null;
1030 foreach (
IntVar var
in vars)
1037 ds.VariableSelectionStrategy = var_str;
1038 ds.DomainReductionStrategy = dom_str;
1070 model_.SolutionHint =
null;
1096 void SetObjective(
LinearExpr obj,
bool minimize)
1101 objective.Offset = 0L;
1102 objective.ScalingFactor = minimize ? 1L : -1;
1104 else if (obj is IntVar intVar)
1106 objective.Offset = 0L;
1107 objective.Vars.Capacity = 1;
1108 objective.
Vars.Add(intVar.Index);
1110 objective.Coeffs.Capacity = 1;
1113 objective.
Coeffs.Add(1L);
1114 objective.ScalingFactor = 1L;
1118 objective.
Coeffs.Add(-1L);
1119 objective.ScalingFactor = -1L;
1124 var dict = var_value_map_;
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;
1133 objective.
Coeffs.AddRange(dict.Values);
1134 objective.ScalingFactor = 1L;
1135 objective.Offset = constant;
1139 foreach (var coeff
in dict.Values)
1141 objective.
Coeffs.Add(-coeff);
1143 objective.ScalingFactor = -1L;
1144 objective.Offset = -constant;
1147 model_.Objective = objective;
1181 private int ConvertConstant(
long value)
1183 if (constant_map_.TryGetValue(value, out var index))
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);
1198 private int ConvertConstantWithName(
long value,
string name)
1200 if (constant_map_.TryGetValue(value, out var index))
1206 IntegerVariableProto var =
new IntegerVariableProto();
1207 var.Domain.Capacity = 2;
1208 var.Domain.Add(value);
1209 var.Domain.Add(value);
1211 constant_map_.Add(value, index);
1216 internal LinearExpr GetLinearExpr<X>(X x)
1218 if (typeof(X) == typeof(IntVar))
1220 return (IntVar)(Object)x;
1222 if (typeof(X) == typeof(
long) || typeof(X) == typeof(
int) || typeof(X) == typeof(
short))
1224 return LinearExpr.Constant(Convert.ToInt64(x));
1226 if (typeof(X) == typeof(LinearExpr))
1228 return (LinearExpr)(Object)x;
1230 throw new ArgumentException(
"Cannot convert argument to LinearExpr");
1233 internal LinearExpressionProto GetLinearExpressionProto(LinearExpr expr,
bool negate =
false)
1235 var dict = var_value_map_;
1237 long constant = LinearExpr.GetVarValueMap(expr, dict, terms_);
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;
1246 foreach (var coeff
in dict.Values)
1248 linear.Coeffs.Add(-coeff);
1250 linear.Offset = -constant;
1254 linear.Coeffs.AddRange(dict.Values);
1255 linear.Offset = constant;
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_;
long[] FlattenedIntervals()