10 ExactRepairRequest request)
12 ArgumentNullException.ThrowIfNull(
15 ArgumentNullException.ThrowIfNull(
37 ApplyAllowedActiveIndices(
41 int nextConstraintId =
42 result.Constraints.Count == 0
48 if (request.HammingRadius.HasValue)
58 if (request.ObjectiveCutoff.HasValue)
62 request.ObjectiveCutoff.Value,
73 IReadOnlyList<double> referenceValues,
77 ArgumentNullException.ThrowIfNull(
82 new ExactRepairRequest
85 MatheuristicSolveMode.OriginalObjective,
100 ExactRepairRequest request)
114 variable.VariableType =
119 result.EnsureValid();
124 private static void EnsureSupportedMode(
125 ExactRepairRequest request)
127 if (request.NodeLimit <= 0)
129 throw new InvalidOperationException(
130 "An exact-repair node limit must be strictly positive.");
134 MatheuristicSolveMode.OriginalObjective)
136 throw new NotSupportedException(
137 $
"Alpha.37 exact-repair bridge supports OriginalObjective mode only; received '{request.Mode}'.");
140 if (request.DistanceLimit.HasValue ||
141 request.TargetValues is not
null)
143 throw new NotSupportedException(
144 "Distance-target exact-repair modes are deferred beyond alpha.37.");
148 private static void ApplyBounds(
149 IReadOnlyList<MathematicalVariable> variables,
150 ExactRepairRequest request)
152 foreach (KeyValuePair<int, MatheuristicVariableBound> bound
160 EnsureBoundInsideSource(
165 variable.LowerBound =
168 variable.UpperBound =
172 foreach (KeyValuePair<int, double> fixing
173 in request.FixedValues)
175 MathematicalVariable variable =
180 EnsureBoundInsideSource(
185 EnsureValueMatchesType(
189 variable.LowerBound =
192 variable.UpperBound =
197 private static void ApplyAllowedActiveIndices(
198 IReadOnlyList<MathematicalVariable> variables,
199 ExactRepairRequest request)
201 if (request.AllowedActiveIndices is
null)
208 request.AllowedActiveIndices);
211 index < variables.Count;
214 MathematicalVariable variable =
225 EnsureBoundInsideSource(
230 variable.LowerBound =
233 variable.UpperBound =
238 private static int AddHammingConstraint(
239 MathematicalModel model,
240 IReadOnlyList<MathematicalVariable> variables,
241 ExactRepairRequest request,
244 if (request.ReferenceValues is
null)
246 throw new InvalidOperationException(
247 "A Hamming-radius request requires reference values.");
250 if (request.ReferenceValues.Count !=
253 throw new InvalidOperationException(
254 "Hamming reference dimension does not match the mathematical model.");
258 request.HammingRadius ??
259 throw new InvalidOperationException(
260 "A Hamming radius is required.");
264 throw new InvalidOperationException(
265 "A Hamming radius cannot be negative.");
269 new LinearExpression();
271 int referenceOneCount =
275 index < variables.Count;
278 MathematicalVariable variable =
288 request.ReferenceValues[index];
291 Math.Abs(reference) <=
295 Math.Abs(reference - 1.0) <=
301 throw new InvalidOperationException(
302 $
"Binary Hamming reference at index {index} is not zero or one.");
322 new LinearConstraint(
324 "metaheuristicLocalBranchingHamming",
330 return constraintId + 1;
333 private static void AddObjectiveCutoff(
334 MathematicalModel model,
338 if (!
double.IsFinite(
341 throw new InvalidOperationException(
342 "A matheuristic objective cutoff must be finite.");
345 LinearExpression expression =
355 model.Objective.Sense
switch
357 ObjectiveSense.Minimize =>
360 ObjectiveSense.Maximize =>
364 throw new NotSupportedException(
365 $
"Objective sense '{model.Objective.Sense}' cannot define a matheuristic objective cutoff.")
369 new LinearConstraint(
371 "metaheuristicObjectiveCutoff",
378 private static MathematicalVariable GetVariable(
379 IReadOnlyList<MathematicalVariable> variables,
386 throw new ArgumentOutOfRangeException(
390 return variables[index];
393 private static void EnsureBoundInsideSource(
394 MathematicalVariable variable,
398 if (!
double.IsFinite(lower) ||
399 !
double.IsFinite(upper) ||
403 throw new InvalidOperationException(
404 $
"Invalid exact-repair bounds for variable '{variable.Name}'.");
412 throw new InvalidOperationException(
413 $
"Exact-repair bounds for variable '{variable.Name}' exceed its source domain.");
417 private static void EnsureValueMatchesType(
418 MathematicalVariable variable,
431 throw new InvalidOperationException(
432 $
"Integer variable '{variable.Name}' cannot be fixed to {value:G17}.");
441 throw new InvalidOperationException(
442 $
"Binary variable '{variable.Name}' can only be fixed to zero or one.");
448 throw new NotSupportedException(
449 $
"Variable type '{variable.VariableType}' is outside the alpha.37 exact-repair bridge.");