1using System.Diagnostics;
25 public async ValueTask<LinearModelSolveResult>
SolveAsync(
29 CancellationToken cancellationToken =
default)
31 ArgumentNullException.ThrowIfNull(model);
32 ArgumentNullException.ThrowIfNull(selection);
33 ArgumentNullException.ThrowIfNull(options);
38 throw new ArgumentException(
39 "The supplied selection does not target CPLEX.",
44 ResolveCplexExecutable(
47 if (
string.IsNullOrWhiteSpace(executable))
56 "cplex executable unavailable",
58 "CPLEX runtime discovery succeeded, but the stand-alone " +
59 "cplex executable was not found in the selected runtime " +
96 $
"read {Quote(modelPath)}",
98 $
"write {Quote(solutionPath)}",
104 await _runner.RunAsync(
114 process.CombinedOutput;
120 bool solutionExists =
121 File.Exists(solutionPath);
138 !
string.IsNullOrWhiteSpace(solution.Status)
142 $
"cplex exit code: {process.ExitCode}.",
143 !
string.IsNullOrWhiteSpace(solution.Status)
144 ? $
"CPLEX solution status: {solution.Status}."
149 catch (OperationCanceledException)
161 [
"CPLEX execution was cancelled by the caller."],
166 catch (Exception exception)
177 exception.GetType().Name,
191 private static string ResolveCplexExecutable(
197 if (
string.IsNullOrWhiteSpace(directory))
200 Path.GetDirectoryName(
205 if (
string.IsNullOrWhiteSpace(directory))
210 string[] candidates =
211 OperatingSystem.IsWindows()
212 ? [
"cplex.exe",
"cplex"]
213 : [
"cplex",
"cplex.bin"];
215 foreach (
string name
in candidates)
222 if (File.Exists(path))
224 return Path.GetFullPath(path);
231 private static string Quote(
237 StringComparison.Ordinal) +
251 if (!
string.IsNullOrWhiteSpace(nativeStatus))
257 "infeasible or unbounded",
258 StringComparison.OrdinalIgnoreCase))
267 "optimal, tolerance",
268 StringComparison.OrdinalIgnoreCase) ||
270 "optimal within tolerance",
271 StringComparison.OrdinalIgnoreCase))
278 StringComparison.OrdinalIgnoreCase))
285 StringComparison.OrdinalIgnoreCase))
292 StringComparison.OrdinalIgnoreCase))
300 "infeasible or unbounded",
301 StringComparison.OrdinalIgnoreCase))
307 "optimal, tolerance",
308 StringComparison.OrdinalIgnoreCase) ||
310 "optimal within tolerance",
311 StringComparison.OrdinalIgnoreCase))
313 return solutionExists
314 ? LinearModelSolveStatus.Feasible
320 StringComparison.OrdinalIgnoreCase))
327 StringComparison.OrdinalIgnoreCase))
334 StringComparison.OrdinalIgnoreCase))
345 ? LinearModelSolveStatus.Unknown
Parses CPLEX XML .sol files written by the stand-alone CPLEX optimizer.
static CplexXmlSolution Parse(string path)
Runs a solver command-line process with cancellation and captured output.
Configures one solver-backed execution of a portable linear model.
bool KeepTemporaryFiles
Gets or sets whether temporary model/solution/log artifacts are retained.
Result of executing a solver-independent linear or mixed-integer model.
Writes a conservative LP representation understood by all four supported execution backends.
void Write(LinearModel model, string path)
Writes the supplied model to an LP file.
Executes portable LP/MILP models through the stand-alone CPLEX optimizer.
async ValueTask< LinearModelSolveResult > SolveAsync(LinearModel model, SolverSelectionResult selection, LinearModelSolveOptions options, CancellationToken cancellationToken=default)
Executes one portable model using an already selected solver.
SolverKind SolverKind
Gets the concrete solver implemented by this executor.
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 string LastMeaningfulLine(string text)
static void DeleteArtifactsUnlessRetained(string directory, LinearModelSolveOptions options)
static void ExportModelIfRequested(string generatedModelPath, LinearModelSolveOptions options)
Immutable solver-independent linear or mixed-integer linear model.
string Name
Gets the model name.
Describes solver availability and the installation selected by an adapter.
string NativeLibraryPath
Gets the native library or executable path, when applicable.
string ManagedAssemblyPath
Gets the managed assembly path, when applicable.
Serializable-style immutable snapshot of the solver selected for one solver-backed ULS execution.
Describes the outcome of optimization-solver selection.
SolverKind SelectedSolver
Gets the selected solver kind, or Unknown when none was selected.
SolverAvailabilityInfo? Availability
Gets machine-availability information for the selected solver.
Executes the portable LinearModel with one concrete solver.
LinearModelSolveStatus
Describes the termination state of a solver-backed portable linear model.
record CplexXmlSolution(string Status, IReadOnlyDictionary< int, double > Values)
record ExternalSolverProcessResult(int ExitCode, string StandardOutput, string StandardError)