ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
SolverExecutionUtilities.cs
Go to the documentation of this file.
2
4
5internal static class SolverExecutionUtilities
6{
7 internal static string CreateArtifactDirectory(
8 SolverKind solverKind,
10 {
11 string parent =
12 string.IsNullOrWhiteSpace(
13 options.TemporaryRootPath)
14 ? Path.GetTempPath()
15 : Path.GetFullPath(
16 options.TemporaryRootPath);
17
18 Directory.CreateDirectory(parent);
19
20 string directory =
21 Path.Combine(
22 parent,
23 "ULSAlgorithms",
24 solverKind.ToString(),
25 Guid.NewGuid().ToString("N"));
26
27 Directory.CreateDirectory(directory);
28 return directory;
29 }
30
31 internal static void ExportModelIfRequested(
32 string generatedModelPath,
34 {
35 if (string.IsNullOrWhiteSpace(
36 options.ExportModelPath))
37 {
38 return;
39 }
40
41 string destination =
42 Path.GetFullPath(
43 options.ExportModelPath);
44
45 string? directory =
46 Path.GetDirectoryName(destination);
47
48 if (!string.IsNullOrWhiteSpace(directory))
49 {
50 Directory.CreateDirectory(directory);
51 }
52
53 File.Copy(
54 generatedModelPath,
55 destination,
56 overwrite: true);
57 }
58
59 internal static IReadOnlyDictionary<int, double>
61 LinearModel model,
62 IReadOnlyDictionary<int, double> returnedValues)
63 {
64 var completed =
65 new Dictionary<int, double>(
66 model.VariableCount);
67
68 foreach (LinearVariable variable in model.Variables)
69 {
70 completed[variable.Id] =
71 returnedValues.TryGetValue(
72 variable.Id,
73 out double value)
74 ? value
75 : variable.LowerBound == variable.UpperBound
76 ? variable.LowerBound
77 : 0.0;
78 }
79
80 return completed;
81 }
82
84 LinearModel model,
85 SolverSelectionResult selection,
87 LinearModelSolveStatus proposedStatus,
88 IReadOnlyDictionary<int, double> returnedValues,
89 bool hasCandidateSolution,
90 TimeSpan duration,
91 string nativeStatus,
92 IEnumerable<string> diagnostics,
93 string artifactDirectory)
94 {
95 var messages =
96 diagnostics.ToList();
97
98 IReadOnlyDictionary<int, double> completed =
99 hasCandidateSolution
101 model,
102 returnedValues)
103 : new Dictionary<int, double>();
104
105 IReadOnlyDictionary<int, double> normalized =
106 hasCandidateSolution
108 model,
109 completed,
110 options)
111 : completed;
112
114 null;
115
116 LinearModelSolveStatus normalizedStatus =
117 proposedStatus;
118
119 if (hasCandidateSolution)
120 {
121 validation =
123 model,
124 normalized,
125 options.FeasibilityTolerance,
126 options.IntegralityTolerance);
127
128 foreach (string diagnostic in validation.Diagnostics)
129 {
130 messages.Add(
131 "Independent checker: " +
132 diagnostic);
133 }
134
135 if (!validation.IsFeasible &&
136 proposedStatus is
137 LinearModelSolveStatus.Optimal or
138 LinearModelSolveStatus.Feasible)
139 {
140 normalizedStatus =
142
143 messages.Add(
144 "The native solver returned a candidate solution, but " +
145 "the independent portable-model checker rejected it.");
146 }
147 }
148
149 string retainedDirectory =
150 options.KeepTemporaryFiles
151 ? artifactDirectory
152 : string.Empty;
153
154 return new LinearModelSolveResult(
155 model.Name,
156 normalizedStatus,
157 new SolverExecutionInfo(selection),
158 normalized,
159 validation,
160 duration,
161 nativeStatus,
162 messages,
163 retainedDirectory)
164 {
165 SolverReportedStatus =
166 proposedStatus
167 };
168 }
169
170
171 internal static IReadOnlyDictionary<int, double> NormalizeValues(
172 LinearModel model,
173 IReadOnlyDictionary<int, double> values,
175 {
176 var normalizer =
178 options.ZeroTolerance,
179 options.IntegralityTolerance,
180 options.NearIntegerTolerance);
181
182 var normalized =
183 new Dictionary<int, double>(
184 model.VariableCount);
185
186 foreach (LinearVariable variable in model.Variables)
187 {
188 if (!values.TryGetValue(
189 variable.Id,
190 out double rawValue))
191 {
192 throw new InvalidOperationException(
193 $"No returned value exists for variable '{variable.Name}'.");
194 }
195
196 normalized[variable.Id] =
197 normalizer.Normalize(
198 variable,
199 rawValue);
200 }
201
202 return normalized;
203 }
204
205 internal static void DeleteArtifactsUnlessRetained(
206 string directory,
208 {
209 if (options.KeepTemporaryFiles)
210 {
211 return;
212 }
213
214 try
215 {
216 if (Directory.Exists(directory))
217 {
218 Directory.Delete(
219 directory,
220 recursive: true);
221 }
222 }
223 catch
224 {
225 // Cleanup must never mask a solver result.
226 }
227 }
228
229 internal static string LastMeaningfulLine(
230 string text)
231 {
232 return text
233 .Split(
234 ['\r', '\n'],
235 StringSplitOptions.RemoveEmptyEntries |
236 StringSplitOptions.TrimEntries)
237 .LastOrDefault() ??
238 string.Empty;
239 }
240}
241
Independent solver-agnostic validation of a returned variable assignment.
Independently checks solver-returned values against the portable model.
static LinearModelSolutionValidation Validate(LinearModel model, IReadOnlyDictionary< int, double > values, double feasibilityTolerance, double integralityTolerance)
Validates bounds, integrality, constraints and objective reconstruction.
Configures one solver-backed execution of a portable linear model.
string TemporaryRootPath
Gets or sets an optional parent directory for temporary solver artifacts.
double NearIntegerTolerance
Gets or sets the tolerance used to clean continuous values that are numerically indistinguishable fro...
double ZeroTolerance
Gets or sets the tolerance used to identify numerical zero before validation and objective reconstruc...
double IntegralityTolerance
Gets or sets the integrality tolerance used both for normalization and the independent solution check...
bool KeepTemporaryFiles
Gets or sets whether temporary model/solution/log artifacts are retained.
string ExportModelPath
Gets or sets an optional path receiving the exact LP model submitted to the selected solver.
double FeasibilityTolerance
Gets or sets the feasibility tolerance used by the independent solution checker.
Result of executing a solver-independent linear or mixed-integer model.
Normalizes raw mathematical-variable values returned by optimization solvers before independent valid...
static LinearModelSolveResult BuildSolutionResult(LinearModel model, SolverSelectionResult selection, LinearModelSolveOptions options, LinearModelSolveStatus proposedStatus, IReadOnlyDictionary< int, double > returnedValues, bool hasCandidateSolution, TimeSpan duration, string nativeStatus, IEnumerable< string > diagnostics, string artifactDirectory)
static string CreateArtifactDirectory(SolverKind solverKind, LinearModelSolveOptions options)
static IReadOnlyDictionary< int, double > NormalizeValues(LinearModel model, IReadOnlyDictionary< int, double > values, LinearModelSolveOptions options)
static void DeleteArtifactsUnlessRetained(string directory, LinearModelSolveOptions options)
static void ExportModelIfRequested(string generatedModelPath, LinearModelSolveOptions options)
static IReadOnlyDictionary< int, double > CompleteValues(LinearModel model, IReadOnlyDictionary< int, double > returnedValues)
Immutable solver-independent linear or mixed-integer linear model.
Definition LinearModel.cs:7
int VariableCount
Gets the number of variables.
Describes one variable in a portable linear mathematical model.
int Id
Gets the stable zero-based variable identifier.
Serializable-style immutable snapshot of the solver selected for one solver-backed ULS execution.
Describes the outcome of optimization-solver selection.
LinearModelSolveStatus
Describes the termination state of a solver-backed portable linear model.
SolverKind
Identifies a mathematical optimization solver that can be used by solver-backed ULS algorithms.
Definition SolverKind.cs:15