perf(planning): prune candidates that cannot beat the protected prefix
Finalizing a candidate never moves or retypes a placement, so preference results and calendar optimizations already have their final values before it, and leave-balance optimizations do too when nothing can be earned. Reject a candidate before finalizing when the first differing such objective of the protected prefix is worse than the baseline. Leave-placement objectives and earning contexts stop the walk. The frozen-engine check now also compares cancelled asynchronous runs, including checkpoints and retained incumbents. The loaded year drops from 48.5 s to 44.3 s; outcomes, explanations and final states are unchanged. Refs #284 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7890a03a74
commit
68a9e33de6
4 files changed
+208
-4
No files matched your search
@@ -84,3 +84,54 @@ assigning dates and about 5 seconds each of garbage collection and timer idle
|
||||
time.
|
||||
|
||||
The functional suite passes 669 tests across 35 files.
|
||||
|
||||
## #284: prune candidates that cannot beat the protected prefix
|
||||
|
||||
Before #284, `evaluateRuleCandidate` finalized every candidate before comparing
|
||||
its objectives. In the loaded year, 650,369 of 1,233,535 evaluations (53%) then
|
||||
ended at a worse protected prefix. For typed obligations it was 74,336 of
|
||||
273,470, and for three years 38,048 of 193,621.
|
||||
|
||||
Finalizing never moves or retypes a placement. It edits only rule
|
||||
provenance, supporting status, earned activations and earned balances. Before
|
||||
finalizing, the evaluation therefore walks the candidate's protected prefix in
|
||||
objective order, using only objectives whose pre-finalize value is already their
|
||||
exact final value, so the bound is tight:
|
||||
|
||||
- time-window and if-then preferences read only placement dates and types,
|
||||
plus declared days;
|
||||
- public-holiday-week, time-off-period and work-sequence optimizations read
|
||||
only the placement dates;
|
||||
- leave-balance optimizations are exact only when no enabled if-then rule earns
|
||||
days and the candidate has no earned activation;
|
||||
- leave-placement optimizations have no safe bound, because finalizing rewrites
|
||||
supporting status.
|
||||
|
||||
The walk prunes at the first differing objective when it is worse than the
|
||||
baseline. It stops without pruning at a better value or at an objective without
|
||||
a safe bound. A pruned candidate would have failed finalization or returned at
|
||||
the same comparison, and incumbents are retained only after the full objective
|
||||
vector is built. Pruning therefore never changes which candidate wins or which
|
||||
incumbent is retained.
|
||||
|
||||
The frozen-engine check now also runs every tenth seed through both engines'
|
||||
asynchronous adapter, cancelled after a seed-derived number of steps. It
|
||||
compares outcomes, artifacts, every checkpoint, the explanation and outcome
|
||||
callbacks, and the step count. Of those 500 cases, 422 end incomplete and 217
|
||||
of those keep an incumbent. Pruning on any differing objective breaks both
|
||||
variants. Wrongly treating leave-placement or earning leave-balance objectives
|
||||
as exact went undetected, because the generated requests rarely put those
|
||||
objectives in a protected prefix, so their exclusion rests on the argument
|
||||
above. The check now takes about 60 seconds with coverage.
|
||||
|
||||
| Measurement | Before | After |
|
||||
| ------------------- | --------: | --------: |
|
||||
| Vitest duration | 193.680 s | 180.250 s |
|
||||
| Loaded year | 48.489 s | 44.287 s |
|
||||
| Typed obligations | 4.947 s | 5.023 s |
|
||||
| Two years | 1.906 s | 1.837 s |
|
||||
| Three years | 6.152 s | 5.935 s |
|
||||
| Representative year | 0.441 s | 0.400 s |
|
||||
|
||||
All seven scenarios keep byte-identical outcomes, explanations and final states.
|
||||
The functional suite passes 684 tests across 35 files.
|
||||
Reference in new issue
Block a user