LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
SolverRunResult.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Xml.Serialization;
4using LotSizingDataModel.Solution;
8
10
11/// <summary>
12/// Represents the normalized result of a solver execution.
13/// </summary>
14/// <remarks>
15/// This class is independent of CPLEX, Gurobi, Xpress, and
16/// COIN-OR CBC. Each solver adapter converts its native status,
17/// statistics, and solution values into this common result.
18/// </remarks>
19[Serializable]
20[XmlType(TypeName = "solverRunResult")]
21public sealed class SolverRunResult
22{
23 private readonly List<string> _diagnostics =
24 new();
25
26 private readonly List<SolverProgressSnapshot>
27 _progressHistory =
28 new();
29
30 /// <summary>
31 /// Initializes an empty solver run result.
32 /// </summary>
34 {
35 RunId =
36 Guid.NewGuid().ToString("D");
37
38 RunName =
39 string.Empty;
40
42 string.Empty;
43
45 string.Empty;
46
48 string.Empty;
49
51 DateTime.UtcNow;
52
55 }
56
57 /// <summary>
58 /// Gets or sets the unique solver-run identifier.
59 /// </summary>
60 [XmlAttribute("runId")]
61 public string RunId
62 {
63 get;
64 set;
65 }
66
67 /// <summary>
68 /// Gets or sets the user-defined solver-run name.
69 /// </summary>
70 [XmlElement("runName")]
71 public string RunName
72 {
73 get;
74 set;
75 }
76
77 /// <summary>
78 /// Gets or sets the solver kind used for the run.
79 /// </summary>
80 [XmlAttribute("solverKind")]
82 {
83 get;
84 set;
85 }
86
87 /// <summary>
88 /// Gets or sets the solver display name.
89 /// </summary>
90 [XmlElement("solverName")]
91 public string SolverName
92 {
93 get;
94 set;
95 }
96
97 /// <summary>
98 /// Gets or sets the solver version.
99 /// </summary>
100 [XmlElement("solverVersion")]
101 public string SolverVersion
102 {
103 get;
104 set;
105 }
106
107 /// <summary>
108 /// Gets or sets the mathematical formulation name.
109 /// </summary>
110 [XmlElement("formulationName")]
111 public string FormulationName
112 {
113 get;
114 set;
115 }
116
117 /// <summary>
118 /// Gets or sets the UTC date and time at which the run
119 /// started.
120 /// </summary>
121 [XmlElement("startedAtUtc")]
122 public DateTime StartedAtUtc
123 {
124 get;
125 set;
126 }
127
128 /// <summary>
129 /// Gets or sets the UTC date and time at which the run
130 /// completed.
131 /// </summary>
132 [XmlElement("completedAtUtc")]
133 public DateTime? CompletedAtUtc
134 {
135 get;
136 set;
137 }
138
139 /// <summary>
140 /// Gets or sets the elapsed wall-clock time in seconds.
141 /// </summary>
142 [XmlElement("elapsedSeconds")]
143 public double ElapsedSeconds
144 {
145 get;
146 set;
147 }
148
149 /// <summary>
150 /// Gets or sets the elapsed processor time in seconds,
151 /// when available.
152 /// </summary>
153 [XmlElement("processorSeconds")]
154 public double? ProcessorSeconds
155 {
156 get;
157 set;
158 }
159
160 /// <summary>
161 /// Gets or sets the normalized termination reason.
162 /// </summary>
163 [XmlAttribute("terminationReason")]
165 {
166 get;
167 set;
168 }
169
170 /// <summary>
171 /// Gets or sets the final incumbent objective value.
172 /// </summary>
173 [XmlElement("objectiveValue")]
174 public double? ObjectiveValue
175 {
176 get;
177 set;
178 }
179
180 /// <summary>
181 /// Gets or sets the objective value independently recomputed
182 /// from the normalized decision-variable values.
183 /// </summary>
184 [XmlElement("recomputedObjectiveValue")]
186 {
187 get;
188 set;
189 }
190
191 /// <summary>
192 /// Gets or sets the absolute difference between the
193 /// solver-reported and recomputed objective values.
194 /// </summary>
195 [XmlElement("objectiveDifference")]
196 public double? ObjectiveDifference
197 {
198 get;
199 set;
200 }
201
202 /// <summary>
203 /// Gets or sets the result of objective-value verification.
204 /// </summary>
205 [XmlAttribute("objectiveVerificationStatus")]
207 {
208 get;
209 set;
210 }
211
212 /// <summary>
213 /// Gets or sets the final best objective bound.
214 /// </summary>
215 [XmlElement("bestBound")]
216 public double? BestBound
217 {
218 get;
219 set;
220 }
221
222 /// <summary>
223 /// Gets or sets the final absolute optimality gap.
224 /// </summary>
225 [XmlElement("absoluteGap")]
226 public double? AbsoluteGap
227 {
228 get;
229 set;
230 }
231
232 /// <summary>
233 /// Gets or sets the final relative optimality gap.
234 /// </summary>
235 [XmlElement("relativeGap")]
236 public double? RelativeGap
237 {
238 get;
239 set;
240 }
241
242 /// <summary>
243 /// Gets or sets the number of explored search-tree nodes.
244 /// </summary>
245 [XmlElement("exploredNodeCount")]
246 public long? ExploredNodeCount
247 {
248 get;
249 set;
250 }
251
252 /// <summary>
253 /// Gets or sets the number of solver iterations.
254 /// </summary>
255 [XmlElement("iterationCount")]
256 public long? IterationCount
257 {
258 get;
259 set;
260 }
261
262 /// <summary>
263 /// Gets or sets the number of feasible solutions found.
264 /// </summary>
265 [XmlElement("solutionCount")]
266 public int SolutionCount
267 {
268 get;
269 set;
270 }
271
272 /// <summary>
273 /// Gets or sets the normalized lot-sizing solution created
274 /// from the native solver result.
275 /// </summary>
276 [XmlElement("solution")]
277 public LotSizingSolution? Solution
278 {
279 get;
280 set;
281 }
282
283 /// <summary>
284 /// Gets the retained convergence history.
285 /// </summary>
286 [XmlArray("progressHistory")]
287 [XmlArrayItem("point")]
288 public List<SolverProgressSnapshot> ProgressHistory =>
289 _progressHistory;
290
291 /// <summary>
292 /// Gets the diagnostics produced during model generation,
293 /// solver execution, and solution extraction.
294 /// </summary>
295 [XmlArray("diagnostics")]
296 [XmlArrayItem("diagnostic")]
297 public List<string> Diagnostics =>
298 _diagnostics;
299
300 /// <summary>
301 /// Gets a value indicating whether a normalized solution is
302 /// available.
303 /// </summary>
304 [XmlIgnore]
305 public bool HasSolution =>
306 Solution is not null;
307
308 /// <summary>
309 /// Gets a value indicating whether the solver run completed
310 /// without an execution failure.
311 /// </summary>
312 [XmlIgnore]
313 public bool IsSuccessful =>
322 SolverTerminationReason.AbsoluteGapLimit;
323
324 /// <summary>
325 /// Adds a diagnostic message.
326 /// </summary>
327 /// <param name="message">
328 /// Diagnostic message.
329 /// </param>
330 public void AddDiagnostic(
331 string message)
332 {
333 if (string.IsNullOrWhiteSpace(
334 message))
335 {
336 throw new ArgumentException(
337 "A diagnostic message cannot be empty.",
338 nameof(message));
339 }
340
341 _diagnostics.Add(
342 message.Trim());
343 }
344
345 /// <summary>
346 /// Copies retained progress snapshots into the result.
347 /// </summary>
348 /// <param name="snapshots">
349 /// Progress snapshots to copy.
350 /// </param>
352 IEnumerable<SolverProgressSnapshot> snapshots)
353 {
354 ArgumentNullException.ThrowIfNull(
355 snapshots);
356
357 _progressHistory.Clear();
358
359 foreach (
361 in snapshots)
362 {
363 ArgumentNullException.ThrowIfNull(
364 snapshot);
365
366 _progressHistory.Add(
367 snapshot);
368 }
369 }
370}
List< SolverProgressSnapshot > ProgressHistory
Gets the retained convergence history.
int SolutionCount
Gets or sets the number of feasible solutions found.
SolverRunResult()
Initializes an empty solver run result.
LotSizingSolution? Solution
Gets or sets the normalized lot-sizing solution created from the native solver result.
string SolverVersion
Gets or sets the solver version.
double? ProcessorSeconds
Gets or sets the elapsed processor time in seconds, when available.
DateTime StartedAtUtc
Gets or sets the UTC date and time at which the run started.
double? AbsoluteGap
Gets or sets the final absolute optimality gap.
double? RelativeGap
Gets or sets the final relative optimality gap.
void SetProgressHistory(IEnumerable< SolverProgressSnapshot > snapshots)
Copies retained progress snapshots into the result.
double? ObjectiveValue
Gets or sets the final incumbent objective value.
bool IsSuccessful
Gets a value indicating whether the solver run completed without an execution failure.
void AddDiagnostic(string message)
Adds a diagnostic message.
List< string > Diagnostics
Gets the diagnostics produced during model generation, solver execution, and solution extraction.
string RunId
Gets or sets the unique solver-run identifier.
SolverTerminationReason TerminationReason
Gets or sets the normalized termination reason.
string SolverName
Gets or sets the solver display name.
double? BestBound
Gets or sets the final best objective bound.
string FormulationName
Gets or sets the mathematical formulation name.
bool HasSolution
Gets a value indicating whether a normalized solution is available.
double? RecomputedObjectiveValue
Gets or sets the objective value independently recomputed from the normalized decision-variable value...
double? ObjectiveDifference
Gets or sets the absolute difference between the solver-reported and recomputed objective values.
double ElapsedSeconds
Gets or sets the elapsed wall-clock time in seconds.
DateTime? CompletedAtUtc
Gets or sets the UTC date and time at which the run completed.
SolverKind SolverKind
Gets or sets the solver kind used for the run.
long? IterationCount
Gets or sets the number of solver iterations.
long? ExploredNodeCount
Gets or sets the number of explored search-tree nodes.
string RunName
Gets or sets the user-defined solver-run name.
ObjectiveVerificationStatus ObjectiveVerificationStatus
Gets or sets the result of objective-value verification.
Represents an immutable snapshot of the current progress of a mathematical optimization run.
SolverTerminationReason
Describes why a solver execution terminated.
@ RelativeGapLimit
The configured relative optimality-gap limit was reached.
@ Feasible
A feasible solution was found, but optimality was not proven.
@ SolutionLimit
The configured solution limit was reached.
@ IterationLimit
The configured iteration limit was reached.