9 private readonly
int[] _searchModelIndices;
10 private readonly
double[] _effectiveLowerBounds;
11 private readonly
double[] _effectiveUpperBounds;
12 private readonly
double[] _fixedValues;
13 private readonly Dictionary<int, int> _modelIndexByVariableId;
19 ArgumentNullException.ThrowIfNull(
27 ArgumentNullException.ThrowIfNull(
28 options.BoundOverrides);
37 if (_variables.Length == 0)
39 throw new InvalidOperationException(
40 "A metaheuristic encoding requires at least one mathematical variable.");
43 _modelIndexByVariableId =
58 foreach (
int variableId
59 in options.BoundOverrides.Keys)
61 if (!_modelIndexByVariableId.ContainsKey(
64 throw new InvalidOperationException(
65 $
"Bound override references unknown variable identifier '{variableId}'.");
90 for (
int modelIndex = 0;
91 modelIndex < _variables.Length;
95 _variables[modelIndex];
97 EnsureSupportedVariableType(
106 if (options.BoundOverrides.TryGetValue(
115 overrideBounds.Lower;
118 overrideBounds.Upper;
121 if (!
double.IsFinite(lower) ||
122 !
double.IsFinite(upper))
124 throw new NotSupportedException(
125 $
"Variable '{variable.Name}' requires explicit finite metaheuristic bounds.");
131 throw new InvalidOperationException(
132 $
"Effective bounds for variable '{variable.Name}' are inconsistent.");
138 _fixedValues[modelIndex] =
169 if (searchIndices.Count == 0)
171 throw new NotSupportedException(
172 "Metaheuristic search requires at least one non-fixed variable.");
175 _searchModelIndices =
176 searchIndices.ToArray();
178 _effectiveLowerBounds =
179 effectiveLower.ToArray();
181 _effectiveUpperBounds =
182 effectiveUpper.ToArray();
185 new BoundedContinuousSearchSpace(
202 _searchModelIndices.Length;
205 ReadOnlySpan<double> searchPoint)
207 if (searchPoint.Length !=
210 throw new ArgumentException(
211 $
"Expected search dimension {SearchDimension}, received {searchPoint.Length}.",
212 nameof(searchPoint));
216 (
double[])_fixedValues.Clone();
218 for (
int searchIndex = 0;
219 searchIndex < _searchModelIndices.Length;
223 searchPoint[searchIndex];
225 if (!
double.IsFinite(
228 throw new InvalidOperationException(
229 $
"Search coordinate {searchIndex} is not finite.");
233 _searchModelIndices[searchIndex];
236 _variables[modelIndex];
242 _effectiveLowerBounds[searchIndex],
243 _effectiveUpperBounds[searchIndex]);
252 if (!_modelIndexByVariableId.TryGetValue(
256 throw new KeyNotFoundException(
257 $
"Unknown mathematical variable identifier '{variableId}'.");
263 private static void EnsureSupportedVariableType(
275 throw new NotSupportedException(
276 $
"Variable '{variable.Name}' uses a semi-domain not enabled in alpha.37.");
279 throw new NotSupportedException(
280 $
"Variable '{variable.Name}' uses unsupported type '{variable.VariableType}'.");
284 private static void ValidateOverride(
288 if (!
double.IsFinite(bounds.Lower) ||
289 !
double.IsFinite(bounds.Upper) ||
293 throw new InvalidOperationException(
294 $
"Finite strictly ordered override bounds are required for variable '{variable.Name}'.");
301 throw new InvalidOperationException(
302 $
"Override lower bound for variable '{variable.Name}' violates the mathematical lower bound.");
309 throw new InvalidOperationException(
310 $
"Override upper bound for variable '{variable.Name}' violates the mathematical upper bound.");
314 private static void ValidateFreeBounds(
315 MathematicalVariable variable,
325 throw new NotSupportedException(
326 $
"A free binary variable '{variable.Name}' must expose the complete [0,1] latent interval.");
335 Math.Truncate(lower) ||
337 Math.Truncate(upper)))
339 throw new InvalidOperationException(
340 $
"Integer variable '{variable.Name}' requires integral effective bounds.");
344 private static double NormalizeValue(
345 MathematicalVariable variable,
356 return variable.VariableType
switch
358 MathematicalVariableType.Continuous =>
361 MathematicalVariableType.Integer =>
365 MidpointRounding.AwayFromZero),
369 MathematicalVariableType.Binary =>
375 throw new NotSupportedException(
376 $
"Variable type '{variable.VariableType}' cannot be normalized by alpha.37.")