Skip to content

perf: scale the absolute gap with the goal energy, and give it to the probe - #188

Open
andig wants to merge 1 commit into
mainfrom
perf/request-scaled-gap
Open

andig wants to merge 1 commit into
mainfrom
perf/request-scaled-gap

Conversation

@andig

@andig andig commented Oct 4, 2026

Copy link
Copy Markdown
Member

fixes #186

A fixed cent sits below the slack the c_min gate leaves in the LP relaxation whenever a vehicle's minimum power is a sizeable share of a slot. The relaxation charges below c_min on a fractional z, the integer schedule cannot, and CBC has to enumerate to prove the difference. On the three phase request of #186 that is 9 ct of slack and no proof in 110 minutes; a 2.5 ct gap proves the same schedule in 1.5 s. The analysis and the three options tried are on the issue.

Two changes. OPTIMIZER_GAP_SHARE, 0.25 % by default: the absolute gap becomes max(gap_abs, gap_share × goal energy × mean import price), where goal energy is what the batteries still need for their s_goal. A request without a goal keeps the cent. And the probe runs with that gap instead of proving to CBC's own tolerance, which alone turns the #170 request into a joint Optimal in 0.7 s where it splits today.

Measured under the production limits on the requests from #186, #170 and the one phase household of the README:

request before after
#186, 221 steps split, Feasible, 7.9 s joint, Optimal, 1.5 s, −0.1 ct
#186, 414 steps split, Feasible, 7.9 s joint, Optimal, 2.0 s, −0.2 ct
#170 split, Feasible, 5.4 s joint, Optimal, 1.9 s, same cost
one phase joint, Optimal, 1.2 s joint, Optimal, 1.0 s, same cost

A replay of the production slow-request dump, 120 requests with a goal and 120 without, before and after, follows as a comment.

🤖 Generated with Claude Code

… probe

A fixed cent sits below the slack the c_min gate leaves in the LP
relaxation whenever a vehicle's minimum power is a sizeable share of a
slot: the relaxation charges below c_min on a fractional z, the integer
schedule cannot, and CBC enumerates to prove the difference. On the
request of #186 that is 9 ct and no proof in 110 minutes, where 2.5 ct
proves the same schedule in 1.5 s.

The gap becomes max(gap_abs, gap_share of the goal energy at the mean
import price), 0.25 % by default, and the probe runs with it too instead
of proving to CBC's own tolerance.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@andig andig added the enhancement New feature or request label Oct 4, 2026
@andig

andig commented Oct 4, 2026

Copy link
Copy Markdown
Member Author

@ekkea if this is ok to do it should dramatically improve performance and reduce "feasible" solutions without giving away much. Wdyt?

@andig
andig requested a review from ekkea October 4, 2026 19:28
@andig

andig commented Oct 4, 2026

Copy link
Copy Markdown
Member Author

Replay of the production slow-request dump, 9,691 requests dumped between July and October for exhausting the limit or leaving more than a currency unit unproven. Sample of 240: all 2 October requests with a goal plus 118 random ones with a goal, and 40 October plus 80 random ones without. Each replayed on main (e8f9b2b) and on this branch under the production limits, 10 s and one thread, same machine, same CBC.

group Optimal joint path mean solve median solve
with a goal, 120 main 41 27 5.97 s 7.67 s
branch 51 39 5.39 s 7.65 s
without, 120 main 40 26 6.06 s 7.64 s
branch 53 40 5.40 s 7.36 s

Money, on the requests whose cost is money and not penalty units, 102 and 99 of the two groups: 186 identical to the cent, 7 worse, worst by 0.27 ct, 8 better. The requests without a goal keep the 1 ct gap, so their change is the probe alone: 14 more joint proofs out of 120.

Two of the better ones are not cents. On main the cost stage hit its 3 s cap on them with 27.9 € and 15.4 € still between schedule and bound and the split went on with that incumbent; the branch proves the joint objective in 1.0 and 2.0 s and returns a schedule better by that amount. One of the two is reported Optimal on main, which it is not: the label comes from the tie break MILP proving the preferences over a cost schedule that was never proven. Separate issue, noted here because the replay surfaced it.

The one request that got slower by more than a second, and the 0.21 ct it lost, is a joint solve on both sides whose continuity stage found a different equal-cost schedule; the gap did not change its path.

Nothing hit the limit on either side. Scripts and samples are in this session's scratchpad, the outputs fit a comment: bench_gap.py replays a sample against a source tree, bench_compare.py joins the two.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Three phase EV with a charge goal never proves: hosted result Feasible, uncapped CBC runs for hours

1 participant