Class ConditionalParams
- Namespace
- OptunaSharp.Samplers.NsgaiiiCpt
- Assembly
- OptunaSharp.dll
Declares conditional parameters — parameters that only exist while an activator parameter holds one of a set of values — the rule set consumed by NSGAIIICptSampler (NSGA-III-CPT), the only sampler that accepts it. An OptunaSharp extension with no Optuna analog: opt-in, and the plain genetic samplers (NSGAIISampler / NSGAIIISampler) are bit-exact Optuna ports that do not take it.
Why it exists. Optuna's define-by-run API lets an objective suggest a parameter under
a branch only (if (optimizer == "adam") t.SuggestFloat("beta1", …)), but the GA samplers
evolve the intersection search space — the parameters present in every completed
trial. A parameter absent from even one trial leaves the intersection for good and is resampled
uniformly at random by the independent sampler on every later trial: no crossover, no mutation,
no inheritance — no evolutionary pressure at all. Declaring the parameter here tells the sampler
that its absence is expected (it was inactive), so it stays in the relative search space and
is evolved like any other parameter whenever it is active, and is simply not present — never
blended, never counted — whenever it is not.
Rules. When(activator, values…).Activates(parameters…) declares that each of
parameters is active only while activator holds one of values (Python ==
semantics via CategoricalChoice: 1 == 1.0 == true, strings ordinal, a lone
null is None); When(activator, predicate) takes an arbitrary test instead — the
value arrives as the trial stores it: a boxed long for int parameters, a
double for float parameters, the raw choice value for categorical ones. Several
rules may name the same activator (they OR: any admissible value suffices) and a parameter may be
declared under several activators (they AND: every activator must admit). An activator may itself
be conditional (chains); self-activation and cycles are rejected at declaration.
What the sampler does with it. (1) Relative search space: a conditional parameter joins
it once any completed trial has suggested it, provided every trial that did used the same
distribution (a changing distribution excludes it, exactly as the intersection would).
(2) Crossover: the categorical uniform crossover and the numerical crossover operator run over the
parameters the selected parents all carry; a parameter carried by only some parents is inherited
from one of those; one carried by none stays absent. (3) After crossover (or the no-crossover
parent copy) every conditional parameter whose activators say "inactive" is removed from the
child — it neither counts toward the default 1 / n_params mutation probability nor reaches
the trial. (4) The objective's own Suggest* calls stay the final word: a proposed parameter
the objective never suggests is never recorded, and a suggested parameter the sampler did not
propose is drawn independently — the usual define-by-run contract. The sampler warns once per
parameter when a completed trial contradicts the rules (present while inactive, or absent while
active), which usually means the objective's branches and the declaration drifted apart.
var rules = new ConditionalParams()
.When("optimizer", "adam", "adamw").Activates("beta1", "beta2")
.When("optimizer", "sgd").Activates("momentum")
.When("n_layers", v => (long)v! >= 3).Activates("width_3");
var sampler = new NSGAIIICptSampler(populationSize: 32, seed: 0, conditionalParams: rules);public sealed class ConditionalParams
- Inheritance
-
ConditionalParams
- Inherited Members
Properties
Parameters
The conditional (activated) parameter names, in declaration order.
public IReadOnlyCollection<string> Parameters { get; }
Property Value
PreserveDormantValues
Opt-in divergence from Optuna (off by default). When true, a conditional parameter
that is inactive for a trial does not vanish: its last active value is parked in a latent
side channel (a trial system attribute — never suggested, never scored, never crossed or
mutated, so still out of every equation), and when the parameter's branch reactivates it
resumes from that preserved value instead of a fresh random draw. The hyperparameter list
stays fluid — genes move between the active genome and the dormant channel — but the fluidity is
non-destructive: a branch toggling off and on again does not throw away what was learned about
it. Optuna always re-samples, so this only takes effect when you ask for it.
A resumed gene is an ordinary active gene again from that point (free to be crossed and
mutated); dormancy freezes the value only while the branch is off. A gene that has never been
active has no latent value to resume, so its first activation is still a normal draw. Requires
the chosen storage to round-trip a {name: value} map through trial system attributes
(in-memory and JSON storages do).
public bool PreserveDormantValues { get; init; }
Property Value
Methods
ActivatorsOf(string)
The activators name was declared under (empty when unconditional).
public IReadOnlyCollection<string> ActivatorsOf(string name)
Parameters
namestringThe parameter or attribute name to look up.
Returns
- IReadOnlyCollection<string>
The declared activator names for this parameter, or an empty collection for an unconditional parameter.
IsActive(string, IReadOnlyDictionary<string, object?>)
Whether name is active for a complete parameter assignment such as
Params: unconditional parameters always are; a conditional one is
active when every activator it was declared under is present, admits the value it holds, and is
itself active.
public bool IsActive(string name, IReadOnlyDictionary<string, object?> @params)
Parameters
namestringThe parameter or attribute name to look up.
paramsIReadOnlyDictionary<string, object>The complete external parameter assignment against which activation is evaluated.
Returns
- bool
True when the current assignment satisfies every declared activator requirement.
Exceptions
- ArgumentNullException
The parameter assignment is null or the lookup name is null.
- Exception
A caller-supplied activation predicate throws while evaluating an external parameter value.
IsConditional(string)
Whether name was declared conditional.
public bool IsConditional(string name)
Parameters
namestringThe parameter or attribute name to look up.
Returns
- bool
True when the parameter has at least one declared activator.
ToString()
Returns a deterministic textual description of the declared activation rules.
public override string ToString()
Returns
- string
A deterministic textual description of the declared activation rules.
When(string, Func<object?, bool>)
Starts a rule with an arbitrary test on the activator's value — the value arrives as the trial
stores it: a boxed long for int parameters, a double for float
parameters, the raw choice value (string/long/double/bool/null)
for categorical ones.
public ConditionalParams.ActivationBuilder When(string activator, Func<object?, bool> predicate)
Parameters
activatorstringThe name of the parameter whose value controls whether dependent parameters are active.
predicateFunc<object, bool>The admissible-value test applied to the activator's external value.
Returns
- ConditionalParams.ActivationBuilder
A builder that attaches dependent parameters to the supplied activator condition.
Exceptions
- ArgumentNullException
The activator name or predicate is null.
- ValueError
The activator name is blank.
When(string, params object?[]?)
Starts a rule: the parameters named by the following Activates(params string[])
are active only while activator holds one of values.
public ConditionalParams.ActivationBuilder When(string activator, params object?[]? values)
Parameters
activatorstringThe parameter whose value gates the others.
valuesobject[]Admissible activator values, compared with Python
==semantics (1 == 1.0 == true, strings ordinal, NaN matches NaN as Optuna's categorical lookup does). Anullelement is the choiceNone— spell it(object?)null, since a barenullliteral is ambiguous with the predicate overload.
Returns
- ConditionalParams.ActivationBuilder
A builder that attaches dependent parameters to the supplied activator condition.
Exceptions
- ArgumentNullException
The activator name is null.
- ValueError
The activator name is blank, or no admissible values are supplied.