All checks were successful
Build, test and publish / verify (push) Successful in 6m5s
146 lines
8.2 KiB
Markdown
146 lines
8.2 KiB
Markdown
# S18 — Scheduling dance groups across a show
|
|
|
|
Status: IMPLEMENTED
|
|
|
|
As a dance school manager,
|
|
I want OR-Tools to schedule groups and order performances using participation,
|
|
changing-time and variety rules,
|
|
so that the complete show is manageable for dancers and enjoyable for audiences.
|
|
|
|
Refinement confirmed by the maintainer on 2026-11-03. This specification records
|
|
the agreed design. Implementation and validation are complete and ready for review.
|
|
See [validation evidence](../../docs/s18-validation.md) and
|
|
[the applied scheduling rules](../../show-scheduling-rules.md).
|
|
|
|
## Show scope and configuration
|
|
|
|
- A show consists of dayparts and can span multiple dates, typically two days.
|
|
All counts below apply across the entire show, not separately per date.
|
|
- Each show has one configurable integer `preferredDayParts`, between 1 and the number of
|
|
dayparts inclusive. Its default is 2, or 1 for a one-daypart show.
|
|
- This replaces the existing configurable appearance counts per group type.
|
|
- A show without dayparts can be stored but cannot be scheduled.
|
|
- If reducing the number of dayparts makes `preferredDayParts` invalid, require the user to
|
|
correct it before scheduling again; do not silently change it.
|
|
- Groups without dancers are excluded from scheduling and from all performance
|
|
counts and showcase-position requirements.
|
|
|
|
## Required group appearances
|
|
|
|
- Each nonempty REGULAR, SELECTION and PRE_EDUCATION group performs in exactly
|
|
`preferredDayParts` distinct dayparts, once within each selected daypart.
|
|
- Each nonempty PRE_SCHOOLER group performs exactly once in the complete show,
|
|
regardless of `preferredDayParts`. At most two such groups are expected. They can be assigned
|
|
freely to dayparts; no additional placement restriction applies.
|
|
- Each nonempty SHOW_CASE group performs exactly once in every daypart.
|
|
- With at least two showcase groups, each daypart starts with one showcase and
|
|
ends with another. Additional showcases can appear anywhere between them.
|
|
Opening and closing groups may differ between dayparts.
|
|
- With exactly one showcase group, it appears either first or last in each
|
|
daypart; the planner chooses. It does not perform twice in that daypart.
|
|
- With no showcase groups, there is no showcase-position requirement.
|
|
|
|
## Dancer participation and coaches
|
|
|
|
- A dancer without a showcase membership performs in at most `preferredDayParts` distinct
|
|
dayparts across the complete show. This is a hard constraint.
|
|
- A showcase participant necessarily performs in all dayparts. Their other
|
|
group performances may span more than `preferredDayParts` dayparts, but this is undesirable.
|
|
- For each non-coach showcase participant, count the distinct dayparts in which
|
|
they perform outside showcases. Their excess is `max(0, count - preferredDayParts)`.
|
|
Minimize the sum of these excesses as the first optimization priority.
|
|
- A person dancing in several groups must use the same dancer registration in
|
|
every group, including when accompanying preschoolers. Up to five group
|
|
memberships per dancer are expected.
|
|
- Explicitly link a coach registration to the corresponding dancer registration;
|
|
never infer identity from matching names. Support maintaining this link.
|
|
- Coaches are available in all dayparts and are excluded from both the hard
|
|
dancer limit and the excess penalty, including coaches in showcases.
|
|
- Being assigned as a group's coach does not automatically mean performing in
|
|
that group. Actual performances are determined by dancer membership only.
|
|
Coach availability never increases a group's required appearances.
|
|
- Dancing coaches remain subject to changing-time rules and contribute to the
|
|
group's average age just like other dancing members.
|
|
|
|
## Changing time and feasibility
|
|
|
|
- Between any two performances involving the same dancer within a daypart,
|
|
there must be at least two intervening performances not involving that dancer.
|
|
- This is mandatory for everyone, including coaches and showcase participants.
|
|
- The rule restarts at each daypart boundary. Assume enough changing time
|
|
between dayparts, including on the same date.
|
|
- All hard constraints apply together, even for unusual membership combinations
|
|
such as a person dancing in both preschool and ordinary groups. Do not relax
|
|
a rule to obtain a result.
|
|
|
|
## Balance and optimization priorities
|
|
|
|
- Count all scheduled performances, including preschool and showcase groups.
|
|
- The difference between the largest and smallest daypart performance counts
|
|
must not exceed two. This is a hard constraint.
|
|
- Prefer a difference of zero. Preschool groups are an expected cause of
|
|
differences but have no special exemption or exclusive right to cause them.
|
|
- Optimize valid schedules in this strict priority order:
|
|
1. Minimize the total excess for non-coach showcase participants defined above.
|
|
2. Minimize the difference between largest and smallest daypart counts.
|
|
3. Improve style and age variety between consecutive performances within
|
|
each daypart.
|
|
- A lower priority must not worsen a higher priority. Showcases participate in
|
|
variety scoring as well.
|
|
|
|
## Variety scoring
|
|
|
|
- For adjacent groups, the style penalty is the number of shared styles divided
|
|
by the number of distinct styles in their combined style sets. No shared
|
|
styles gives zero penalty; two empty style sets also give zero penalty.
|
|
- Compute dancer ages on the first date of the show. All dancers in a group,
|
|
including dancing coaches, contribute equally to its average age.
|
|
- The age penalty decreases linearly from 1 for equal average ages to 0 for a
|
|
difference of five years; differences greater than five years also score 0.
|
|
Equivalently: `max(0, 1 - abs(meanAgeA - meanAgeB) / 5)`.
|
|
- Style and age penalties have equal weight. Minimize their combined penalties
|
|
over adjacent performances. Empty groups have already been excluded.
|
|
|
|
## Solver execution and failure
|
|
|
|
- Retain a maximum solver runtime of thirty minutes.
|
|
- Accept a feasible result without proof of optimality, provided every hard
|
|
constraint holds. Distinguish feasibility from proven optimality.
|
|
- If no valid result is found, preserve the existing assignments and order.
|
|
- Explain whether infeasibility was proven or the time limit expired without
|
|
a valid result; do not report a timeout as proof of infeasibility.
|
|
- Retain existing protections against concurrent scheduling and applying stale
|
|
results after relevant data changes.
|
|
|
|
## Manual editing and schedule lifecycle
|
|
|
|
- Add UI and API support for moving performances between dayparts and changing
|
|
their order. Partial or temporarily invalid assignments can be saved as drafts.
|
|
- Distinguish draft and final schedules explicitly. Display concrete violations
|
|
for invalid drafts; do not present them as valid final schedules.
|
|
- Add an explicit finalization action that checks all hard rules and permits
|
|
finalization only when they all pass. Optimization preferences do not block it.
|
|
- Automatically generated valid schedules also start as drafts for manager review.
|
|
- Manual changes to a final schedule return it to draft. Changes to relevant
|
|
dancer memberships, coach identity links or show settings likewise invalidate
|
|
final status when they affect scheduling rules.
|
|
- Treat existing schedules as drafts when introducing this lifecycle.
|
|
- JSON import preserves assignments and order but makes imported schedules
|
|
drafts and validates them against the new rules.
|
|
- JSON export remains available for drafts and finals and preserves status.
|
|
Import still produces a draft even when the exported status was final.
|
|
- Include the new configuration and coach identity information in persistence
|
|
and school JSON round trips so scheduling semantics survive saving and import.
|
|
|
|
## Documentation and validation
|
|
|
|
- Provide `show-scheduling-rules.md` describing the rules applied by OR-Tools in
|
|
plain English, including hard constraints, exceptions, optimization priorities,
|
|
scoring, cross-date scope and failure behavior.
|
|
- Validate automatic results and finalization using the same agreed rules.
|
|
- Verification must cover ordinary, preschool and showcase appearances; coach
|
|
identity and exemptions; overlapping memberships; changing gaps; balance;
|
|
optimization priority and scoring; multi-date shows; empty groups; invalid
|
|
configuration; infeasible and timed-out runs; manual drafts/finalization; and
|
|
persistence/import/export of the new information.
|