District recruitment examination · 4,200 candidates · 14 centres · one shift
The allocation is the picture. Nothing is summarised into a chart beside it. Each cell is five real candidates in a real hall, and a column that goes over its seat line is visibly over it.
A greedy first pass that seats the most constrained candidates first. A declared access need plus a home-block exclusion can leave very few legal seats, and placing those last is exactly how an access requirement gets quietly dropped. Then repeated pair swaps that are accepted only if the journey gets shorter, so the answer never gets worse and the run can be stopped at any point and used.
Three hard, two soft. A soft rule is minimised; a hard rule is never traded. Switch one off to see what it was holding up.
Why this method and not an optimal one. This is a greedy pass plus improving swaps. It is not the best possible allocation and does not claim to be. It is explainable, it is fast, it never issues an allocation that breaks a hard rule, and every step can be replayed to a candidate standing in a corridor asking why they were sent to Jatni. An optimal solver whose answer cannot be explained is worth less to an examinations controller than a good one whose answer can. The compliance figures are recomputed from the final allocation rather than taken from the algorithm. A solver that reports its own compliance is not a check.