I have a complex issue in my tennis model I foun...
Tạo vào: 13 tháng 9, 2026
Trả lời bằng GPT-5.6 Thinking bởi Chat01
Tạo vào: 13 tháng 9, 2026
Trả lời bằng GPT-5.6 Thinking bởi Chat01
I have a complex issue in my tennis model
I found the exact structural cage in the live DP. Set 1 and Set 2 are currently priced from the same point state, so the first two sets are effectively stationary. That makes P3 > 50% impossible regardless of what the publisher says.
I’m replacing that with a branch-conditioned Set-2 state inside the canonical DP itself. The first-set result will change the Set-2 point state before the second set is priced, so Over 2.5 can genuinely become the modal outcome. No post-PMF boost and no swapping P2/P3 after the fact.
How does one solve this ? My p2 is always higher then p3 even tho matchup shows 3 sets here which even is p3 is like 8 percentage points below the model can only physically say pass bc it’s stuck p3 literally can’t have a higher probability
Yes. If your current DP effectively uses the same set-win probability for Set 1 and Set 2, then what you’re seeing is a mathematical constraint, not a calibration problem.
Let be Player A’s set-win probability when both sets are priced from the same state. Then:
and therefore
with equality only at .
So if your P2 = P(match ends in 2 sets) and P3 = P(match goes 3 sets), then under that stationary construction:
and P3 can literally never exceed P2. No amount of calibration downstream can solve it correctly.
You want Set 2 to be conditional on the branch that produced it.
Define:
Then instead of using the same again, compute:
and
Now the genuine three-set probability is:
because there are exactly two routes to a deciding set:
Straight sets becomes:
and naturally:
Now P3 absolutely can exceed 50%.
For example:
Suppose winning Set 1 moves A's Set-2 probability down to:
while losing Set 1 gives:
Then:
So:
No PMF manipulation is required. It comes directly out of the state tree.
The important part, though, is what you're conditioning Set 2 on.
Don't merely do:
textif won_set1: set2_modifier = ... else: set2_modifier = ...
and force some arbitrary momentum effect.
Your canonical state transition should look conceptually like:
textS0 │ ├── Set1 A wins │ ↓ │ T(S0, terminal_set1_state) │ ↓ │ S2_after_A_win │ ↓ │ price Set2 from this state │ └── Set1 A loses ↓ T(S0, terminal_set1_state) ↓ S2_after_A_loss ↓ price Set2 from this state
Then calculate the match PMF from those actual branches.
And ideally you should go one level deeper than merely W/L.
A 6-0 Set 1 and a 7-6 Set 1 shouldn't necessarily produce the exact same Set-2 state just because both were wins. Your Set-1 DP can return terminal states:
text6-0 6-1 6-2 6-3 6-4 7-5 7-6 ...
or even richer terminal information.
Then:
That's the cleanest version.
Your point/game score obviously resets:
textset_score = 0-0 game_score = 0-0
But the probability-generating state does not necessarily reset.
Carry forward whatever your model legitimately models, such as:
That distinction matters. I wouldn't literally make Set 2 start at a different tennis score because A won or lost S1. The score resets. What becomes branch-dependent is the latent/pricing state underlying the point probabilities.
There is another implementation issue I'd inspect immediately: memoization/cache keys.
Suppose you've correctly created:
pythonstate_after_win state_after_loss
but your DP cache key is something like:
python(set_number, games_a, games_b, points_a, points_b, server)
while your branch-conditioned posterior/fatigue/strength state is omitted.
Then both branches can still hit the same cached Set-2 solution, silently recreating your stationary cage.
Your DP key needs all probability-relevant state, conceptually:
pythonkey = ( set_number, games_a, games_b, points_a, points_b, server, service_rotation, strength_state_a, strength_state_b, fatigue_a, fatigue_b, posterior_state, ruleset, )
You don't necessarily need those exact fields, but the rule is:
If changing a variable can change point probability, that variable must either be represented in the DP state/cache key or the cache must be scoped so it cannot collapse distinct branches.
Log these three numbers before doing anything else:
textq1 = P(A wins S1 | current state) q2_win = P(A wins S2 | A wins S1) q2_loss = P(A wins S2 | A loses S1)
Then calculate independently:
pythonp3 = q1 * (1 - q2_win) + (1 - q1) * q2_loss p2 = q1 * q2_win + (1 - q1) * (1 - q2_loss)
If you currently see something like:
textq1 = 0.57 q2_win = 0.57 q2_loss = 0.57
you have essentially confirmed the problem.
In fact:
and that's about as high as the architecture can ever get.
But if the canonical branches produce:
textq1 = 0.57 q2_win = 0.43 q2_loss = 0.62
then:
Now the deciding set can genuinely become the model's modal number-of-sets outcome.
One final distinction is important for your 8-point discrepancy: don't impose that P3 must become >50% merely because your matchup layer says “three sets.” The matchup layer should affect the state variables that generate and . Then let the DP decide. If it still says 46% after removing the structural ceiling, that's a legitimate model disagreement rather than an architectural impossibility.
So your intended direction—branch-conditioned Set-2 state inside the canonical recursion, then recompute the PMF normally—is exactly the architecture I'd use. The two things I'd examine most closely are the state-transition function and the DP memoization key, because either one can accidentally collapse the two Set-2 branches back into the same state.