Logistics · Simulation · AgenticCJ AI Center, with CJ LogisticsWrite-up October 2026 · 9 min read

Two engines for a ring-conveyor picking system

A QPS puts picking stations around a ring conveyor. Where each SKU lives and in what order boxes enter decide whether the line flows or queues. This post describes the allocation and reordering engines that now run in a logistics centre's regular operations, and lets you run a re-implementation of both.

station 1station 2station 3station 4 queue · 3 waiting inject
Boxes enter at a fixed interval and circulate. A station with a full queue is bypassed — the box goes round again. Where SKUs sit and who enters when decide how often that happens.

Decisions on two clocks

Logistics centre operations depend on order volume, worker and equipment status, task priority and bottlenecks. In a QPS, two decisions dominate throughput, and they are made on different clocks. Which SKU goes to which station is decided once per batch, when the stations are set up. In what order boxes are injected is decided again and again while the batch runs, because the floor changes. Treating them as one problem makes both slow; splitting them by decision cycle gives a batch engine and an operating engine that share a single sequencing core.

EngineWhenDecidesReturns
AllocationOnce per batchSKU → station, how many stations to openSeveral alternatives by station count, each with expected duration and man-hours
ReorderingRepeatedly during operationInjection order of the boxes not yet injectedA new sequence, with already-injected boxes fixed in place

Allocation: put together what is picked together

A box visits every station that holds one of its SKUs, so the cost of an allocation is mostly how many stations each box must visit and how evenly the picking load spreads. The engine first measures which SKUs are ordered together — a Jaccard overlap weighted by how often the pair co-occurs — and then builds the allocation in stages rather than solving one monolithic model.

  1. Anchors. One seed SKU per station, chosen to be strongly connected to others but weakly connected to the other anchors, so the stations start apart.
  2. Five rounds of knapsack. Stations are filled to 20%, 40% … 100% of their cells in turn. For one station in one round, an exact two-dimensional 0/1 knapsack picks the SKUs that maximize load + α · affinity within the remaining cells and a load target — so good SKUs are not swallowed by whichever station is filled first.
  3. Polish. Greedy placement of leftovers, affinity-driven moves under a load cap, and 1:1 swaps between the heaviest and lightest stations.

A dedicated station type (for items that must be handled separately) is respected at every stage: ordinary SKUs never enter it. The engine then repeats the whole build for one more station, and one more, and returns the alternatives — the floor chooses how many stations to staff, with the predicted duration and man-hours next to each option.

Live model · synthetic batch, computed on a Python server (2–8 s)Open full demo ↗

Both rings replay the simulation of the same batch on the same SKU placement; only the injection order differs. Watch queues build at stations and boxes bypass when a queue is full. Switch the station count to see makespan fall and then rise again when a low-load dedicated station is opened; "New batch" solves a fresh batch on the server. The full control panel adds the allocation stages, Gantt and mid-batch re-sequencing.

Injection order: simulate, then search

The order is a permutation of boxes on fixed injection slots. Each candidate order is scored by a next-event simulation of the ring: a box arrives at a station; if it has nothing to pick there it passes in three seconds; if the queue has room it waits for the single worker, who needs ten seconds per distinct SKU; if the queue is full it is bypassed and comes back after a full lap. The objective is the time the last box finishes plus the number of bypasses.

The search is deliberately plain. A few hundred random permutations seed a best-so-far; then a Tabu Search repeatedly samples position-pair swaps, simulates each, moves to the best one even if it is worse, and forbids reversing recent swaps. The final sequence is not the permutation itself but the order in which boxes first start picking when that permutation is simulated — the number the floor actually needs. During operation the boxes already injected form a fixed prefix and only the tail is re-searched, batch after batch.

One deliberate compromise sits on top: a post-process that groups boxes of the same box type into contiguous runs, because excessive alternation between box types slows injection on the floor. It does not re-simulate, so it can give back a little of the makespan it was handed. The live model shows both numbers so the trade-off is visible.

fixed prefix+ boxes to sequence random seedsbest of ≤ 1,000 Tabu Searchswap · simulate · tenure 50 first-start orderre-simulate best box-type runsfloor-friendly every candidate = one discrete-event simulation of the ring (queue 5 · 10 s per SKU · 3 s per hop · bypass)
Up to roughly 49,000 simulations per call at production budgets; the demo runs a reduced budget so a call returns in seconds.

In operation

+20%productivity improvement, field-validated at the centre
Deployedinto regular operations, with a multi-centre rollout
2engines on one simulation core

The engines run behind an asynchronous API: a request is acknowledged immediately, the optimization runs in the background, and the result is delivered back to the operating system by callback. Candidate evaluation is compiled and parallelized so a reorder call fits the floor's response window. Alongside the engines, an LLM-agent "AI Floor Supervisor" interprets real-time conditions, watches workload and bottleneck signals, and recommends allocation and priority adjustments to field managers.

The result showed that AI can support real-time logistics decisions rather than remain an offline analysis tool, and it supported the rollout to a second centre and the wider logistics AI roadmap, including cart picking optimization.

Limitations

About the demo and confidentiality

The orders, SKUs, stations and box types in the embedded model are generated from a seed. No equipment, centre, system or table names appear, and the engines shown are a re-implementation of the decision logic validated against the original on random instances — not the production code.

Taehee Lee · Data Scientist / Applied AI Scientist, CJ AI CenterProblem definition, engine design, field validation. Demo re-implemented on synthetic data for this site.