18using System.Collections;
19using System.Collections.Generic;
21using System.Runtime.CompilerServices;
22using Google.Protobuf.Collections;
24internal static class HelperExtensions
43 [MethodImpl(MethodImplOptions.AggressiveInlining)]
44 internal static void TrySetCapacity<TField, TValues>(
this RepeatedField<TField> field, IEnumerable<TValues> values)
46 if (values is ICollection<TValues> collection)
48 field.Capacity = collection.Count;
52 [MethodImpl(MethodImplOptions.AggressiveInlining)]
53 internal static void TryEnsureCapacity<TValue, TValues>(
this List<TValue> list, IEnumerable<TValues> values)
56 if (values is ICollection collection)
58 list.Capacity = Math.Max(list.Count + collection.Count, list.Capacity);
63 [MethodImpl(MethodImplOptions.AggressiveInlining)]
64 internal static bool TryDequeue<T>(
this Queue<T> queue, out T value)
68 value = queue.Dequeue();
119 return Prod(expr, coeff);
127 return Prod(expr, coeff);
255 internal static double GetVarValueMap(LinearExpr e, SortedDictionary<int, double> dict, Queue<Term> terms)
258 double coefficient = 1;
266 case LinearExprBuilder builder:
267 constant += coefficient * builder.Offset;
268 if (coefficient == 1)
270 foreach (
Term sub
in builder.Terms)
277 foreach (
Term sub
in builder.Terms)
279 terms.Enqueue(
new Term(sub.expr, sub.coefficient * coefficient));
284 if (dict.TryGetValue(var.Index, out var c))
286 dict[var.Index] = c + coefficient;
290 dict.Add(var.Index, coefficient);
294 throw new ArgumentException(
"Cannot evaluate '" + expr +
"' in an expression");
297 if (!terms.TryDequeue(out var term))
302 coefficient = term.coefficient;
314 terms_ =
new List<Term>(sizeHint);
334 terms_.Add(
new Term(expr, coefficient));
341 terms_.TryEnsureCapacity(exprs);
352 terms_.TryEnsureCapacity(exprs);
353 foreach (var p
in exprs.Zip(coefficients, (e, c) =>
new { Expr = e, Coeff = c }))
363 terms_.TryEnsureCapacity(exprs);
364 foreach (var p
in exprs.Zip(coefficients, (e, c) =>
new { Expr = e, Coeff = c }))
374 terms_.TryEnsureCapacity(exprs);
375 foreach (var p
in exprs.Zip(coefficients, (e, c) =>
new { Expr = e, Coeff = c }))
384 foreach (
Term term
in terms_)
386 bool first = String.IsNullOrEmpty(result);
398 result += term.
expr.ToString();
407 result += String.Format(
"{0} * {1}", term.
coefficient, term.
expr.ToString());
413 result += String.Format(
" - {0}", term.
expr.ToString());
417 result += String.Format(
"-{0}", term.
expr.ToString());
424 result += String.Format(
" - {0} * {1}", -term.
coefficient, term.
expr.ToString());
428 result += String.Format(
"{0} * {1}", term.
coefficient, term.
expr.ToString());
434 if (!String.IsNullOrEmpty(result))
436 result += String.Format(
" + {0}", offset_);
440 result += String.Format(
"{0}", offset_);
443 else if (offset_ < 0)
445 if (!String.IsNullOrEmpty(result))
447 result += String.Format(
" - {0}", -offset_);
451 result += String.Format(
"{0}", offset_);
471 private double offset_;
472 private List<Term> terms_;
492 if (!
string.IsNullOrEmpty(name))
544 return string.IsNullOrEmpty(name) ? String.Format(
"var_{0}",
index_) : name;
584 type_ =
Type.BoundExpression;
593 type_ = equality ? Type.VarEqVar :
Type.VarDiffVar;
602 type_ = equality ? Type.VarEqCst :
Type.VarDiffCst;
607 if (type_ ==
Type.VarEqVar)
609 return (
object)left_ == (object)right_;
611 else if (type_ ==
Type.VarDiffVar)
613 return (
object)left_ != (object)right_;
625 return !ble.IsTrue();
632 case Type.BoundExpression:
633 return String.Format(
"{0} <= {1} <= {2}", lb_, left_, ub_);
635 return String.Format(
"{0} == {1}", left_, right_);
636 case Type.VarDiffVar:
637 return String.Format(
"{0} != {1}", left_, right_);
639 return String.Format(
"{0} == {1}", left_, lb_);
640 case Type.VarDiffCst:
641 return String.Format(
"{0} != {1}", left_, lb_);
643 throw new ArgumentException(
"Wrong mode in BoundedLinearExpression.");
649 if (a.
CtType !=
Type.BoundExpression || a.
Ub != Double.PositiveInfinity)
651 throw new ArgumentException(
"Operator <= not supported for this BoundedLinearExpression");
658 if (a.
CtType !=
Type.BoundExpression || a.
Lb != Double.NegativeInfinity)
660 throw new ArgumentException(
"Operator >= not supported for this BoundedLinearExpression");