saealib.PymooCrossover#
- class saealib.PymooCrossover(operator, *, prob=None, n_parents=None, n_children=None)[source]#
Bases:
CrossoverAdapter wrapping a pymoo crossover operator as a saealib
Crossover.Lets researchers who already have a pymoo
Crossover(e.g.SBX(),PCX()) reuse it unchanged inside saealib’sGA.- Parameters:
operator (pymoo.core.crossover.Crossover) – An already-constructed pymoo crossover operator instance.
prob (float, optional) – Individual-level crossover probability, gated by saealib’s
GAbeforecrossover_batch()/crossover()is even called (on the gated subset in batch mode, per gated pair in sequential mode). Defaults to the wrapped operator’s ownprob.value(pymoo wraps it as apymoo.core.variable.Real).n_parents (int, optional) – Defaults to
operator.n_parents.n_children (int, optional) – Defaults to
operator.n_offsprings.
Notes
crossover_batch()calls the wrapped operator’s_do()(not.do(), which would apply pymoo’s ownprobgate a second time on top of saealib’s). The inheritedcrossover()derives a single-parent- group call from that batch implementation.A minimal internal
pymoo.core.problem.Problemis synthesized to satisfy operators (e.g. SBX) that readproblem.xl/problem.xu/problem.n_var; it is cached and rebuilt only whendimorboundschanges. Most pymoo crossovers unconditionally require finitexl/xuand raise their own (pymoo-internal) error whenbounds=Noneis passed through; saealib’s ownGAalways supplies bounds, so this only matters for direct calls.rngis forwarded to the wrapped operator via pymoo’s ownrandom_stateparameter, so results are reproducible under saealib’s seeding.
Methods
Return the wrapped crossover contract. |
|
Execute crossover for one parent group. |
|
Execute crossover on a batch of parent pairs via a single pymoo call. |
|
Post-crossover lifecycle hook; override to inject custom processing. |
|
Run the post-crossover lifecycle hook for a batch. |
|
Return a copy of this operator with |
Method Details
- PymooCrossover.__init__(operator, *, prob=None, n_parents=None, n_children=None)[source]#
- Parameters:
operator (_PymooCrossoverLike)
prob (float | None)
n_parents (int | None)
n_children (int | None)
- Return type:
None
- PymooCrossover.crossover(parent, bounds=None, rng=Generator(PCG64) at 0x7F79179411C0)#
Execute crossover for one parent group.
This method is derived from
crossover_batch()by passing a single-pair batch.Notes
Overriding only this method (not
crossover_batch()) has no effect under GA’s defaultvariation_execution="batch": the batch path callscrossover_batch()directly and never callscrossover(). Such an override only takes effect undervariation_execution="sequential". To customize behavior under both modes, overridecrossover_batch().- Parameters:
parent (np.ndarray) – Parent individuals. shape = (n_parents, dim)
bounds (tuple of (np.ndarray, np.ndarray) or None) – Lower and upper bounds for each variable.
Nonemeans unbounded.rng (np.random.Generator, optional) – Random number generator, by default np.random.default_rng()
- Returns:
Offspring individuals. shape = (n_offspring, dim)
- Return type:
np.ndarray
- PymooCrossover.crossover_batch(parents_batch, bounds=None, rng=Generator(PCG64) at 0x7F7917915B60)[source]#
Execute crossover on a batch of parent pairs via a single pymoo call.
This is the adapter’s primary crossover implementation and calls the wrapped operator’s
_do()exactly once for the whole batch.- Parameters:
parents_batch (np.ndarray) – Batch of parent groups. shape = (n_pair, n_parents, dim)
bounds (tuple of (np.ndarray, np.ndarray) or None) – Lower and upper bounds for each variable.
rng (np.random.Generator, optional) – Forwarded to the wrapped operator as
random_state.
- Returns:
Offspring individuals. shape = (n_pair, n_children, dim)
- Return type:
np.ndarray
Notes
For
n_pair > 1, a loop of separate single-paircrossover_batchcalls (equivalently, separatecrossover()calls) does not reproduce the same per-row results as one batched call with the same seededrng. Operators such as pymoo’s SBX draw each random phase across the whole batch, whereas single-pair calls interleave phases per row.
- PymooCrossover.post_crossover(offspring, parents, rng, ctx=None)#
Post-crossover lifecycle hook; override to inject custom processing.
- Parameters:
offspring (np.ndarray) – Offspring produced by crossover. shape = (n_children, dim)
parents (np.ndarray) – Parent individuals. shape = (n_parents, dim)
rng (np.random.Generator) – Random number generator.
ctx (ExecutionContext or None, optional) – Current optimization context.
- Returns:
Processed offspring. shape = (n_children, dim)
- Return type:
np.ndarray
- PymooCrossover.post_crossover_batch(offspring_batch, parents_batch, rng, ctx=None)#
Run the post-crossover lifecycle hook for a batch.
The default implementation calls
post_crossover()once per parent group, in order. Override this method to provide genuinely vectorized post-processing.- Parameters:
offspring_batch (np.ndarray) – Offspring produced by crossover. shape = (n_pair, n_children, dim)
parents_batch (np.ndarray) – Batch of parent groups. shape = (n_pair, n_parents, dim)
rng (np.random.Generator) – Random number generator.
ctx (ExecutionContext or None, optional) – Current optimization context.
- Returns:
Processed offspring. shape = (n_pair, n_children, dim)
- Return type:
np.ndarray
Notes
with_post()reassigns only the instance’spost_crossover()hook. A subclass override of this method is responsible for composing that hook itself. If the override does not callself.post_crossover, a hook installed withwith_post()will not run in GA batch mode. It still runs in GA sequential mode, which callspost_crossover()directly.