Skip to content

Decision schedules

When a policy may order. Guide: Decision schedules.

DecisionSchedule

Base class for a calendar of ordering opportunities.

A schedule answers when a policy may order; the policy answers how much. Periods are zero-based demand periods of the run. Subclasses implement the three methods below; they see only period numbers (never demand) and must not change while being queried, so the engine can check every decision before a run starts.

Example
class EveryOtherDay(DecisionSchedule):
    def should_decide(self, period):
        return period % 2 == 0

    def next_decision_period(self, period):
        return period + 2 - period % 2

    def to_manifest(self):
        return {"type": "every_other_day"}

should_decide

should_decide(period: int) -> bool

Whether the policy may order in period.

Parameters:

Name Type Description Default
period int

Zero-based demand period.

required

Returns:

Type Description
bool

True for an ordering opportunity.

next_decision_period

next_decision_period(period: int) -> Optional[int]

The next opportunity strictly after period.

Used to size the protection window of irregular schedules, H = (next - period) + lead_time.

Parameters:

Name Type Description Default
period int

Zero-based demand period.

required

Returns:

Type Description
Optional[int]

The next decision period, or None if there is none.

to_manifest

to_manifest() -> dict

Describe the schedule for the run manifest.

Returns:

Type Description
dict

A JSON-serialisable dict.

PeriodicSchedule dataclass

PeriodicSchedule(every: int, start: int = 0)

Bases: DecisionSchedule

Decide every every periods, starting at start.

Decision periods are start, start + every, start + 2 * every, .... review_period=R on a policy is shorthand for PeriodicSchedule(R).

Parameters:

Name Type Description Default
every int

Review period R, an integer >= 1.

required
start int

First decision period, an integer >= 0 (default 0).

0
Example
PeriodicSchedule(every=7, start=3)   # periods 3, 10, 17, ...

OneTimeSchedule dataclass

OneTimeSchedule(period: int = 0)

Bases: DecisionSchedule

Decide exactly once, in period.

Used by SingleOrderPolicy for a single seasonal purchase.

Parameters:

Name Type Description Default
period int

The decision period, an integer >= 0 (default 0).

0

ExplicitSchedule dataclass

ExplicitSchedule(periods: tuple[int, ...])

Bases: DecisionSchedule

Decide in an explicit list of periods.

Useful for supplier calendars and irregular ordering days. Each decision then covers its own window, (next decision - decision) + lead_time.

Parameters:

Name Type Description Default
periods tuple[int, ...]

Unique integers >= 0, in any order (stored sorted).

required
Example
ExplicitSchedule(periods=(0, 3, 10))