LotSizingDataModel.Checker 2.0.1
Reusable validation engine for structural, mathematical and objective consistency checks.
Loading...
Searching...
No Matches
SolutionCheckBatchAggregator.cs
Go to the documentation of this file.
3
5
6/// <summary>
7/// Aggregates independent checker results for batch-validation campaigns.
8/// </summary>
9public sealed class SolutionCheckBatchAggregator
10{
11 private readonly List<SolutionCheckBatchItemSummary> _items = new();
12
13 /// <summary>
14 /// Adds one checked candidate to the batch.
15 /// </summary>
16 /// <param name="candidateKey">Stable caller-defined candidate identifier.</param>
17 /// <param name="result">Checker result for the candidate.</param>
18 /// <param name="candidateName">Optional display name.</param>
19 public void Add(
20 string candidateKey,
22 string? candidateName = null)
23 {
24 if (string.IsNullOrWhiteSpace(candidateKey))
25 {
26 throw new ArgumentException(
27 "The candidate key cannot be empty.",
28 nameof(candidateKey));
29 }
30
31 ArgumentNullException.ThrowIfNull(result);
32
33 _items.Add(
35 {
36 CandidateKey =
37 candidateKey,
38 CandidateName =
39 candidateName,
40 Summary =
42 });
43 }
44
45 /// <summary>
46 /// Removes all accumulated candidate summaries.
47 /// </summary>
48 public void Clear()
49 {
50 _items.Clear();
51 }
52
53 /// <summary>
54 /// Builds a detached aggregate summary from all accumulated candidates.
55 /// </summary>
56 /// <returns>A new batch summary.</returns>
58 {
59 var summary =
61 {
62 CandidateCount =
63 _items.Count,
64 ValidCandidateCount =
65 _items.Count(
66 item =>
67 item.Summary.IsValid),
68 InvalidCandidateCount =
69 _items.Count(
70 item =>
71 !item.Summary.IsValid),
72 InformationCount =
73 _items.Sum(
74 item =>
75 item.Summary.InformationCount),
76 WarningCount =
77 _items.Sum(
78 item =>
79 item.Summary.WarningCount),
80 ErrorCount =
81 _items.Sum(
82 item =>
83 item.Summary.ErrorCount),
84 CandidateWithConstraintViolationCount =
85 _items.Count(
86 item =>
87 item.Summary.ViolatedConstraintCount > 0),
88 CandidateWithObjectiveMismatchCount =
89 _items.Count(
90 item =>
91 item.Summary.IssueCountsByKind.Any(
92 issueCount =>
93 issueCount.Kind ==
94 SolutionCheckIssueKind.ObjectiveMismatch &&
95 issueCount.Count > 0)),
96 MaximumConstraintViolation =
97 _items.Count == 0
98 ? 0.0
99 : _items.Max(
100 item =>
101 item.Summary.MaximumConstraintViolation)
102 };
103
104 foreach (SolutionCheckIssueKind kind in
105 Enum.GetValues<SolutionCheckIssueKind>())
106 {
107 int count =
108 _items.Sum(
109 item =>
110 item.Summary.IssueCountsByKind
111 .Where(issueCount =>
112 issueCount.Kind == kind)
113 .Sum(issueCount =>
114 issueCount.Count));
115
116 if (count == 0)
117 {
118 continue;
119 }
120
121 summary.IssueCountsByKind.Add(
123 {
124 Kind =
125 kind,
126 Count =
127 count
128 });
129 }
130
131 foreach (SolutionCheckBatchItemSummary item in _items)
132 {
133 summary.Items.Add(
134 CloneItem(item));
135 }
136
137 return summary;
138 }
139
140 private static SolutionCheckBatchItemSummary CloneItem(
142 {
144 {
145 CandidateKey =
146 source.CandidateKey,
147 CandidateName =
148 source.CandidateName,
149 Summary =
150 CloneSummary(source.Summary)
151 };
152 }
153
154 private static SolutionCheckSummary CloneSummary(
155 SolutionCheckSummary source)
156 {
157 var clone =
158 new SolutionCheckSummary
159 {
160 Level =
161 source.Level,
162 IsValid =
163 source.IsValid,
164 StructuralStatus =
165 source.StructuralStatus,
166 VariableDomainStatus =
167 source.VariableDomainStatus,
168 FeasibilityStatus =
169 source.FeasibilityStatus,
170 ObjectiveStatus =
171 source.ObjectiveStatus,
172 IssueCount =
173 source.IssueCount,
174 InformationCount =
175 source.InformationCount,
176 WarningCount =
177 source.WarningCount,
178 ErrorCount =
179 source.ErrorCount,
180 ViolatedConstraintCount =
181 source.ViolatedConstraintCount,
182 MaximumConstraintViolation =
183 source.MaximumConstraintViolation,
184 TotalConstraintViolation =
185 source.TotalConstraintViolation,
186 ReportedObjectiveValue =
187 source.ReportedObjectiveValue,
188 RecomputedObjectiveValue =
189 source.RecomputedObjectiveValue,
190 ObjectiveDifference =
191 source.ObjectiveDifference,
192 ObjectiveRelativeDifference =
193 source.ObjectiveRelativeDifference,
194 ObjectiveComparisonTolerance =
195 source.ObjectiveComparisonTolerance
196 };
197
198 foreach (SolutionCheckIssueCount issueCount in
199 source.IssueCountsByKind)
200 {
201 clone.IssueCountsByKind.Add(
202 new SolutionCheckIssueCount
203 {
204 Kind =
205 issueCount.Kind,
206 Count =
207 issueCount.Count
208 });
209 }
210
211 return clone;
212 }
213}
Aggregates independent checker results for batch-validation campaigns.
void Add(string candidateKey, SolutionCheckResult result, string? candidateName=null)
Adds one checked candidate to the batch.
SolutionCheckBatchSummary BuildSummary()
Builds a detached aggregate summary from all accumulated candidates.
Associates a batch candidate identifier with its compact checker summary.
string CandidateKey
Gets or sets the caller-defined candidate identifier.
SolutionCheckSummary Summary
Gets or sets the compact checker summary for this candidate.
string? CandidateName
Gets or sets an optional human-readable candidate name.
Contains aggregated metrics for a collection of checked solutions.
Associates an issue category with its occurrence count.
Builds compact summaries from complete checker results.
static SolutionCheckSummary Create(SolutionCheckResult result)
Creates a compact machine-oriented summary.
Contains the complete result of checking one lot-sizing solution.
SolutionCheckIssueKind
Identifies the category of an issue detected while checking a solution.