Schedule

A ScheduleConfiguration is the execution plan for a multi-phase optimisation. It pairs:

  • a named map of Algorithms, and

  • a tree of StepConfiguration nodes that reference those algorithms by key.

Attach a built schedule to a ConfigurationBuilder with set_schedule_configuration(). This is mutually exclusive with set_algorithm(), which is shorthand for a one-step schedule.

Step types

A StepType controls how a node executes:

  • SINGLE — leaf node; invokes the algorithm at algorithm_config_key against the current best solution.

  • SEQUENCE — container; runs children one after another, each seeded by the previous step’s result.

  • PARALLEL — container; runs children concurrently from the same seed and merges their results.

Containers may nest. A schedule with one SINGLE root is the simplest case:

from daitum_configuration import (
    GeneticAlgorithm,
    ScheduleConfiguration,
    StepConfiguration,
    StepType,
)

root = StepConfiguration(StepType.SINGLE, algorithm_config_key="ga")
schedule = ScheduleConfiguration(root).add_algorithm("ga", GeneticAlgorithm())

Subproblem and execution features

Each StepConfiguration carries optional fields that scope or control its execution. All are configured by chained add_* / set_* methods after construction. JSON keys are flattened onto the step.

Tag-based filtering — add_included_tag

Restrict the step to a subset of decision variables. A variable is included when every tag attached to it appears in the step’s includedTags; variables with no tags are always included. Excluded variables are held at their seed values.

Tags are sourced from the model via DecisionVariable.set_tag_source.

Parameter overrides — add_override_parameter

Set model parameter values for the duration of this step. The model is fully re-evaluated each evaluation, so override targets need not lie on decision-dependent paths. Step-scoped overrides take precedence over schedule-wide add_global_parameter() entries.

Dynamic splitting — set_split_values_key

Split the step into independent subproblems by model value. split_values_key is a model reference returning a comma-separated string (for example "North,South,East,West"). One subproblem is run per value, with the value appended to includedTags so each subproblem optimises a disjoint slice of variables. Subproblem variable sets must not overlap.

Conditional skipping — set_disabled_key

Skip the step based on a model value. disabled_key is a model reference; when its serialised value equals "true" the step is replaced with an empty pass-through and the current best solution flows through unchanged.

Dynamic range recalculation — set_recalculate_ranges

Narrow decision-variable bounds from current model state. The platform reads each variable’s range fields against the current best solution and any applied overrides, then builds the subproblem with the resulting bounds. New bounds must be a subset of the original; empty ranges exclude the variable; single-value ranges fix it.

Deferred construction — set_deferred

Delay step construction until just before execution. Required when any of the above depends on values that earlier steps must first produce. When deferred, the current best solution is passed in as the seed for evaluating the model references.

Complete example

A three-phase optimisation that:

  1. optimises each day of the week as an independent subproblem,

  2. follows with a full optimisation using ranges recalculated from the result of phase 1, and

  3. ends with an optional local-search refinement that may be skipped via a model flag.

from daitum_configuration import (
    GeneticAlgorithm,
    ScheduleConfiguration,
    StepConfiguration,
    StepType,
    VariableNeighbourhoodSearch,
)

per_day = (
    StepConfiguration(StepType.SINGLE, algorithm_config_key="ga")
    .set_split_values_key("DayOfWeek")
    .add_included_tag("PerDay")
    .add_override_parameter("dailyOptimisation", "true")
)

full_refit = (
    StepConfiguration(StepType.SINGLE, algorithm_config_key="ga")
    .set_deferred(True)
    .set_recalculate_ranges(True)
)

refinement = (
    StepConfiguration(StepType.SINGLE, algorithm_config_key="ls")
    .set_disabled_key("skipRefinement")
)

root = StepConfiguration(StepType.SEQUENCE)
root.add_step(per_day).add_step(full_refit).add_step(refinement)

schedule = (
    ScheduleConfiguration(root)
    .add_algorithm("ga", GeneticAlgorithm())
    .add_algorithm("ls", VariableNeighbourhoodSearch())
)

JSON field reference

Each StepConfiguration emits a flat object — none of the subproblem fields nest under a sub-object. None-valued fields are omitted.

JSON key

Type

Default

Notes

type

StepType

required

SINGLE, SEQUENCE, or PARALLEL.

algorithmConfigKey

string

Required for SINGLE; forbidden for containers.

steps

list

Populated for containers via add_step; absent for SINGLE.

includedTags

list[string]

omitted

Tag whitelist; see add_included_tag.

overrideParameters

map[string, string]

omitted

Step-scoped parameter overrides.

splitValuesKey

string

omitted

Model reference for splitting into separable subproblems.

disabledKey

string

omitted

Model reference; step is skipped when its value is "true".

recalculateRanges

bool

false

Recompute variable bounds from current model state.

deferred

bool

false

Delay construction until just before execution.

API reference

ScheduleConfiguration — multi-step optimisation schedule.

class ScheduleConfiguration(schedule_root)[source]

Multi-step optimisation schedule.

Pairs a named map of Algorithm instances with a StepConfiguration tree that references them by key. The tree is the execution plan; the map supplies the algorithms each StepType.SINGLE leaf invokes.

Algorithms are registered via add_algorithm(). The key argument is the same string that a SINGLE StepConfiguration passes as its algorithm_config_key. Schedule-wide parameter overrides are registered via add_global_parameter(); step-scoped overrides on individual steps take precedence (see StepConfiguration.add_override_parameter()).

Attach a built schedule to a ConfigurationBuilder with set_schedule_configuration() — mutually exclusive with set_algorithm().

Example:

