Mathematical programming / Stochastic programming

Chance Constraints

Require a constraint to hold with at least a target probability, rather than always — a way to bake in a service-level target directly.

Note Advanced

Short note. A compact reference, correct as far as it goes. It will be expanded into a full guide with a worked example and an interactive demonstration.

Problem

You want a constraint to hold “most of the time” rather than always — e.g. “inventory should cover demand at least 95% of the time,” not “inventory must always cover demand no matter what,” which would force absurdly high stock levels to guard against the tail.

When to use it

Anywhere a business already thinks in service levels: inventory service level, network reliability targets, staffing to cover demand with a target probability. It’s a direct way to encode “how much risk are we willing to accept” into the model rather than picking safety stock by rule of thumb.

Formulation

A chance constraint requires:

P(a^T x >= b) >= 1 - epsilon

where epsilon is the acceptable failure probability (e.g. 0.05 for a 95% service level). In general this is nonconvex and hard to solve directly, but for the common case where the uncertain quantity is normally distributed, it has a clean closed-form linear reformulation:

demand ~ Normal(mu, sigma^2)
P(inventory >= demand) >= 1 - epsilon
  =>  inventory >= mu + z_(1-epsilon) * sigma

where z_(1-epsilon) is the standard normal quantile (e.g. 1.645 for 95%). This is the same idea as newsvendor’s critical ratio, generalized into a constraint you can drop into a larger model.

Code sketch

from scipy.stats import norm

service_level = 0.95
mu, sigma = 500, 60
z = norm.ppf(service_level)

safety_stock = z * sigma
required_inventory = mu + safety_stock   # plug this into the larger MILP as a bound

Pitfalls

  • The clean linear reformulation only holds for specific distributions (normal being the common one) and specific constraint structures. For general nonlinear or non-Gaussian cases, chance constraints become genuinely hard (nonconvex), and you typically approximate via sampling (scenario-based chance constraints) instead.
  • Correlated uncertainty across multiple constraints (e.g. shared demand risk across several products) breaks the simple per-constraint reformulation — you need a joint chance constraint, which is meaningfully harder than the individual (marginal) version shown here.
  • A 95% service level sounds safe until you have many such constraints simultaneously — the probability that all of them hold is lower than 95% unless you explicitly account for that (a joint, not marginal, guarantee).