Constraint weighting (0-100%)

Constraint weighting (0–100%)

The Constraint Weights tab on the Constraints page has one 0–100 input per soft constraint (S1 through S11 — see the soft constraints reference for what each one means). This page explains exactly what that number does.

What the number means

A weight is a percentage of that constraint's normal strength. 100 is the default and means "full strength, exactly as if weighting didn't exist" — every soft constraint had one fixed, hardcoded penalty before per-constraint weighting was added, and a weight of 100 reproduces that original value exactly. Turning a constraint's weight down scales its penalty proportionally:

  • 50% costs half as much per violation as the default.
  • 0% costs nothing at all — the constraint is fully, silently disabled, without needing a separate on/off switch.
  • Anywhere in between scales linearly.

You can also raise a weight above its natural relative strength by pushing it toward 100 while leaving others lower — weighting is always relative, since the solver is balancing the sum of every active penalty against every other one. There's no way to push a single constraint's weight past 100 (making it more important than its default) — 100 is the ceiling, matching FET's own 0–100% weighting model.

A weight of 0 vs. an actual toggle

Some soft constraints already have their own dedicated on/off switch for unrelated reasons — Room Stability (S4) and Student Gap Minimization (S5) each have a Switch on the Teacher Welfare / Student Constraints tabs, and S3/S6/S7 are naturally "off" for any lesson that doesn't use SPREAD/CONSECUTIVE bunching or preferred slots at all. Setting a constraint's weight to 0% achieves the same practical effect (it contributes nothing to the objective) through a completely different mechanism — it doesn't touch the underlying switch or the lesson data, it just zeroes out the penalty. Turning S4's weight to 0% and turning the Room Stability switch off both result in "room changes are never penalized," but only the switch also skips building the constraint's internal tracking variables in the first place — for a large school this can matter slightly for solve time, though never for the actual result.

Only soft constraints have a weight

Hard constraints (H1–H9, P1 — see the hard constraints reference) have no weight field anywhere, and never will: a hard constraint is either satisfiable by your data or it isn't. There's no "80% honor this teacher's unavailability" — weighting is exclusively a soft-constraint concept, since only soft constraints have a penalty to scale in the first place.

Rounding — a real gotcha for low-cost constraints

The solver's underlying engine requires whole-number costs, so a weighted penalty is always rounded to the nearest integer, not kept as a precise fraction. For a constraint with a large base cost this is invisible (a 100-point-per-violation constraint at 33% still rounds to 33, close enough to a third). But for one of the smaller constraints — Student Gap Minimization (S5) has a base cost of only 5 — a weight anywhere from 1% to 9% rounds down to 0, which fully disables the constraint well before you'd expect from the number you typed. If you want a constraint to have some effect but less than full strength, keep the weight comfortably above the point where base × weight ÷ 100 rounds to zero for that specific constraint's base cost (see the table on the soft constraints reference page for each one's base cost).

Where changes take effect

Weights are saved immediately when you click "Save Changes" on the Constraints page, but they only affect future generations — a saved or in-progress timetable was built with whatever weights were active at the time it was generated, and changing a weight afterward doesn't retroactively change anything already on screen. Regenerate (or use "Lock & Re-solve" on a saved timetable) to see a weight change reflected.