saealib.MutationPolynomial#

class saealib.MutationPolynomial(prob=1.0, *, eta, prob_var=None)[ソース]#

ベースクラス: Mutation

Polynomial mutation operator.

パラメータ:
  • prob (float)

  • eta (float)

  • prob_var (float | None)

prob#

Individual-level mutation probability.

Type:

float

eta#

Distribution index. Larger values produce smaller perturbations.

Type:

float

prob_var#

Per-variable mutation probability. Defaults to min(0.5, 1/dim) when None.

Type:

float or None

メモ

Originates from Deb & Goyal (1996); the primary paper has not been obtained (it is credited here by name only). The asymmetric delta1/delta2 perturbation formula implemented in mutate_batch() has been verified against Deb's own official NSGA-II reference implementation (nsga2-gnuplot-v1.1.6/mutation.c, function real_mutate_ind).

Methods

__init__

Initialize polynomial mutation operator.

contract

Return the real-valued polynomial mutation contract.

mutate

Execute mutation for one candidate.

mutate_batch

Execute polynomial mutation on a batch of candidates at once.

post_mutation

Post-mutation lifecycle hook; override to inject custom processing.

post_mutation_batch

Run the post-mutation lifecycle hook for a batch.

with_post

Return a copy of this operator with fn appended to the hook.

Method Details

MutationPolynomial.__init__(prob=1.0, *, eta, prob_var=None)[ソース]#

Initialize polynomial mutation operator.

パラメータ:
  • prob (float, optional) -- Individual-level mutation probability, by default 1.0.

  • eta (float) -- Distribution index.

  • prob_var (float or None, optional) -- Per-variable mutation probability. None uses min(0.5, 1/dim).

MutationPolynomial.contract()[ソース]#

Return the real-valued polynomial mutation contract.

戻り値の型:

ComponentContract

MutationPolynomial.mutate(p, mutate_range, rng=Generator(PCG64) at 0x7FE0F47AA6C0)#

Execute mutation for one candidate.

This method is derived from mutate_batch() by passing a single-row batch.

メモ

Overriding only this method (not mutate_batch()) has no effect under GA's default variation_execution="batch": the batch path calls mutate_batch() directly and never calls mutate(). Such an override only takes effect under variation_execution="sequential". To customize behavior under both modes, override mutate_batch().

パラメータ:
  • p (np.ndarray) -- Parent individual. shape = (dim,)

  • mutate_range (tuple) -- Tuple of (lower_bound, upper_bound) for mutation.

  • rng (np.random.Generator, optional) -- Random number generator, by default np.random.default_rng()

戻り値:

Mutated individual. shape = (dim,). The result is always float64 because mutate_batch() casts its input internally; the result does not preserve the input's dtype.

戻り値の型:

np.ndarray

MutationPolynomial.mutate_batch(candidates_batch, mutate_range, rng=Generator(PCG64) at 0x7FE0F47AAEA0)[ソース]#

Execute polynomial mutation on a batch of candidates at once.

This is the primary polynomial mutation implementation. An individual-level prob gate (one Bernoulli draw per row via rng.random(n) < self.prob) selects which rows are touched at all; a per-dimension prob_var gate is then drawn only for the selected rows, and only dimensions passing that gate are replaced. Unlike mutate_batch(), the replacement value is not a plain uniform draw: it is the asymmetric delta1/delta2 polynomial perturbation formula (Deb & Goyal, 1996), which itself branches on a second per-dimension draw u (u <= 0.5 vs. u > 0.5). That inner branch is vectorized by computing both branches (delta_q_lo, delta_q_hi) over the full (k, dim) array unconditionally and selecting between them with np.where(u <= 0.5, delta_q_lo, delta_q_hi) -- the same "compute both sides, select after" pattern already used by CrossoverSBX.crossover_batch()'s _beta_q helper. Rows that fail the individual-level gate are returned byte-identical to the input; dimensions failing the per-dimension gate on a selected row keep their original value exactly (np.where copies rather than recomputes them). If no row passes the individual-level gate (gate.sum() == 0), no further random draws happen at all and the input is returned unchanged, mirroring MutationUniform.mutate_batch's empty-gate skip.

パラメータ:
  • candidates_batch (np.ndarray) -- Batch of candidate individuals. shape = (n, dim)

  • mutate_range (tuple) -- Tuple of (lower_bound, upper_bound) for mutation.

  • rng (np.random.Generator, optional) -- Random number generator, by default np.random.default_rng()

戻り値:

Mutated individuals. shape = (n, dim)

戻り値の型:

np.ndarray

メモ

For multiple rows, a loop of separate single-row mutate_batch calls (equivalently, separate mutate() calls) does not reproduce the same per-row results as one batched call with the same seeded rng. Separate calls interleave each row's individual gate, full per-dimension gate array, and full u array before moving to the next row. One batched call instead draws all individual gates, then the variable-gate arrays for all gated rows, then the u arrays for all of them. These phases therefore have a different draw order whenever more than one row is involved. Only the statistical and distributional semantics are guaranteed to match.

The output is always float64 (via the internal dtype=float cast), regardless of the input array's dtype.

MutationPolynomial.post_mutation(offspring, mutate_range, rng, ctx=None)#

Post-mutation lifecycle hook; override to inject custom processing.

パラメータ:
  • offspring (np.ndarray) -- Individual after mutation. shape = (dim,)

  • mutate_range (tuple) -- Tuple of (lower_bound, upper_bound) used for mutation.

  • rng (np.random.Generator) -- Random number generator.

  • ctx (ExecutionContext or None, optional) -- Current optimization context.

戻り値:

Processed individual. shape = (dim,)

戻り値の型:

np.ndarray

MutationPolynomial.post_mutation_batch(offspring_batch, mutate_range, rng, ctx=None)#

Run the post-mutation lifecycle hook for a batch.

The default implementation calls post_mutation() once per individual, in order. Override this method to provide genuinely vectorized post-processing.

パラメータ:
  • offspring_batch (np.ndarray) -- Offspring produced by mutation. shape = (n, dim)

  • mutate_range (tuple) -- Tuple of (lower_bound, upper_bound) used for mutation.

  • rng (np.random.Generator) -- Random number generator.

  • ctx (ExecutionContext or None, optional) -- Current optimization context.

戻り値:

Processed offspring. shape = (n, dim)

戻り値の型:

np.ndarray

メモ

with_post() reassigns only the instance's post_mutation() hook. A subclass override of this method is responsible for composing that hook itself. If the override does not call self.post_mutation, a hook installed with with_post() will not run in GA batch mode. It still runs in GA sequential mode, which calls post_mutation() directly.

MutationPolynomial.with_post(fn)#

Return a copy of this operator with fn appended to the hook.

パラメータ:

fn (callable) -- fn(offspring, mutate_range, rng, ctx) -> np.ndarray

戻り値:

Shallow copy with the hook registered.

戻り値の型:

Mutation