Skip to main content
Real-time re-optimization covers replacing the whole plan on disruption. This page covers the finer-grained controls: locking part of a resource’s tour in place while the engine re-plans the rest, and reserving a stop for exactly one resource without making it mandatory.

Locking a sequence: mode × assignment status

state is set per resource and works on two levels: state.mode applies to the resource as a whole, while status applies to each individual entry in state.assignments (a stop, a break, or the tour’s begin or end).
  • status: "assigned" — the entry is assigned to this resource, but its position in the sequence isn’t imposed: the engine sequences the resource’s assigned entries according to the plan’s objectives.
  • status: "fixed" (the default) — the entry is taken as given: its position in the sequence, and its times, aren’t challenged.
  • mode: "free" (the default) — the engine can add more stops to this resource’s tour.
  • mode: "fixed" — the resource’s tour is limited to its assigned entries. The engine can’t add any more stops.
The two combine as follows:

Live supervision as a tour progresses

Reflect a driver’s real progress with successive PUT /plans/{planId} calls: a begin assignment with the real departureTime, then stop assignments filled in with arrivalTime/beginTime/departureTime as they actually happen, a break inserted dynamically if needed. Keep mode: "free" so the engine can still plan what comes after, and give every pinned assignment status: "fixed". Each of these calls carries the complete plan; the following excerpt only shows the resources entry being updated:
For a pinned time to be kept as given rather than re-planned by the optimization, every assignment before it in the sequence must also carry its times, and those times must be chronologically consistent: each entry’s times can’t be earlier than the previous entry’s. In practice, fill in assignments in the order the driver actually completes them, starting from begin, without leaving an earlier entry’s times blank.

Pinning a stop to exactly one resource (pattern “Isolate”)

forbiddenAssignment (see Real-time re-optimization) excludes a resource/stop pairing. There’s no single dedicated field for the opposite — reserving a stop for one resource — but three mechanisms get you there, from strictest to softest:
  • state.assignments — pin the stop directly onto the resource’s tour, as described in the first section of this page. The only one of the three that the engine keeps exactly as given.
  • skills/requiredSkills (pattern “Isolate”) — give the resource a skills entry derived from its own id (for example skills: ["resource-12"]) and require it on the targeted order (requiredSkills: ["resource-12"]). No other resource can then serve the stop.
  • preferredStopTags — tag the stop, list that tag in the resource’s preferredStopTags, and include maximizePreferredStops in objectives. A soft preference: another resource can still take the stop when that serves a higher-priority objective better.
Pinning a stop to a resource through requiredSkills doesn’t guarantee that the stop is planned: it only restricts which resource can serve it. The engine can still leave the stop unplanned if the assignment degrades a higher-priority objective. To keep the stop on that resource’s tour whatever the objectives, use state.assignments instead.

See also