Optimization with Constraints -

Python Numerical Methods


Optimizations of an Equation for Max or Min with Constraints

Optimization using minimize, and PuLP. First we will use the minimize library to optimize an objective function as a maximum or minimum. The programs are the same except for multiplying all equations by negative one for maximums. Scipy does not support maximums, so we must multiply by negative one. The second area we will examine is the use of PuLP for optimization of linear equations. Suggested reading is Numerical Methods for Engineers, Fifth Edition by Chapra and Canale.



Two Examples of Minimum Optimization with Constraining Equations

There are many examples of optimization problems in books and on the internet. What is important is to see a working program. The syntax is specialized. It is simpler to copy and paste the program and make changes as necessary. Note that generally, problems with constraints of the form aX+bY>=C are minimization problems. Problems with constraints of the form aX+bY<=C are maximization problems.

First Example. Here we will be optimizing for minimization given an objective function and three constraints. We start the program by importing scipy.optimize minimize, and import math. We then define the objective equation in a function.
Notice the independent variables substitutions: X1=x[0], X2=x[1], X3=x[2] .
Given log(X1**2 + 1) + X2**4 + X1*X3 we get math.log(x[0]**2 + 1) + x[1]**4 + x[0]*x[2] .
The first constraining equation is X1**3 - X2**2 >= 1 and we get x[0]**3 - x[1]**2 – 1
The second two constraints are X1, X3>=0 and we get x[0] and x[2]
Cons is the abbreviation for constraints.
Notice the format for the three equations. Note that for ‘type’ we have either ineq for >= or <=, or eq for = .
The next step is using minimize with the following parameters: function, initial guess, and constraints.
The result is printed. It rounds to [1,0,0], where x1=1, x2=0, and x3=0.

# log(X1**2 + 1) + X2**4 + X1*X3
# X1**3 - X2**2 >= 1
# X1, X3 >= 0
# Notice X1 = x[0], X2 = x[1], X3 = x[2]
from scipy.optimize import minimize
import math
def f(x):
   return math.log(x[0]**2 + 1) + x[1]**4 + x[0]*x[2]

x0 = [1, 1, 1]
#Constraints of form ax+by>=c for minimization
cons=({'type': 'ineq',
   'fun': lambda x: x[0]**3 - x[1]**2 - 1},
   {'type': 'ineq',
   'fun': lambda x: x[0]},
   {'type': 'ineq',
   'fun': lambda x: x[2]})

res = minimize(f, x0, constraints=cons)
print(res)

#Output x: array([ 1.00000000e+00, -1.39403314e-06, -5.59970051e-14])



Second Example. Here we will be optimizing for minimization given an objective function and three constraints. We start the program by importing scipy.optimize minimize, and import math.

A short description of the problem follows. We are building a cylindrical tank, that lays on its side in the back of a pickup truck. Two constaints are given as truck bed length and width. A third constraint is the equation for the necessary tank volume. The objective is to minimize cost for steel and welding. Find the diameter and length of the tank.

Given parameters for constraints: Volume = 0.8, Length max = 2, Width max = 1. Minimize cost subject to pi*D**2*L/4 =0.8, L<=2 , D<=1 .
The cost equation that we will minimize is given in the program below.

Start by importing scipy.optimize minimize, and import math. Define the objective function, which is the cost equation. (The equation is long. Here we will place a backslash after the first part of the equation to continue it to the next line.) Make our initial guess. List the constraining functions. Use minimize with the parameters: function, best guess, and constraints. Output the results. L=1.05 and D=0.98 .

# We are building a tank to place in pickup truck bed.
# We are given truck bed length and width (constraints)
# We are given the necessary tank volume (constraint)
# Objective function minimizes cost for steel and welding
# Find D and L of tank.

from scipy.optimize import minimize
import math
def f(x):
   # Use a backslash key to continue equation on next line.
   # x[0]=L , x[1]=D
   return 4.5*8000*(x[0]*math.pi*((x[1]/2+.03)**2-(x[1]/2)**2) \
       +2*math.pi*(x[1]/2+.03)**2*.03)+20*4*math.pi*(x[1]+.03)
x0= [2,1]
cons=({'type': 'eq',
   'fun': lambda x: math.pi*x[1]**2*x[0]/4 - .8},
   {'type': 'ineq',
   'fun': lambda x: x[1]},
   {'type': 'ineq',
   'fun': lambda x: x[0]})
res = minimize(f, x0, constraints=cons)
print(res)

# x[0]=L , x[1]=D
# Output x: array([1.0532219 , 0.98340829])



Three Examples of Maximization Optimization with Constraining Equations

Third Example uses maximization optimization with one constraining equation. The program below has explanatory comments. The steps are the same as above. The difference is we will be maximizing the objective function, rather than minimizing it. Because scipy only supports minimization, we will be multiplying the objective function and constraint by -1 . The multiplication by -1 allows us to maximize.

# (X-1)**2+(Y-2)**2 Objective function to maximize
# X**2 - Y**2 = 80 Constraint
#Constraints of form ax+by>=c for minimization
#Constraints of form ax+by<=c for maximization

from scipy.optimize import minimize
import math
# Multiply objective function and constraint by -1 to find maximum
# because scipy only supports minimization.
# Notice X = x[0], Y = x[1]
def f(x):
   return -1*((x[0]-1)**2+(x[1]-2)**2)

x0 = [1, 1]
cons=({'type': 'eq',
   'fun': lambda x: -1*(x[0]**2 + x[1]**2 - 80)})

