Worked examples

Worked examples

Three real scenarios, end to end, that between them touch most of the constraint machinery described in the hard and soft references.

"I want Chemistry labs to always be 2 periods back-to-back"

Set the lesson's Duration to 2 (Creating Lessons). That's it — you don't need any bunching setting or preference for this.

Duration is a hard guarantee, not a preference: a lesson with Duration: 2 always occupies two genuinely consecutive periods on the same day, and the solver enforces (via constraint P1) that this window can never cross into the next day — a lab starting in a day's last period simply isn't a valid start slot at all, so you'll never see a lab split across a day boundary.

A common mix-up worth avoiding: Duration is for one session that is inherently N periods long. It is not the same thing as Bunching: CONSECUTIVE, which is for a lesson with Count greater than 1 whose separate repeated instances you want to land on the same day next to each other (e.g. "two independent Art lessons a week, but when they both fall on the same day, keep them adjacent" — see S6 in the soft constraints reference). If what you actually want is one uninterrupted double-period block, use Duration: 2, Count: 1, not Duration: 1, Count: 2, Bunching: CONSECUTIVE — the latter is only a soft preference for adjacency, not a guarantee, and the solver can trade it away if something else scores better.

"I want French and German electives to run at the same time, in different rooms"

Give both lessons the same Block value, e.g. P3_ELECTIVES (Creating Lessons). Everything else about the two lessons can differ freely — room, teacher, subject, even duration — only their start slot is forced to match.

This is a genuine hard constraint (H7 in the hard constraints reference), not a preference — if the two teachers involved have no period in common where both are free (check their unavailable slots, and any department meetings they belong to), generation goes INFEASIBLE straight away with a message like Block “P3_ELECTIVES” runs French (10A / French) and German (10A / German) at the same time, but there's no period when Ms Dubois and Mr Weber are both free for them, followed by what takes up each teacher's time. The same goes for a Block whose lessons are for the same class, or have the same teacher: they can never run at the same time, and generation says so. This is a good sanity check that the constraint is working as a real rule and not just a suggestion — if you ever want to confirm it's binding, try temporarily making the two teachers' availability disjoint and confirm generation fails.

Two things worth knowing before you rely on this for a whole timetable of electives:

  • If you have more than two parallel options (say, French / German / Spanish all at once), just give all three lessons the same Block value — it isn't limited to pairs.
  • If the block's members don't all have the same Count (e.g. French runs 3x/week and German only 2x/week), only the shorter count's worth of instances get synced — French's 3rd weekly instance has no German instance to pair with, and is free to land wherever the solver likes. When a generation fails, this situation is listed as a warning so it's visible rather than a silent surprise — if you want all instances synced, make sure every lesson in a block shares the same Count.

"My school has part-time teachers"

Add their non-working periods to Unavailable Periods on their Teacher record. This is H4, a hard constraint — the solver will never place any lesson that teacher is on (including as one of several co-teachers) into one of those slots, full stop.

This is a resource-level rule, not a lesson-level one — it automatically applies to every lesson that teacher is assigned to, so you set it once per teacher rather than repeating it on each of their lessons. It stacks with anything else blocking that teacher's time, most notably Department meetings (H9) — a teacher who's both part-time and a department member is unavailable for the union of both sets of slots, and there's no conflict between the two kinds of blocking; they're implemented with the same underlying mechanism.

If a part-time teacher's limited availability makes a lesson genuinely impossible to place at all (e.g. they're the only teacher for a subject and available for fewer periods than the subject needs Count times), generation will correctly go INFEASIBLE rather than silently overloading them — that's the hard constraint doing its job, and the fix is a data change (more availability, a co-teacher, or a reduced Count), not a constraint weight, since weights only affect soft constraints (see Constraint weighting).