10 IExactRepairMatheuristicDomain
18 private readonly MatheuristicPoint _initialPoint;
19 private readonly MatheuristicVariableKind[] _variableKinds;
20 private readonly
double _feasibilityTolerance;
24 IReadOnlyDictionary<int, double> initialValuesByVariableId,
27 double feasibilityTolerance = 1.0e-6)
29 ArgumentNullException.ThrowIfNull(
32 ArgumentNullException.ThrowIfNull(
33 initialValuesByVariableId);
37 throw new ArgumentNullException(
42 throw new ArgumentNullException(
43 nameof(relaxationSolver));
46 feasibilityTolerance) ||
47 feasibilityTolerance < 0.0)
49 throw new ArgumentOutOfRangeException(
50 nameof(feasibilityTolerance));
78 _feasibilityTolerance =
81 double[] initialValues =
83 initialValuesByVariableId);
85 if (!_evaluator.IsFeasible(
87 feasibilityTolerance))
89 throw new InvalidOperationException(
90 "The exact-repair initial point must be feasible for the source mathematical model.");
94 new MatheuristicPoint(
96 _evaluator.EvaluateObjective(
103 _sourceModel.Objective.Sense
switch
106 OptimizationSense.Minimize,
109 OptimizationSense.Maximize,
112 throw new NotSupportedException(
113 $
"Objective sense '{_sourceModel.Objective.Sense}' is not supported by the exact-repair bridge.")
116 public IReadOnlyList<MatheuristicVariableKind>
121 IRandomSource random)
123 ArgumentNullException.ThrowIfNull(
126 return new MatheuristicPoint(
127 _initialPoint.Values,
128 _initialPoint.Objective,
129 _initialPoint.IsIntegerFeasible,
130 _initialPoint.ReducedCosts);
134 IReadOnlyList<double> values)
136 return _evaluator.EvaluateObjective(
141 IReadOnlyList<double> values)
143 return _evaluator.IsIntegerFeasible(
145 _feasibilityTolerance);
149 ExactRepairRequest request,
150 CancellationToken cancellationToken)
153 _builder.BuildRelaxation(
157 return SolveSubproblem(
161 requireIntegerFeasible:
167 ExactRepairRequest request,
168 CancellationToken cancellationToken)
175 return SolveSubproblem(
179 requireIntegerFeasible:
184 private MatheuristicSolveResult SolveSubproblem(
188 bool requireIntegerFeasible,
189 CancellationToken cancellationToken)
197 ArgumentNullException.ThrowIfNull(
202 return MatheuristicSolveResult.NoSolution(
204 ConvertExploredNodes(
208 var subproblemEvaluator =
209 new MathematicalModelCandidateEvaluator(
213 subproblemEvaluator.ExtractCompleteValues(
216 if (!subproblemEvaluator.IsConstraintFeasible(
218 _feasibilityTolerance))
220 throw new InvalidOperationException(
221 "Exact-repair solve delegate returned a point infeasible for its generated subproblem.");
224 bool integerFeasible =
225 _evaluator.IsIntegerFeasible(
227 _feasibilityTolerance);
229 if (requireIntegerFeasible &&
232 throw new InvalidOperationException(
233 "Exact-repair solve delegate returned a non-integral exact point.");
237 new MatheuristicPoint(
239 _evaluator.EvaluateObjective(
243 return MatheuristicSolveResult.FromPoint(
246 ConvertExploredNodes(
250 private double[] CreateCompleteValues(
251 IReadOnlyDictionary<int, double> valuesByVariableId)
254 new double[_variables.Length];
257 index < _variables.Length;
263 if (!valuesByVariableId.TryGetValue(
267 throw new InvalidOperationException(
268 $
"Initial point is missing variable identifier '{variable.Id}'.");
271 if (!
double.IsFinite(
274 throw new InvalidOperationException(
275 $
"Initial value for variable '{variable.Name}' is not finite.");
285 private static MatheuristicVariableKind
287 MathematicalVariable variable)
289 return variable.VariableType
switch
291 MathematicalVariableType.Continuous =>
292 MatheuristicVariableKind.Continuous,
294 MathematicalVariableType.Integer =>
295 MatheuristicVariableKind.Integer,
297 MathematicalVariableType.Binary =>
298 MatheuristicVariableKind.Binary,
301 throw new NotSupportedException(
302 $
"Variable type '{variable.VariableType}' is outside the alpha.37 exact-repair bridge.")
306 private static int ConvertExploredNodes(
309 if (!exploredNodes.HasValue)
314 if (exploredNodes.Value <
316 exploredNodes.Value >
319 throw new InvalidOperationException(
320 "Exact-repair explored-node count is outside the supported range.");
323 return (
int)exploredNodes.Value;