LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
MathematicalSolverRunResultMapper.cs
Go to the documentation of this file.
1using System;
3
5
6/// <summary>
7/// Creates the public solver-run result from the generic
8/// mathematical-model result and the normalized solution
9/// mapping result.
10/// </summary>
12{
13 /// <summary>
14 /// Creates a normalized solver-run result.
15 /// </summary>
16 /// <param name="solveResult">
17 /// Generic mathematical-model solve result returned by the
18 /// selected solver adapter.
19 /// </param>
20 /// <param name="mappingResult">
21 /// Result of mapping mathematical variable values back to a
22 /// lot-sizing solution.
23 /// </param>
24 /// <param name="startedAtUtc">
25 /// UTC date and time at which the complete solve workflow
26 /// started.
27 /// </param>
28 /// <param name="elapsed">
29 /// Total elapsed duration of the complete solve workflow.
30 /// </param>
31 /// <returns>
32 /// Public normalized solver-run result.
33 /// </returns>
34 /// <exception cref="ArgumentNullException">
35 /// Thrown when <paramref name="solveResult"/> or
36 /// <paramref name="mappingResult"/> is
37 /// <see langword="null"/>.
38 /// </exception>
39 /// <exception cref="ArgumentOutOfRangeException">
40 /// Thrown when <paramref name="elapsed"/> is negative.
41 /// </exception>
42 public static SolverRunResult Create(
45 DateTime startedAtUtc,
46 TimeSpan elapsed)
47 {
48 ArgumentNullException.ThrowIfNull(
49 solveResult);
50
51 ArgumentNullException.ThrowIfNull(
52 mappingResult);
53
54 if (elapsed < TimeSpan.Zero)
55 {
56 throw new ArgumentOutOfRangeException(
57 nameof(elapsed),
58 elapsed,
59 "The total solve duration cannot be negative.");
60 }
61
62 DateTime normalizedStartedAtUtc =
63 NormalizeUtc(
64 startedAtUtc);
65
66 var result =
68 {
69 RunName =
70 solveResult.RunName ?? string.Empty,
71
72 SolverKind =
73 solveResult.SolverKind,
74
75 SolverName =
76 solveResult.SolverName ?? string.Empty,
77
78 SolverVersion =
79 solveResult.SolverVersion ?? string.Empty,
80
81 FormulationName =
82 solveResult.FormulationId ?? string.Empty,
83
84 StartedAtUtc =
85 normalizedStartedAtUtc,
86
87 CompletedAtUtc =
88 normalizedStartedAtUtc + elapsed,
89
90 ElapsedSeconds =
91 elapsed.TotalSeconds,
92
93 TerminationReason =
94 solveResult.TerminationReason,
95
96 ObjectiveValue =
97 solveResult.ObjectiveValue,
98
99 BestBound =
100 solveResult.BestBound,
101
102 AbsoluteGap =
103 solveResult.AbsoluteGap,
104
105 RelativeGap =
106 solveResult.RelativeGap,
107
108 ExploredNodeCount =
109 solveResult.ExploredNodeCount,
110
111 IterationCount =
112 solveResult.IterationCount,
113
114 SolutionCount =
115 solveResult.HasFeasibleSolution
116 ? 1
117 : 0,
118
119 Solution =
120 mappingResult.IsSuccessful
121 ? mappingResult.Solution
122 : null
123 };
124
125 result.AddDiagnostics(
126 solveResult);
127
128 result.AddDiagnostics(
129 mappingResult);
130
131 return result;
132 }
133
134 private static DateTime NormalizeUtc(
135 DateTime value)
136 {
137 return value.Kind switch
138 {
139 DateTimeKind.Utc =>
140 value,
141
142 DateTimeKind.Local =>
143 value.ToUniversalTime(),
144
145 _ =>
146 DateTime.SpecifyKind(
147 value,
148 DateTimeKind.Utc)
149 };
150 }
151
152 private static void AddDiagnostics(
153 this SolverRunResult target,
154 MathematicalModelSolveResult source)
155 {
156 foreach (
157 string diagnostic
158 in source.Diagnostics)
159 {
160 if (!string.IsNullOrWhiteSpace(
161 diagnostic))
162 {
163 target.AddDiagnostic(
164 diagnostic);
165 }
166 }
167 }
168
169 private static void AddDiagnostics(
170 this SolverRunResult target,
171 MathematicalSolutionMappingResult source)
172 {
173 foreach (
174 string diagnostic
175 in source.Diagnostics)
176 {
177 if (!string.IsNullOrWhiteSpace(
178 diagnostic))
179 {
180 target.AddDiagnostic(
181 diagnostic);
182 }
183 }
184
185 if (!source.IsSuccessful &&
186 !string.IsNullOrWhiteSpace(
187 source.FailureMessage))
188 {
189 bool alreadyPresent =
190 source.Diagnostics.Exists(
191 diagnostic =>
192 string.Equals(
193 diagnostic,
194 source.FailureMessage,
195 StringComparison.Ordinal));
196
197 if (!alreadyPresent)
198 {
199 target.AddDiagnostic(
200 source.FailureMessage);
201 }
202 }
203 }
204}
Stores the solver result for a solver-independent mathematical model.
SolverTerminationReason TerminationReason
Gets or sets the termination reason.
long? IterationCount
Gets or sets the number of simplex or barrier iterations, when available.
long? ExploredNodeCount
Gets or sets the number of explored branch-and-bound nodes, when available.
Creates the public solver-run result from the generic mathematical-model result and the normalized so...
static SolverRunResult Create(MathematicalModelSolveResult solveResult, MathematicalSolutionMappingResult mappingResult, DateTime startedAtUtc, TimeSpan elapsed)
Creates a normalized solver-run result.
Represents the normalized result of a solver execution.
Describes the result of mapping a mathematical solver result back to a normalized lot-sizing solution...
bool IsSuccessful
Gets or sets a value indicating whether mapping succeeded.