Skip to content
SkyRosterBook a working session

The engine

A constraint solver, not a machine-learning model

SkyRoster's rostering engine decides who works which shift by search, not by pattern-matching against past rosters. It builds a first pass fast, then spends a time budget you set improving it against every rule your organisation has switched on, scored in tiers so a safety rule always outweighs a preference. That is the whole mechanism. This page explains it plainly, including the part most vendors leave out: run it twice on the same month and you can get two different, equally good rosters back.

The mechanism

Two phases: build something feasible, then spend the time budget improving it

Phase one · Construction

Get to a feasible first draft, fast

The solver places shifts one at a time using a fast, greedy heuristic: given the demand and the people available, fill the slots that are hardest to fill first. The result is rarely good. It is meant to be a starting point a search can improve on, not a finished roster.

Phase two · Local search

Improve it, move by move, until time runs out

From that first draft, the solver repeatedly tries a small change, swap two people's shifts, move an assignment, and keeps the change if it improves the score. It keeps doing this for as long as you let it, or until it stops finding improvements for a while, at which point it hands back its best roster.

You set the time budget, not us: shorten it for a quick draft while you are still shaping demand, lengthen it for the pass you intend to publish. We do not print a solve-time figure on this site, because the honest answer is “however long you gave it,” not a number that would read as a benchmark we have not actually measured at your scale.

Scoring

Hard rules, soft rules, and the weights in between

Every candidate roster gets a score with two parts. A hard violation, someone assigned without the qualification the position requires, for instance, dominates the score outright: the solver will accept a worse soft score to remove a hard one every time. Soft violations, an uneven spread of weekends, a broken preference, are weighed and summed, and the solver looks for the arrangement that minimises that sum without breaking a hard rule.

Hard only

39

Never broken while enabled, mostly the data-integrity guards no organisation would want to turn off.

Soft only

20

Weighed and minimised, never a reason on its own to leave a shift unfilled.

Either, by your setting

74

The largest group: whether it is a hard stop or a weighted preference is a setting your organisation chose, not a difference in code.

This is the reason “minimum rest time” can be a non-negotiable stop for one ANSP and a strongly weighted preference for another, running the exact same product. See configuration for how a threshold and a weight are set, and the full rule catalogue for all 133 rules across the three engines.verified

What optimal means

Best found in the time you gave it, not best possible in the abstract

“Optimal” on a roster this size does not mean a mathematical proof that no better arrangement exists anywhere in the search space. That space is too large to exhaust. It means the best roster the search found against your active rule configuration, within the time budget you gave it. Two honest consequences follow, and both are worth stating plainly rather than leaving a buyer to assume otherwise.

A score is only meaningful next to another score

A soft score on its own tells you almost nothing. What it is for is comparison: this month's roster against last month's, this configuration against a proposed change, this scenario against that one. Judge a number by what it improved on, not by its size in isolation.

More time can find a better roster, not a different truth

Lengthening the time budget lets the search look further and can lower the soft score further. It will not change which rules are hard, and it will not fix a demand or a staffing shape that simply cannot satisfy every hard rule at once. No amount of searching invents people who do not exist.

The honest part

Run the same month twice, get two different rosters of the same score

Give the solver the same demand, the same staff and the same rules twice, and the concrete placements it hands back can differ between the two runs, even though the score usually does not. This is not a bug and not the system behaving unpredictably. It is a property of the method.

Local search over a roster of any real size has many arrangements that tie at, or near, the best score the search can find in its time budget. Swap two interchangeable people on otherwise-identical shifts and the score does not move at all. Which of those tied arrangements you land on depends on the order the search happened to try its moves in, not on anything the system remembers from a previous run. There is no memory between solves to make one run's placements resemble another's. Each solve starts fresh from the construction phase.

Bring a month that fought you.

A working session runs your own demand, your own staff and your own rules through the solver, so you see the mechanism on your own data rather than a demo tenant's.