55 CancellationToken cancellationToken =
default)
57 ArgumentNullException.ThrowIfNull(problem);
58 cancellationToken.ThrowIfCancellationRequested();
62 var triangularLength =
69 ArrayPool<double>.Shared.Rent(
73 ArrayPool<double>.Shared.Rent(
76 var predecessorBuffer =
77 ArrayPool<int>.Shared.Rent(
80 var demandPrefixBuffer =
81 ArrayPool<double>.Shared.Rent(
97 predecessorBuffer.AsSpan(
102 demandPrefixBuffer.AsSpan(
107 double.PositiveInfinity);
109 predecessor.Fill(-1);
110 demandPrefix.Clear();
121 demandPrefix[period + 1] =
122 demandPrefix[period] +
125 if (!
double.IsFinite(
126 demandPrefix[period + 1]))
128 throw new ArithmeticException(
129 "Numerical overflow in cumulative demand.");
133 MaterializeTriangularCosts(
138 for (var endExclusive = 1;
139 endExclusive <= horizon;
142 cancellationToken.ThrowIfCancellationRequested();
148 double.PositiveInfinity;
152 if (demands[end] == 0.0)
155 value[endExclusive - 1];
166 demandPrefix[end + 1] -
169 if (intervalDemand == 0.0)
182 if (!
double.IsFinite(candidate))
184 throw new ArithmeticException(
185 "Numerical overflow in Saydam-McKnew DP.");
188 if (candidate < best ||
189 (candidate == best &&
197 if (!
double.IsFinite(best) ||
200 throw new ArithmeticException(
201 $
"No finite Saydam-McKnew value for prefix {endExclusive}.");
204 value[endExclusive] = best;
205 predecessor[endExclusive] =
217 ArrayPool<double>.Shared.Return(
221 ArrayPool<double>.Shared.Return(
225 ArrayPool<int>.Shared.Return(
229 ArrayPool<double>.Shared.Return(