6using LotSizingDataModel.Solution;
7using LotSizingDataModel.Solver.Modeling;
58 throw new ArgumentNullException(
64 MathematicalModel model,
65 LotSizingSolution solution,
68 ArgumentNullException.ThrowIfNull(model);
69 ArgumentNullException.ThrowIfNull(solution);
70 ArgumentNullException.ThrowIfNull(options);
82 AreVariableDomainsValid =
86 IsObjectiveConsistent =
106 double recomputedObjective =
111 result.RecomputedObjectiveValue =
114 double? reportedObjective =
115 options.ReportedObjectiveValueOverride ??
116 solution.Evaluation?.ObjectiveValue;
118 result.ReportedObjectiveValue =
121 if (!reportedObjective.HasValue)
123 result.IsObjectiveConsistent =
129 if (!
double.IsFinite(
130 reportedObjective.Value))
140 "The objective value reported by the " +
141 "candidate solution is not finite."
147 CompareObjectiveValues(
148 reportedObjective.Value,
155 catch (Exception exception)
157 result.IsObjectiveConsistent =
168 "Objective-value checking failed: " +
176 private static void AddProjectionIssues(
194 $
"Variable projection failed" +
195 $
"{FormatVariable(issue)}: " +
201 private static double EvaluateObjective(
202 MathematicalModel model,
205 double objectiveValue =
206 model.Objective.Expression.Constant;
210 in model.Objective.Expression.Terms)
214 out
double variableValue))
216 throw new InvalidOperationException(
217 $
"No projected value exists for mathematical " +
218 $
"variable '{term.VariableId}' while evaluating " +
227 if (!
double.IsFinite(
230 throw new InvalidOperationException(
231 "The recomputed objective value is not finite.");
234 return objectiveValue;
237 private static void CompareObjectiveValues(
238 double reportedObjective,
239 double recomputedObjective,
240 SolutionCheckOptions options,
241 SolutionCheckResult result)
243 double absoluteDifference =
246 recomputedObjective);
255 recomputedObjective)));
257 double relativeDifference =
261 double comparisonTolerance =
267 result.ObjectiveDifference =
270 result.ObjectiveRelativeDifference =
273 result.ObjectiveComparisonTolerance =
276 result.IsObjectiveConsistent =
277 absoluteDifference <=
286 new SolutionCheckIssue
299 "Objective values are inconsistent. " +
300 $
"Reported={reportedObjective:G17}; " +
301 $
"recomputed={recomputedObjective:G17}; " +
302 $
"absolute difference={absoluteDifference:G17}; " +
303 $
"relative difference={relativeDifference:G17}; " +
304 $
"comparison tolerance={comparisonTolerance:G17}."
308 private static string FormatVariable(
309 MathematicalSolutionProjectionIssue issue)
312 !
string.IsNullOrWhiteSpace(
316 $
" for variable '{issue.VariableName}' " +
317 $
"(id={issue.VariableId.Value})";
323 $
" for variable id={issue.VariableId.Value}";
Configures generic lot-sizing solution checking.
double ObjectiveRelativeTolerance
Gets or sets the relative tolerance used when comparing objective values.
double ObjectiveAbsoluteTolerance
Gets or sets the absolute tolerance used when comparing objective values.
void EnsureValid()
Validates the checker options.
MathematicalObjectiveChecker(IMathematicalSolutionValueProjector projector)
Initializes the checker with an explicit projector.
SolutionCheckResult Check(MathematicalModel model, LotSizingSolution solution, SolutionCheckOptions options)
Projects the candidate solution onto the mathematical model, independently evaluates the model object...
MathematicalObjectiveChecker()
Initializes the checker with the default mathematical solution projector.
Describes one issue encountered while projecting a business solution onto mathematical-model variable...
int? VariableId
Gets or sets the mathematical variable identifier.
string? DomainKey
Gets or sets the mathematical domain key.
string? VariableName
Gets or sets the mathematical variable name.
Contains mathematical-variable values projected from one normalized lot-sizing solution.
bool IsSuccessful
Gets whether every mathematical variable was projected successfully.
IReadOnlyList< MathematicalSolutionProjectionIssue > Issues
Gets all projection diagnostics.
bool TryGetValue(int variableId, out double value)
Attempts to get the projected value of one mathematical variable.
Projects a normalized LotSizingSolution onto the variables of a MathematicalModel by using the canoni...
Describes one issue detected by a lot-sizing solution checker.
Contains the complete result of checking one lot-sizing solution.
bool IsObjectiveConsistent
Gets or sets whether objective-value verification succeeded.
void AddIssue(SolutionCheckIssue issue)
Adds one issue to the result.
Defines independent objective-value validation of a candidate lot-sizing solution against a mathemati...
Defines projection of a normalized lot-sizing solution onto the variables of a solver-independent mat...
SolutionCheckLevel
Defines how deeply a lot-sizing solution must be checked.
SolutionCheckSeverity
Defines the severity of a solution-check issue.
SolutionCheckIssueKind
Identifies the category of an issue detected while checking a solution.