1. Convex-constrained optimization with inequality constraints
Great job! Let's now explore the same problem with different constraints.
2. Corner versus interior solution
We suggested Alexia work approximately 9 hours daily.
However, if she only has enough work for 5 hours a day. We'll need to incorporate this inequality constraint as w is less than or equal to 5.
Let's examine the graph of constraints and indifference curves. The intersection of the two constraints, one representing 24 hours in the day and the other representing 5 hours of work, forms a corner solution.
Our previous solution was known as interior, since it was not an intersection and not a corner.
3. Manufacturer with capacity constraints
Let's revisit a problem similar to one we have seen before. An automaker produces identical cars in two separate plants A and B.
Each plant's capacity is 90, represented as qA and qB being less than or equal to 90.
Producing cars costs 3q in plant A and 3.5q in plant B.
Price is determined by market demand using the formula P equals 120 minus Q.
The automaker must produce a minimum of 92 cars due to signed contracts, so Q should be greater than or equal to 92.
The firm's objective is to maximize profit Pi, by choosing optimal production levels.
4. Maximizing profit
Before using SciPy, let's identify the objective, constraints, and do some rearranging.
Starting with the objective. Profit, shown as Pi, is revenue minus cost.
Revenue is price per car, P, times number of cars sold, Q. We know from the demand function that
5. Maximizing profit
price equals 120 minus Q.
6. Maximizing profit
Q is the quantity the automaker supplies equals qA + qB.
Cost, C, is the sum of the costs across both plants.
The Bounds for qA and qB are both 90, representing capacity.
Finally, we rewrite the contractual constraint as Q >= 92 as 92<=qA+qB.
7. Formulation
We'll convert this to Python and SciPy.
Here is a more mathematical way of writing what we just walked through.
First, we import minimize, Bounds, and LinearConstraint from scipy.optimize(), since the constraint variables appear linearly.
Next, we define revenue R, cost C and their difference, profit.
We define bounds with a Bounds object, with a list of lower bounds for every variable as the first argument and the upper bounds as the second argument.
Finally, we define constraints using the LinearConstraint() function. The first argument, a list of coefficients of variables, indicates how each variable contributes to the constraint. For instance, a list of two ones implies that one car from plant A and one car from plant B counts towards the total cars made. An alternative would be each plant producing half a car, for example.
The second argument sets the lower bound in the constraint, here set as lb=92.
8. Maximize profit with SciPy
To maximize profit using SciPy, we provide the negative of the objective to function minimize using a lambda function. The expression in the first argument of minimize is a function whose argument is q and return value is negative profit(q).
Next, we provide our initial guess.
Then, we pass the bounds and constraints.
We check whether minimize found a solution with result.message. result.x contains the solution and result.fun the value of the objective. We need to take its negative to cancel out the original negation.
Success! Plant A needs to make 90 cars, while plant B needs to make 2 cars to achieve a profit of 2299 dollars.
9. Non-linear contraints in SciPy
For non linear constraints, we import and use NonlinearConstraint instead.
For instructional purposes, we will apply the same linear constraint, namely 92 <= qA + qB.
In the first argument, we provide the function lambda q: q[0] + q[1]. Next, we provide the lower and upper bounds. As there is no upper bound we set ub=np.Inf, a numpy representation for positive infinity, hence our import of numpy.
10. Solution with NonlinearConstraint
The result is the same.
LinearConstraint is suitable for straightforward, linear problems. If the problem lacks this neat structure, NonlinearConstraint is preferred.
11. Let's practice!
Time to practice!