17using System.Collections.Generic;
18using Google.OrTools.Util;
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.LinearIndex = GetLinearExpressionProto(index);
243 element.
Exprs.TrySetCapacity(exprs);
246 element.Exprs.Add(GetLinearExpressionProto(expr));
248 element.LinearTarget = GetLinearExpressionProto(target);
251 ct.Proto.Element = element;
263 element.LinearIndex = GetLinearExpressionProto(index);
264 element.
Exprs.TrySetCapacity(values);
265 foreach (
long value
in values)
267 element.Exprs.Add(GetLinearExpressionProto(value));
269 element.LinearTarget = GetLinearExpressionProto(target);
272 ct.Proto.Element = element;
284 element.LinearIndex = GetLinearExpressionProto(index);
285 element.
Exprs.TrySetCapacity(values);
286 foreach (
int value
in values)
288 element.Exprs.Add(GetLinearExpressionProto(value));
290 element.LinearTarget = GetLinearExpressionProto(target);
293 ct.Proto.Element = element;
351 table.
Vars.TrySetCapacity(exprs);
354 table.Exprs.Add(GetLinearExpressionProto(expr));
358 ct.Proto.Table = table;
380 ct.Proto.Table.Negated =
true;
419 IEnumerable<long> final_states)
422 automaton.
Vars.TrySetCapacity(expressions);
425 automaton.Exprs.Add(GetLinearExpressionProto(expr));
428 automaton.StartingState = starting_state;
429 automaton.FinalStates.AddRange(final_states);
432 ct.Proto.Automaton = automaton;
452 inverse.
FDirect.TrySetCapacity(direct);
453 foreach (
IntVar var
in direct)
455 inverse.FDirect.Add(var.
Index);
458 inverse.FInverse.TrySetCapacity(reverse);
459 foreach (
IntVar var
in reverse)
461 inverse.FInverse.Add(var.
Index);
465 ct.Proto.Inverse = inverse;
499 res.MinLevel = minLevel;
500 res.MaxLevel = maxLevel;
503 ct.Proto.Reservoir = res;
515 int var_index = var.
Index;
516 foreach (
IntVar bool_var
in bool_vars)
518 int b_index = bool_var.
Index;
521 lin1.Vars.Capacity = 1;
522 lin1.
Vars.Add(var_index);
523 lin1.Coeffs.Capacity = 1;
525 lin1.Domain.Capacity = 2;
526 lin1.
Domain.Add(offset + i);
527 lin1.
Domain.Add(offset + i);
531 model_.Constraints.Add(ct1);
534 lin2.Vars.Capacity = 1;
535 lin2.
Vars.Add(var_index);
536 lin2.Coeffs.Capacity = 1;
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);
546 model_.Constraints.Add(ct2);
560 or.Literals.Capacity = 2;
565 ct.Proto.BoolOr = or;
577 bool_argument.
Literals.TrySetCapacity(literals);
580 bool_argument.Literals.Add(lit.
GetIndex());
584 ct.Proto.BoolOr = bool_argument;
606 bool_argument.
Literals.TrySetCapacity(literals);
609 bool_argument.Literals.Add(lit.
GetIndex());
613 ct.Proto.AtMostOne = bool_argument;
625 bool_argument.
Literals.TrySetCapacity(literals);
628 bool_argument.Literals.Add(lit.
GetIndex());
632 ct.Proto.ExactlyOne = bool_argument;
644 bool_argument.
Literals.TrySetCapacity(literals);
647 bool_argument.Literals.Add(lit.
GetIndex());
651 ct.Proto.BoolAnd = bool_argument;
663 bool_argument.
Literals.TrySetCapacity(literals);
666 bool_argument.Literals.Add(lit.
GetIndex());
670 ct.Proto.BoolXor = bool_argument;
682 lin.
Exprs.TrySetCapacity(exprs);
685 lin.Exprs.Add(GetLinearExpressionProto(expr,
true));
687 lin.Target = GetLinearExpressionProto(target,
true);
690 ct.Proto.LinMax = lin;
702 lin.
Exprs.TrySetCapacity(exprs);
705 lin.Exprs.Add(GetLinearExpressionProto(expr));
707 lin.Target = GetLinearExpressionProto(target);
710 ct.Proto.LinMax = lin;
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));
728 ct.Proto.IntDiv = div;
740 abs.Exprs.Capacity = 2;
741 abs.
Exprs.Add(GetLinearExpressionProto(expr));
742 abs.
Exprs.Add(GetLinearExpressionProto(expr,
true));
743 abs.Target = GetLinearExpressionProto(target);
746 ct.Proto.LinMax = abs;
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));
764 ct.Proto.IntMod = mod;
776 prod.Target = GetLinearExpressionProto(target);
777 prod.
Exprs.TrySetCapacity(exprs);
780 prod.Exprs.Add(GetLinearExpressionProto(expr));
784 ct.Proto.IntProd = prod;
796 prod.Target = GetLinearExpressionProto(target);
797 prod.Exprs.Capacity = 2;
798 prod.
Exprs.Add(GetLinearExpressionProto(left));
799 prod.
Exprs.Add(GetLinearExpressionProto(right));
802 ct.Proto.IntProd = prod;
832 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
859 return new IntervalVar(model_, startProto, sizeProto, endProto, name);
889 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.
GetIndex(), name);
919 return new IntervalVar(model_, startProto, sizeProto, endProto, is_present.
GetIndex(), name);
934 no_overlap.
Intervals.TrySetCapacity(intervals);
937 no_overlap.Intervals.Add(var.
GetIndex());
941 ct.Proto.NoOverlap = no_overlap;
990 LinearExpr capacityExpr = GetLinearExpr(capacity);
991 cumul.Capacity = GetLinearExpressionProto(capacityExpr);
994 ct.Proto.Cumulative = cumul;
1003 SetObjective(obj,
true);
1009 SetObjective(obj,
false);
1013 void ClearObjective()
1015 model_.Objective =
null;
1021 return model_.Objective is not
null || model_.FloatingPointObjective is not
null;
1033 foreach (
IntVar var
in vars)
1040 ds.VariableSelectionStrategy = var_str;
1041 ds.DomainReductionStrategy = dom_str;
1042 model_.SearchStrategy.Add(ds);
1049 model_.SolutionHint.Vars.Add(var.
GetIndex());
1050 model_.SolutionHint.Values.Add(value);
1060 model_.SolutionHint.Vars.Add(index);
1061 model_.SolutionHint.Values.Add(value ? 1 : 0);
1065 model_.SolutionHint.Vars.Add(Negated(index));
1066 model_.SolutionHint.Values.Add(value ? 0 : 1);
1073 model_.SolutionHint =
null;
1079 model_.Assumptions.Add(lit.
GetIndex());
1094 model_.Assumptions.Clear();
1099 void SetObjective(
LinearExpr obj,
bool minimize)
1104 objective.Offset = 0L;
1105 objective.ScalingFactor = minimize ? 1L : -1;
1107 else if (obj is IntVar intVar)
1109 objective.Offset = 0L;
1110 objective.Vars.Capacity = 1;
1111 objective.
Vars.Add(intVar.Index);
1113 objective.Coeffs.Capacity = 1;
1116 objective.
Coeffs.Add(1L);
1117 objective.ScalingFactor = 1L;
1121 objective.
Coeffs.Add(-1L);
1122 objective.ScalingFactor = -1L;
1127 var dict = var_value_map_;
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;
1136 objective.
Coeffs.AddRange(dict.Values);
1137 objective.ScalingFactor = 1L;
1138 objective.Offset = constant;
1142 foreach (var coeff
in dict.Values)
1144 objective.
Coeffs.Add(-coeff);
1146 objective.ScalingFactor = -1L;
1147 objective.Offset = -constant;
1150 model_.Objective = objective;
1184 private int ConvertConstant(
long value)
1186 if (constant_map_.TryGetValue(value, out var index))
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);
1201 private int ConvertConstantWithName(
long value,
string name)
1203 if (constant_map_.TryGetValue(value, out var index))
1209 IntegerVariableProto var =
new IntegerVariableProto();
1210 var.Domain.Capacity = 2;
1211 var.Domain.Add(value);
1212 var.Domain.Add(value);
1214 constant_map_.Add(value, index);
1219 internal LinearExpr GetLinearExpr<X>(X x)
1221 if (typeof(X) == typeof(IntVar))
1223 return (IntVar)(Object)x;
1225 if (typeof(X) == typeof(
long) || typeof(X) == typeof(
int) || typeof(X) == typeof(
short))
1227 return LinearExpr.Constant(Convert.ToInt64(x));
1229 if (typeof(X) == typeof(LinearExpr))
1231 return (LinearExpr)(Object)x;
1233 throw new ArgumentException(
"Cannot convert argument to LinearExpr");
1236 internal LinearExpressionProto GetLinearExpressionProto(LinearExpr expr,
bool negate =
false)
1238 var dict = var_value_map_;
1240 long constant = LinearExpr.GetVarValueMap(expr, dict, terms_);
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;
1249 foreach (var coeff
in dict.Values)
1251 linear.Coeffs.Add(-coeff);
1253 linear.Offset = -constant;
1257 linear.Coeffs.AddRange(dict.Values);
1258 linear.Offset = constant;
1264 internal LinearExpressionProto GetLinearExpressionProto(
long value)
1266 LinearExpressionProto linear =
new LinearExpressionProto();
1267 linear.Offset = value;
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_;
long[] FlattenedIntervals()