An AI scientist built a better factory scheduler
Built with Sagent and Trackinizer, the program beat an expert-designed scheduling solver on 29 of 30 fresh synthetic problems.
We wanted an AI scientist to produce a program we could keep using after the research session ended. We chose factory scheduling: deciding when jobs should run on shared machines so that high-priority jobs finish on time. Using Sagent and Trackinizer, the AI scientist developed a C++ solver. We froze its code and tested it on thirty new synthetic problems against EGRASP, an expert-designed solver that achieved ten best-known results on standard scheduling benchmarks.
The final test, instance by instance
Deadline multipliers 3/2, 7/4 and 2 allow 1.5×, 1.75× or 2× a job’s total processing time after release (rounded up); smaller means tighter deadlines. “Uniform” draws weights uniformly from 1–10; “priority” gives six jobs weight 10 and the other twenty-four weight 1.
How the comparison is calculated
Each job contributes its priority multiplied by its time late; on-time jobs contribute zero. Each bar compares the programs' mean penalties over three runs on one fresh problem. We divide the difference by the larger penalty (or 1, if both are smaller):
Normalized advantage = (EGRASP mean − candidate mean) / max(EGRASP mean, candidate mean, 1).
Averaging these 30 percentages gives 9.66%. This was a registered secondary statistic. It gives each problem equal weight and does not measure a reduction in the combined penalty across all problems, factory completion time or real-world costs.
The registered primary test scored each of the nine cross-program run pairings within a problem +1 for a win, −1 for a loss and 0 for a tie. The candidate won 260 of 270 pairings, yielding a mean score of +0.926 (95% interval: +0.793 to +1.000). These pairings reuse the 180 executions; the interval resamples whole problems. Frozen analysis and instance results.
The finished program takes a factory problem as input and searches for a schedule. It needs no language model at runtime. The AI scientist’s work was to investigate methods, write the solver and improve it through experiments; our work was to define the task, build the evaluation process and check what the results meant.
What the factory needs
The starting task, from FrontierOR, has thirty jobs moving through ten machines. Each job follows a prescribed sequence, and each machine can do only one operation at a time. Each late job contributes its priority weight multiplied by how late it finishes; on-time jobs contribute zero. The sum is total weighted tardiness, the score we want to minimize.
The synthetic inputs use time units without specifying minutes or hours. Weights are dimensionless priorities, so the score is in weighted time units. A job with priority 3 finishing 4 time units late contributes 12. Lower is better; zero means every job finished on time.
The AI scientist developed a solver that changes the order of operations on each machine. Moving one operation forward can bring other work forward, delay it, or create an impossible cycle of dependencies. The program searches legal moves using established critical-path and tabu-search ideas: concentrate on consequential operations, discourage immediate reversals, and restart from promising schedules when progress stalls.
Same work, different machine order
These are known scheduling techniques. The result was a working implementation adapted to this task, with experiments to establish where it helped.
How the AI scientist changed the program
We supplied the formulation, public inputs and evaluation requirements. The AI scientist investigated approaches and wrote solver variants.
For this study we built a custom loop using Sagent, a universal LLM harness for customizing agent workflows across hosted providers and local models. Its pure-Python API lets you compose loops or graphs with your own tools and evaluation steps.
Within the loop, the AI scientist could save a solver, evaluate it and record what to try next. Each saved version had a source hash; each evaluation retained its schedule and logs. FrontierOR’s checker and a separate validator checked feasibility and recalculated the penalty. Trackinizer linked the versions, experiments and conclusions so the next decision could refer to the evidence behind it. We extended the Sagent loop with one rule for this study: record a conclusion before starting the next experiment.
Watch the research workflow in Trackinizer
The first solver spent effort rebuilding machine dependencies for each proposed move and restarted from a narrow range of schedules. The recorded decision shows the AI scientist addressing both problems in V2: updating only affected links, reusing calculations, cutting off unpromising evaluations and restarting from a more varied set of schedules found during the search. With both versions given 300 seconds, V2 achieved a lower penalty on all five familiar large inputs.
That first result left a question: would the improvement survive a different random seed? V2 still trailed FrontierOR’s saved Gurobi solution on one input, so the recorded conclusion called for another comparison before spending more compute. The loop repeated the five tests with V2’s code unchanged and a new seed; V2 again beat V1 on all five. This gave a reason to extend the time budget and test a different scheduling method.
The next approach combined constraint programming with large-neighborhood search. It offered a different way to construct schedules, but its comparison with V2 exposed a tradeoff: on one development case, it finished the workload at simulated time 2,037 rather than 2,081, while incurring a higher lateness penalty, 31,063 rather than 28,661. V2’s schedule served the stated objective better even though the last job finished later. Comparing both measures made that distinction visible: the factory needed to limit priority-weighted lateness, which could require accepting a later overall finish.
See the saved schedules and the development comparison
Both programs ran on the public large_1 case with seed zero and a requested
1,200-second budget. The completion times 2,037 and 2,081 use simulated
input time units; the 1,200-second limit is computation time.
Finishing sooner can still leave a higher penalty
large_1,
seed 0, with a requested 1,200-second computation budget.
Schedule records ·
Original figure.
In the earlier 300-second V1–V2 comparison on the same large_1 input, total
weighted tardiness fell from 31,807 to 30,579: a reduction of 1,228 weighted
time units, or about 3.9%. That is a lower benchmark lateness score, not measured
hours or dollars saved. Several changes went into V2 together, so this
experiment cannot identify which change contributed most. Nor does it isolate
the effect of Trackinizer or Sagent from the rest of the workflow.
Would it work on new inputs?
The revised solver eventually beat FrontierOR’s saved Gurobi solution values on all five public large inputs under both tested seeds. Those were feasible recorded schedules, not proven optima, and they had influenced development. We wanted to know whether the program could handle unfamiliar problems.
We obtained the scheduling researchers’ historical EGRASP executable and built the input conversion and independent checks needed for a comparison. An early test was uninformative: both programs achieved zero tardiness on eight of twelve synthetic problems. We tightened deadlines in the development generator to make the test more demanding.
We then froze V2 – the same source used in the development comparison – along with the generator settings, evaluation procedure and analysis before drawing thirty fresh problems. Each program ran three times per problem in the same emulated Linux environment, with one CPU quota, 512 MiB of memory and a 300-second external deadline. All 180 executions produced valid schedules. The opening chart compares each program’s three-run mean penalty.
This demonstrates reuse on thirty new inputs from the tested distribution. The comparison uses a historical executable released in 2014, associated with Bierwirth and Kuhpfahl’s 2017 paper; it does not establish a new scheduling state of the art. We did not give that baseline the same development effort, and the shared host was not fully isolated.
From one problem to the next
If your problem has the same scheduling formulation, you can start with the frozen C++ solver and test it against your own baseline. Changing the objective or constraints may require changing the program.
For a different problem, reuse the research process: give the scientist a precise objective, representative inputs and an evaluator that checks both validity and quality. You will need to adapt the input format, execution runner and validators to your domain. Preserve each candidate program with its results, then reserve fresh inputs for the final comparison. An operations specialist supplies the constraints that make a schedule usable; the same division of work can apply to a compiler optimization or a circuit design if you can run and independently check the candidate.
Beyond scheduling: what the delivery and cutting studies showed
The broader question led us to a separate campaign across 180 FrontierOR tasks, each needing its own solver. Of 180 selected outputs, 177 passed the feasibility checker. Review retained four gains over the references and a fifth, marginal result with an unresolved reference label. Those results cover one public small input per task; they do not establish the scheduling study’s reuse on fresh inputs. Two examples show what a researcher can learn from the resulting programs:
Delivery: a legal plan the reference could not express
One task required thirty pickup-and-delivery requests, with time windows, capacity limits and last-in-first-out loading. The candidate served them with ten trucks; the released reference used thirty. Its code required every modeled truck to operate even though the problem allowed unused vehicles. At 10,000 cost units per operating truck, avoiding twenty departures accounted for about 99.4% of the improvement. The candidate found a legal plan outside the reference implementation’s restricted search. Ten trucks suffice for this input; the minimum fleet is unknown.
Cutting: a solution with a proof of optimality
Another task asked for guillotine cuts on a 40 × 40 sheet. The candidate produced 400 pieces of size 1 × 4, using the entire sheet, compared with the reference’s value of 1,592. Here each piece was worth its area. The candidate’s value of 1,600 therefore reached an upper bound: no plan could recover more area than the sheet contained. This instance had both a checked construction and a proof of optimality.
These are modeled benchmark outcomes; savings in operating businesses have not been measured.
For a problem you can specify and independently evaluate, an AI scientist can help build the specialist program you need. The starting materials are open: Sagent, Trackinizer, and our solver code, inputs, results and validation records. As in the Craftax study, the research produces a system that can run on its own. You set the objective and judge whether the evidence is sufficient.
To reproduce or adapt the supply-chain study, reach out to Venkateshwar Reddy Jambula.
Source records
- FrontierOR: task formulations, public inputs, references and feasibility checks.
- Final comparison source: input adapter, generator, runner and validators.
- Recorded V1-to-V2 decision: solver changes, repeated comparisons and the next experiment.
- Sagent and Trackinizer: harness and evidence store.
- Broader campaign records: the separate delivery, cutting and other optimization studies.