from daitum_configuration import (
    GeneticAlgorithm,
    ScheduleConfiguration,
    StepConfiguration,
    StepType,
)

root = StepConfiguration(StepType.SINGLE, algorithm_config_key="ga")
schedule = (
    ScheduleConfiguration(root)
    .add_algorithm("ga", GeneticAlgorithm())
    .add_global_parameter("seed", "42")
)
Parameters:

schedule_root (StepConfiguration) – Root step of the execution tree. Required.

add_algorithm(key, algorithm)[source]

Register an Algorithm under key.

key is the same string a SINGLE StepConfiguration passes as its algorithm_config_key to invoke this algorithm. Every algorithm_config_key referenced anywhere in the schedule tree must resolve to a key registered here. Adding the same key twice replaces the previous algorithm.

Return type:

ScheduleConfiguration

add_global_parameter(key, value)[source]

Add a parameter override applied across every step in the schedule.

key is a parameter name and value is a serialised model value. Adding the same key twice replaces the previous value. Step-scoped overrides set via StepConfiguration.add_override_parameter() take precedence over these globals for the steps on which they’re set.

Return type:

ScheduleConfiguration

StepConfiguration — one node in a ScheduleConfiguration tree.

class StepConfiguration(step_type, algorithm_config_key=None)[source]

One node in a ScheduleConfiguration execution tree.

A step is either a leafStepType.SINGLE referencing an algorithm by key — or a containerStepType.PARALLEL or StepType.SEQUENCE — holding child steps. Containers may nest arbitrarily.

Subproblem and execution behaviour are configured via chained add_* / set_* methods after construction. Each maps to one subproblem feature:

All six fields and add_step return self for fluent chaining.

Parameters:
  • step_type (StepType) – StepType of this node.

  • algorithm_config_key (str | None) – Algorithm key resolved against ScheduleConfiguration.add_algorithm(). Required for SINGLE; forbidden for container types. Container children are appended via add_step().

Raises:

ValueError – If algorithm_config_key does not match step_type.

Example:

from daitum_configuration import StepConfiguration, StepType

# A SEQUENCE: per-day separable optimisation, then a full
# optimisation with narrowed ranges, then an optional refinement.
root = StepConfiguration(StepType.SEQUENCE)
root.add_step(
    StepConfiguration(StepType.SINGLE, algorithm_config_key="ga")
    .set_split_values_key("DayOfWeek")
    .add_included_tag("PerDay")
    .add_override_parameter("dailyOptimisation", "true")
)
root.add_step(
    StepConfiguration(StepType.SINGLE, algorithm_config_key="ga")
    .set_deferred(True)
    .set_recalculate_ranges(True)
)
root.add_step(
    StepConfiguration(StepType.SINGLE, algorithm_config_key="ls")
    .set_disabled_key("skipRefinement")
)
add_step(step_configuration)[source]

Append a child step to this container.

Raises:

ValueError – If this node is StepType.SINGLE.

Return type:

StepConfiguration

add_included_tag(tag)[source]

Append a tag to the variable filter for this step.

Only decision variables whose tags are all in included_tags are optimised; variables with no tags are always included. Excluded variables are held at their seed values. Adding the same tag twice is a no-op.

Variable tags are sourced via DecisionVariable.set_tag_source.

Return type:

StepConfiguration

add_override_parameter(key, value)[source]

Add a model parameter override applied during this step.

key is a parameter name and value is a serialised model value. Overrides are applied before each evaluation in this step; the model is fully re-evaluated, so override targets need not lie on decision-dependent paths. Adding the same key twice replaces the previous value. Step-scoped overrides take precedence over ScheduleConfiguration.add_global_parameter.

Return type:

StepConfiguration

set_split_values_key(split_values_key)[source]

Split this step into independent subproblems by model value.

split_values_key is a model reference returning a comma-separated string (for example "North,South,East,West"). One subproblem is run per value, with the value appended to included_tags so each subproblem optimises a disjoint slice of decision variables. Subproblem variable sets must not overlap.

Return type:

StepConfiguration

set_recalculate_ranges(recalculate_ranges)[source]

Narrow decision-variable bounds from current model state.

When True, the platform reads each variable’s range fields against the current best solution and any applied parameter overrides, then builds the subproblem with the resulting bounds. The new bounds must be a subset of the original. Variables with empty new ranges are excluded; single-value ranges are fixed.

Commonly combined with set_deferred() so the recalculation happens after earlier steps have shaped the current best solution.

Return type:

StepConfiguration

set_disabled_key(disabled_key)[source]

Conditionally skip this step based on a model value.

disabled_key is a model reference; when its serialised value equals "true" the step is replaced with an empty pass-through and the current best solution flows through unchanged.

Return type:

StepConfiguration

set_deferred(deferred)[source]

Delay step construction until just before execution.

Required when any of add_included_tag(), add_override_parameter(), set_split_values_key(), set_recalculate_ranges(), or set_disabled_key() depends on results produced by earlier steps. When deferred, the current best solution is passed in as the seed for evaluating those model references.

Return type:

StepConfiguration

StepType enum used by StepConfiguration.

class StepType(*values)[source]

Kind of node in a ScheduleConfiguration execution tree.

A StepConfiguration’s type determines whether it executes an algorithm (leaf) or composes child steps (container).

Values:
SINGLE: Leaf node — runs the algorithm registered under

algorithm_config_key against the current best solution. Carries no children.

SEQUENCE: Container — runs child steps one after another, each

seeded with the previous step’s best solution.

PARALLEL: Container — runs child steps concurrently from the same

seed and merges their results.

PARALLEL = 'PARALLEL'
SEQUENCE = 'SEQUENCE'
SINGLE = 'SINGLE'