res = minimize(f, x0, constraints=cons)
print(res)

#Output array([-4.00000009, -7.99999996])
# x=-4 y=-8







Fourth Example. The program below has explanatory comments. The steps are the same as above. We will be maximizing the objective function, rather than minimizing it. Because scipy only supports minimization, we will be multiplying the objective function and constraints by -1 . The multiplication by -1 allows us to maximize.

# 3*X1+5*X2 Objective function to maximize
# X2<=6, X1<=4, 3*X1+2*X2<=18 Constraints
#Constraints of form ax+by>=c for minimization
#Constraints of form ax+by<=c for maximization
from scipy.optimize import minimize
#import math
# Multiply objective function and constraints by -1 to find maximum
# because scipy only supports minimization.
# Notice X1 = x[0], X2 = x[1]
def f(x):
   return -1*(3*x[0]+5*x[1])

x0 = [0, 0]
cons=({'type': 'ineq',
   'fun': lambda x: -1*(3*x[0] + 2*x[1] - 18)},
   {'type': 'ineq',
   'fun': lambda x: -1*(x[0] - 4)},
   {'type': 'ineq',
   'fun': lambda x: -1*(x[1] - 6)})

res = minimize(f, x0, constraints=cons)
print(res)

#Output x: array([2., 6.])



Fifth Example. The program below has explanatory comments. The steps are the same as above. We will be maximizing the objective function. Because scipy only supports minimization, we will be multiplying the objective function and constraints by -1 . The multiplication by -1 allows us to maximize.

# 150*x1+175*x2 Objective function to maximize
# 7*x1+11*x2<=77, 10*x1+8*x2<=80, x1<=9, x2<=6,x1>=0, x2>=0 Constraints
#Constraints of form ax+by>=c for minimization
#Constraints of form ax+by<=c for maximization
from scipy.optimize import minimize
#import math
# Multiply objective function and constraints by -1 to find maximum
# because scipy only supports minimization.
# Notice x1 = x[0], x2 = x[1]
def f(x):
   return -1*(150*x[0]+175*x[1])

x0 = [1, 1]
cons=({'type': 'ineq',
   'fun': lambda x: -1*(x[0]*7 + x[1]*11 - 77)},
   {'type': 'ineq',
   'fun': lambda x: -1*(x[0]*10 + x[1]*8 - 80)},
   {'type': 'ineq',
   'fun': lambda x: -1*(x[0] - 9)},
   {'type': 'ineq',
   'fun': lambda x: -1*(x[1] - 6)})

res = minimize(f, x0, constraints=cons)
print(res)

#Output x: array([4.88888889, 3.88888889])




Optimization Using PuLP to Maximize Objective of Linear Equation with Constraints

Sixth Example. We will now switch to the PuLP module. You will have to install the package in PyCharm Community as described in Chapter 12.2 of Introduction to Engineering Python by Steve A. Larsen. The last part of Chapter 12 concerns installation of matplotlib, but installation of PuLP is very similar. Just search for and install PuLP instead of matplotlib.

In this optimization problem we will be looking at a factory that makes tables, chairs, and bookcases. We want to optimize the production of each to maximize profit. We are given the following information.

x1= number of tables
x2= number of chairs
x3= number of bookcases
Objective Function: Profit = 40*x1+30*x2+45*x3
Constraints:
labor: 2*x1 + 1*x2 + 2.5*x3 <= 60 Hours
Machine: 0.8*x1 + 0.6*x2 + 1.0*x3 <= 16 Hours
Wood: 30*x1 + 20*x2 + 30*x3 <= 400 board-feet
Tables: x1>=10 board-feet
x1, x2, x3 >= 0

# Install of pulp in PyCharm Community follow directions
# Chapter 12.2 of Introduction to Engineering Python
# Import all classes of PuLP module
from pulp import *

#Optimum number of tables, chairs, or bookcases
#A linear program problem using Maximization
model = LpProblem("FurnitureProblem", LpMaximize)

# Create 3 variables tables, chairs, and bookcases
# First=item,Second=LowerBound,Third=UpperBound,Fourth=DataType
x1 = LpVariable("tables", 0, None, LpInteger)
x2 = LpVariable("chairs", 0, None, LpInteger)
x3 = LpVariable("bookcases", 0, None, LpInteger)

# Create maximize objective function
# Profit equals $ * item
model += 40 * x1 + 30 * x2 + 45 * x3

# Constraints
model += 2 * x1 + 1 * x2 + 2.5 * x3 <= 60, "Labor"
model += 0.8 * x1 + 0.6 * x2 + 1.0 * x3 <= 16, "Machine"
model += 30 * x1 + 20 * x2 + 30 * x3 <= 400, "wood"
model += x1 >= 10, "tables"

# The problem is solved using PuLP's choice of Solver
model.solve()

# Each of the variables is printed with the optimum value
for v in model.variables():
   print(v.name, "=", v.varValue)

# bookcases = 0.0
# chairs = 5.0
# tables = 10.0





This website consists of example problems from numerical methods for engineers. The first examples apply to roots, plotting roots, maximums, mininums, and optimization problems. You have enough examples so that you become familiar with the syntax used in Python. The examples have been tested and the output of the programs are listed in the comments for each. All programs were run on Python using the PyCharm Community interface. They were run on an older laptop with 8GB of RAM. If you have never used Python, I recommend the manual Introduction to Engineering Python by Steve Larsen. It is availble on Amazon.







Introduction to Engineering Python: For First Year Engineering Students