Skip to content

Later shift usage penalty

Later shift usage penalty

settings.later_shift_usage_penalty is an optional penalty on the optimiser's raw cost. It penalises used time on later declared Shifts, so later days (or later-starting Shifts) stay emptier and new work can still fit — even if that means more driving now.

It is not a hard constraint. Time windows, capacity, Shift bounds, and unserved Jobs still win.

Omit it, set null, or set 0 to leave it off (the default). The value must be a finite number greater than or equal to zero.

The same penalty is added in every optimisation_objective (time, distance, and cost). It is not scaled by costs.hour.

The penalty is constant on the declared Shift. It does not shove stops earlier inside the same Shift.

Used time on a Shift is from that Shift's shift_start to the last stop whose arrival still falls in the Shift (including waiting after the Shift opened). An empty Shift, and a reset Shift with no Jobs (depot deadhead only), contribute 0.

Horizon is the earliest shift_start in the request. A Shift that starts one Planning Day later than that is one day late; two Planning Days later is twice the penalty, and so on.

This is not a penalty for turning a vehicle on. For that, see Active vehicle penalty. The two extras add if both are set.

{
  "settings": {
    "optimisation_objective": "time",
    "later_shift_usage_penalty": 0.02
  }
}

How to choose a value

The number is how hard you want to push work onto earlier Shifts, not a function of how many Jobs or Drivers you have. Job count and fleet size drop out if tour lengths stay similar.

In time mode, later_shift_usage_penalty = 1 means one used second on a Shift that starts one Planning Day later than the earliest shift_start costs the same as one second of driving. That is a very strong push. Typical rolling values are small.

Ask: how much extra driving will I accept to free one hour of used time on a Shift that starts one day later?

later_shift_usage_penalty Extra driving you accept for that hour
0.02 about 1.2 minutes
0.05 3 minutes
0.1 6 minutes
1.0 1 hour

Friday versus Monday is already four times the one-day penalty, so do not inflate the value just because the horizon is longer.

Start at 0.02. If later days still fill first, step toward 0.1 until leftover capacity sits where you want it. Stop if extra driving or split tours get ugly.

Retune when you change optimisation_objective. Distance and cost use the same addend in raw cost units: in distance mode 0.02 is metres, not seconds.

Do not copy values from Active vehicle penalty. That table is hundreds to thousands; this one is 0.020.1.

Single-day staggered starts

The penalty also applies without multi-shift, when Drivers in one request have different shift_starts.

Two Drivers who both start at 08:00 have lateness 0 — the penalty is off. If one starts at 08:00 and another at 14:00, only used time on the afternoon Shift is penalised (6 / 24 of a day late).

Multi-shift with mode = reset

This is the usual reason to set the field. In multi-shift reset, each Shift is its own trip, and travel (and costs.run) do not care which day a Job lands on. The solver can leave Monday thin and park work on Thursday if that tour is shorter.

Monday, Tuesday, and Wednesday at the same clock time have lateness 0, 1, and 2. Used time on Wednesday costs twice the Tuesday penalty. Unused later Shifts stay free, so the optimiser prefers to fill Monday before opening Thursday.

Multi-shift with mode = continue

In multi-shift continue, one Driver keeps a single journey across several Shifts. The penalty is still per declared Shift on that Driver, not a single Monday-to-Friday span.

A leftover on Friday is penalised as Friday used time × Friday lateness. Moving that work to Monday (lateness 0) removes the penalty.

See Multi-Shift.