A Cobb-Douglas Example in Python
Consumer choice theory sits at the heart of microeconomics, and one of its cleanest applications is the classic utility maximization problem with two goods. Given a fixed budget, how should a consumer split spending between two goods to get the most satisfaction possible? In this article we’ll work through a concrete Cobb-Douglas example, solve it both analytically and numerically, and visualize the solution with indifference curves, a 3D utility surface, and a contour map.
The Setup
A consumer chooses quantities of two goods, $x$ and $y$, to maximize a Cobb-Douglas utility function:
$$
U(x, y) = x^{\alpha} y^{\beta}
$$
subject to a linear budget constraint:
$$
p_x x + p_y y = I
$$
where $p_x$ and $p_y$ are the prices of the two goods and $I$ is total income. In our example we’ll use:
$$
\alpha = 0.6, \quad \beta = 0.4, \quad p_x = 4, \quad p_y = 2, \quad I = 100
$$
Solving with Lagrange Multipliers
Setting up the Lagrangian:
$$
\mathcal{L}(x, y, \lambda) = x^{\alpha} y^{\beta} + \lambda (I - p_x x - p_y y)
$$
Taking first-order conditions and eliminating $\lambda$ gives the tangency condition where the marginal rate of substitution equals the price ratio:
$$
\frac{\alpha y}{\beta x} = \frac{p_x}{p_y}
$$
Combining this with the budget constraint yields a closed-form solution:

This closed-form result gives us a perfect benchmark to check against a numerical optimizer.
Python Implementation
1 | import numpy as np |
=== Analytical Solution (Cobb-Douglas closed form) === x* = 15.0000 y* = 20.0000 U* = 16.8293 === Numerical Solution (SLSQP) === x* = 15.0000 y* = 20.0000 U* = 16.8293 Converged: True, message: Optimization terminated successfully === Spending Check === Total spend (analytical): 100.0000 (budget = 100.0) Total spend (numerical): 100.0000 (budget = 100.0)
Code Walkthrough
Utility and constraint functions. utility(x, y) implements the Cobb-Douglas form $x^{\alpha}y^{\beta}$ directly. neg_utility wraps it with a sign flip because scipy.optimize.minimize only minimizes — maximizing utility is equivalent to minimizing its negative. It also guards against non-positive quantities by returning a huge penalty value, which keeps the optimizer away from invalid regions without needing complicated bound logic.
Analytical solution. Because Cobb-Douglas preferences have a well-known closed-form solution, we compute x_analytic and y_analytic directly from the formula derived above. This isn’t just for display — it acts as a ground-truth check against the numerical result.
Numerical solution. We use scipy.optimize.minimize with the SLSQP (Sequential Least Squares Programming) method, which handles equality constraints natively. The budget constraint is passed as a dictionary with 'type': 'eq', and bounds keep both goods within a sensible positive range. Starting from a naive 50/50 budget split (x0), SLSQP converges to the same optimum as the analytical formula, which is a nice sanity check that the numerical approach is correctly specified.
Why this is already fast. This is a small, smooth, twice-differentiable convex optimization problem in two variables — SLSQP converges in a handful of iterations, so there’s no need for any special acceleration here. The computational bottleneck, if any, is in the plotting: the 3D surface and contour plots use a $400 \times 400$ grid, which is dense enough for smooth-looking curves while still rendering instantly.
Visualizing the Solution
Figure 1 — Indifference curves and the budget line. Each colored curve traces a set of $(x, y)$ bundles that give the same utility level. The steepness of these curves at any point reflects the marginal rate of substitution — how much of $y$ the consumer is willing to give up for one more unit of $x$ while staying equally satisfied. The red line is the budget constraint: every point on it costs exactly $I$. The green dot marks the optimum, and geometrically it’s exactly where the budget line is tangent to the highest reachable indifference curve. Any point further out on that indifference curve isn’t affordable, and any affordable point not on that curve leaves utility on the table.

Figure 2 — The 3D utility surface. This lifts the whole picture into three dimensions: height now directly represents utility $U(x, y)$ instead of being encoded as contour lines. The red curve traces the utility value along every affordable bundle on the budget line, and the green marker sits at its peak. Rotating this surface makes it visually obvious that the constrained problem is really about finding the highest point reachable while walking along that one path defined by the budget constraint — the unconstrained peak of the full surface would require unlimited income.

Figure 3 — Filled contour map. This is a top-down view of the same surface, using color intensity to encode utility instead of height. It makes the “climbing” intuition especially clear: the optimal bundle sits at the point on the budget line where the colors are most intense, i.e. the warmest reachable region.

Interpreting the Result
With $\alpha = 0.6$ and $\beta = 0.4$, the consumer values good $X$ relatively more, so the closed-form solution allocates a larger budget share to $X$: specifically a share of $\frac{\alpha}{\alpha+\beta} = 0.6$ of income goes to $X$ and $\frac{\beta}{\alpha+\beta} = 0.4$ goes to $Y$. This is a defining feature of Cobb-Douglas preferences — the optimal expenditure shares depend only on the exponents $\alpha$ and $\beta$, not on prices or income at all. That’s why both the analytical and numerical methods land on the same answer regardless of how the starting guess for the optimizer is chosen.
This framework generalizes readily: swapping in a CES or quasi-linear utility function, adding more goods, or introducing non-linear budget constraints (like quantity discounts) all fit naturally into the same Lagrangian and scipy.optimize machinery used here.
























