Cost Functions Are Policy Knobs
How to turn a rigid optimization model into a tunable decision policy by using economic penalties, simulation, and out-of-sample evaluation instead of piling on rules.
A lot of optimization models become complicated for the wrong reason.
The first version is usually clean. Minimize cost or maximize profit subject to the real physical and contractual constraints. Then the model produces a result someone does not like.
So we add a rule.
Then another rule.
Then a threshold, a buffer, a target, an exception, and eventually a collection of constraints whose main purpose is to force the optimizer to behave more like the planners expect.
At that point the model may still solve, but we have quietly changed what it is. We are no longer modeling the business. We are encoding a policy through hard logic.
There is another option: put some of that behavior in the objective and tune it.
This is one of the most useful ideas in practical decision science. A cost function does not have to represent a literal invoice that accounting can point to. It can approximate the future consequences of a decision that the current optimization model cannot represent directly.
That turns the objective function into part of the policy.
Start with the decision, not the penalty
Suppose we are deciding purchase quantities for a set of products over time.
A basic model might have decision variables
[ q_{i,t} = \text{units of item } i \text{ ordered in period } t ]
with inventory state
[ I_{i,t+1} = I_{i,t} + q_{i,t-L_i} - D_{i,t} ]
where (L_i) is lead time and (D_{i,t}) is demand.
The objective might include purchase cost, holding cost, lost-sales cost, transportation cost, and perhaps fixed ordering cost.
That is a reasonable start. But the operational system often contains effects that are difficult or expensive to represent exactly.
Maybe buying too aggressively today consumes warehouse space that will be valuable later. Maybe frequent ordering creates supplier instability. Maybe a very low inventory position makes the next planning cycle fragile. Maybe an order that looks cheap inside the current horizon creates expensive expedites after the horizon.
You can try to model every future state explicitly. Sometimes you should.
But sometimes the full sequential problem is too large, too slow, or too difficult to maintain. Then an approximation can be more useful than pretending those future consequences do not exist.
The important question is not, “What penalty should we add?”
It is:
What consequence of today’s decision is missing from the model?
That framing keeps the penalty tied to an actual decision problem.
A cost function approximation
Assume the explicit model values decisions over a finite horizon (T). The true economic value of a decision includes consequences after (T), but those are absent from the optimization.
A simple approximation is to add a terminal value:
[ \max \quad \text{Profit}_{1:T} - \theta I_T ]
Here (\theta) is not necessarily the literal weekly holding cost. It is a parameter representing the estimated economic consequence of ending the horizon with inventory.
We can make the approximation richer:
[ \max \quad \text{Profit}_{1:T}
- \theta_1 I_T
- \theta_2 B_T
- \theta_3 N_{orders} ]
where (B_T) might represent backlog or shortage exposure and (N_{orders}) the number of purchase events.
Now (\theta_1, \theta_2, \theta_3) are policy parameters.
The optimizer still handles the combinatorics. It decides which items to buy, how much to buy, when to buy, how to satisfy MOQs, and how to use shared capacity. The parameters influence how it values states and actions that are imperfectly represented by the finite model.
This is much more powerful than hard-coding something like:
Never end the horizon with more than four weeks of supply.
The hard rule declares everything below four weeks acceptable and everything above it unacceptable. The cost function lets the optimizer trade the consequence against everything else in the model.
That tradeoff is usually what the business actually faces.
Constraints and costs are different things
This distinction matters.
A warehouse with room for exactly 100 pallets has a physical constraint:
[ \sum_i v_i I_{i,t} \le 100 ]
A preference to keep utilization below 90 pallets because congestion becomes painful is different.
You might model the latter with an excess variable:
[ e_t \ge \sum_i v_i I_{i,t} - 90 ]
[ e_t \ge 0 ]
and penalize it:
[
- \theta_{congestion} e_t ]
The 100-pallet limit is feasibility. The 90-pallet threshold is economics.
Confusing these two creates brittle models. If every preference becomes a constraint, the feasible region slowly shrinks until the model either becomes infeasible or starts making absurd sacrifices to respect rules that were never truly absolute.
Before adding a constraint, ask:
- Is this physically impossible to violate?
- Is it contractually prohibited?
- Is it a real logical requirement?
- Or is violating it merely expensive, risky, annoying, or undesirable?
The last category usually belongs in the objective, not the feasible region.
For a deeper treatment of this distinction, see Not Every Business Rule Is a Constraint.
But where do the penalty values come from?
This is where many teams get uncomfortable.
They want every coefficient to have an accounting source. If the shortage penalty is $37.42 per unit, someone asks which ledger contains $37.42.
Sometimes that is the right question. Purchase prices, transportation rates, duties, and disposal costs should normally be grounded in real economics.
But an approximation parameter is different. Its job is to make the policy behave well over the actual operating process.
So measure it by that standard.
Suppose we have parameters
[ \theta = (\theta_{terminal}, \theta_{shortage}, \theta_{cadence}) ]
and a simulator that can replay the replenishment system through uncertain demand and lead times.
For each candidate (\theta):
- Solve the optimization model using (\theta).
- Execute only the decisions that would actually be committed.
- Advance the simulated system.
- Observe demand, receipts, cancellations, and other uncertainty.
- Re-optimize when the real process would re-optimize.
- Measure realized economics over the full simulation.
Then select the parameters that perform well out of sample.
Formally, we are searching for
[ \theta^* = \arg\max_{\theta} ; \mathbb{E}[R(\pi_{\theta}, W)] ]
where (\pi_{\theta}) is the policy induced by the optimization model and (W) represents uncertain outcomes.
Nothing has been “trained” in the usual machine-learning sense. We have defined a parameterized policy and searched for parameter values that make good decisions in simulation.
The simulator changes the role of the MILP
Without simulation, people often treat the MILP as the complete decision model. Every important consequence must somehow fit inside it.
With simulation, the MILP can play a narrower and often more useful role.
It becomes the decision function inside a larger system.
The MILP handles what it is good at: discrete choices, shared constraints, MOQs, capacities, setups, fixed costs, logical relationships, and economic tradeoffs at the current decision point.
The simulator handles what it is good at: time, uncertainty, repeated decisions, state transitions, operational noise, and consequences that occur outside the optimization horizon.
The tuning loop connects them.
This architecture can be much easier to improve than one enormous stochastic optimization model that attempts to represent the entire future exactly.
That does not mean stochastic programming or dynamic programming are wrong. If the problem structure supports them, use them. The point is that there is a practical middle ground between a deterministic MILP and a mathematically complete sequential stochastic model.
A concrete supply chain example
Consider a retailer ordering 5,000 SKUs from several hundred vendors.
Each vendor has a minimum order value. Products have case packs. Warehouse capacity is shared. Demand is uncertain. Lead times vary. The ordering engine runs every week.
The deterministic MILP might optimize the next 16 weeks.
A naive model minimizes purchase, holding, and shortage costs over those 16 weeks. The problem is that week 16 is artificial. Inventory arriving in week 15 looks expensive because it generates little in-horizon benefit. Inventory consumed in week 17 has no value because week 17 does not exist.
One response is to extend the horizon to 52 weeks.
That may help, but it also increases model size, adds low-quality distant forecasts, and does not actually remove the terminal problem. It moves it.
Another response is a terminal approximation:
[ V(I_T; \theta) ]
For example:
[ V(I_T; \theta) = \sum_i \theta_i I_{i,T} ]
or a piecewise function that values the first few weeks of terminal coverage differently from extreme excess inventory.
Now the model can recognize that some ending inventory has future value without explicitly solving the entire future.
The parameters can be estimated economically, tuned in simulation, or initialized economically and then calibrated.
That last approach is often the best starting point. Use economics to define a sensible range. Use simulation to determine how the policy actually performs.
Tune policies, not historical outcomes
There is an easy way to fool yourself here.
Suppose you tune (\theta) on the same historical period you use to report performance. You search hundreds of parameter combinations until one happens to fit the realized demand path extremely well.
Congratulations: you have overfit a decision policy.
The same discipline used in predictive modeling applies here, but the unit of evaluation is different.
Split by decision time.
At each historical decision date, expose the optimizer only to information that was available at that date. Use the forecast vintage that actually existed. Reconstruct inventory and open orders as they were known then. Do not let future cancellations, receipts, or demand leak backward.
Tune on one collection of historical periods or simulated worlds. Validate on another. Keep a final holdout if the stakes justify it.
Most importantly, evaluate realized decisions, not the internal objective value of the MILP.
The model objective is the approximation you are tuning. It cannot also be the independent judge of whether the approximation is good.
What should you measure?
Start with money when you can.
Useful metrics include realized contribution margin, purchase cost, holding cost, markdown or disposal cost, expedite cost, lost-sales value, transportation cost, and working-capital consumption.
Then include operational behavior that matters:
- order frequency by vendor,
- order-size volatility,
- stockout duration,
- inventory age,
- capacity violations or emergency interventions,
- percentage of recommendations overridden,
- policy stability from one planning run to the next.
Service level can still be reported. Inventory turns can still be reported. Forecast accuracy can still be reported.
They just should not automatically become the objective.
The test is whether the policy makes better decisions under the economics and constraints of the business.
Beware of compensating errors
Tunable cost functions create a new debugging problem: a good parameter can hide a bad model.
Suppose lead times are understated. The optimizer orders too late. You increase the shortage penalty until the model starts ordering earlier and simulation performance improves.
The tuned policy may look good, but the penalty is compensating for incorrect lead-time logic.
That is dangerous because the compensation may break when the operating environment changes.
Before tuning, validate the mechanics:
- inventory balance,
- lead-time indexing,
- units of measure,
- case-pack rounding,
- MOQ activation,
- capacity consumption,
- cost timing,
- forecast alignment,
- open-order state,
- cancellation and receipt logic.
Then tune the approximation.
A simulator does not absolve you from modeling correctly. It gives you another place to detect incorrect modeling.
Parameter sensitivity matters more than the winning value
Do not just report that (\theta = 4.7) won.
Plot or inspect performance around it.
If (4.7) produces $10.01 million, (4.5) produces $10.00 million, and (5.0) produces $10.00 million, you have a broad stable region. That is good news. Pick a simple value and move on.
If (4.7) produces $10 million while (4.6) and (4.8) produce $8 million, something deserves investigation.
The policy may be sitting on a discrete threshold such as an MOQ, capacity breakpoint, or fixed-charge activation. That may be real. Or the simulator may be noisy. Or the implementation may contain a discontinuity you did not intend.
Robust parameter regions are usually more valuable than numerically precise optima.
Policy refresh is an operational decision
Once parameters are tunable, teams often assume they should be retuned constantly.
Not necessarily.
A stable parameter set has value. Suppliers prefer predictable orders. Planners prefer understandable behavior. Engineering teams prefer reproducible systems. A policy that changes every week because a noisy tuner found a slightly better coefficient can destroy those benefits.
Treat refresh cadence as part of the design.
If a parameterized ordering policy remains strong for several months, there may be little reason to retune daily. Re-evaluate periodically or when the environment changes materially: supplier terms change, lead times shift, margins move, capacity changes, or demand behavior changes.
The goal is not to maximize tuning activity.
The goal is to operate a good policy.
Common failure modes
Turning every business request into a hard constraint. This creates brittle feasibility and prevents economic tradeoffs.
Inventing arbitrary penalties and never validating them. A soft constraint with a random large coefficient is just a hard constraint wearing a disguise.
Tuning against the MILP objective. The objective contains the approximation. Evaluate against realized economics outside the model.
Using future information in replay. If the historical optimizer sees revised forecasts or future receipts, the backtest is fiction.
Ignoring uncertainty during tuning. Parameters that win on one deterministic demand path can be terrible policies.
Tuning too many knobs at once. Every parameter should correspond to a consequence you can explain. If you have 200 mysterious coefficients, debugging becomes nearly impossible.
Treating the best sampled point as truth. Simulation is noisy. Compare confidence intervals, neighboring parameter values, and robustness across scenarios.
Using tuning to repair broken mechanics. Fix incorrect state transitions and business logic first.
What to do in practice
Take an existing optimization model and inspect every hard constraint that is not truly physical, contractual, or logical.
For each one, ask what bad outcome the constraint is trying to prevent.
If the answer is economic, consider representing that consequence as a cost instead.
Then inspect the objective for consequences that the finite optimization horizon misses. Terminal inventory, future shortage exposure, ordering instability, congestion, and recourse costs are common candidates.
Start with a small number of interpretable parameters. Give each a plausible economic range. Build a replay or simulator that reproduces the actual decision cadence and information flow. Search the parameter space with something appropriate for the evaluation cost: grid search for two knobs, random or quasi-random search for a few more, Bayesian optimization or other derivative-free methods when simulation is expensive.
Validate on decision periods and uncertainty realizations that were not used for tuning.
Then look beyond the winning score. Check stability, operational behavior, edge cases, and sensitivity.
The deeper lesson is simple: an optimization model does not have to contain a perfect mathematical description of the future to make good decisions.
It needs to represent today’s decision, today’s state, the real constraints, and a useful approximation of what today’s action does to tomorrow.
When those approximations are explicit and tunable, the model stops being a frozen collection of assumptions.
It becomes a policy you can test, measure, and improve.