19 CancellationToken cancellationToken =
default)
21 ArgumentNullException.ThrowIfNull(
26 UlsSolverDescriptor descriptor =
31 UlsSolverFactory.Create(
35 UlsSolverKind.Heuristic)
37 throw new InvalidOperationException(
38 $
"ULSAlgorithms factory returned a non-heuristic solver for '{descriptor.Id}'.");
48 cancellationToken.ThrowIfCancellationRequested();
53 UlsSolveResult solveResult =
60 if (solveResult.Status !=
61 UlsSolveStatus.Feasible)
63 throw new InvalidOperationException(
64 $
"Pinned heuristic '{descriptor.Id}' returned status '{solveResult.Status}' instead of Feasible.");
67 if (!solveResult.HasSolution ||
68 solveResult.Solution is
null)
70 throw new InvalidOperationException(
71 $
"Pinned heuristic '{descriptor.Id}' returned no feasible solution.");
74 UlsSolution solution =
77 UlsSolutionValidationResult validation =
78 UlsSolutionValidator.Validate(
82 if (!validation.IsFeasible)
84 throw new InvalidOperationException(
85 $
"ULSAlgorithms validator rejected heuristic '{descriptor.Id}'.");
88 if (solution.Horizon !=
91 throw new InvalidOperationException(
92 $
"Heuristic '{descriptor.Id}' returned horizon {solution.Horizon}, expected {problemData.Horizon}.");
95 double objectiveValue =
96 solveResult.ObjectiveValue ??
99 double reportedDifference =
104 double validatedDifference =
107 validation.RecomputedTotalCost);
112 Math.Abs(objectiveValue));
114 if (reportedDifference >
116 validatedDifference >
119 throw new InvalidOperationException(
120 $
"Heuristic '{descriptor.Id}' returned an inconsistent objective value.");
123 string solverVersion =
124 ULSAlgorithmsInfo.InformationalVersion;
126 if (
string.IsNullOrWhiteSpace(
130 ULSAlgorithmsInfo.Version.ToString();
135 solveResult.SolverName,
140 solution.ProductionCost,
141 solution.HoldingCost,
142 solution.ProductionQuantities.ToArray(),
143 solution.EndingInventories.ToArray(),
144 solution.SetupDecisions.ToArray(),