I want to create a sensitivity report in python after running an LP Model using PuLP. I need it to have allowable increase and allowable decrease values for objective function coefficients and for the RHS values on the constraints; similar to the standard Excel Solver Output. I am able to obtain the slack values (model.slack
), and the shadow prices (model.constraints.pi
), and I know how to obtain the reduced costs for the objective function variables (x.dj
). But, try as I might, I can't figure out how to calculate allowable increases and decreases for the coeffs. of obj. func. & the allowable range for the RHS values of the constraints. My Python code and my Excel outputs are all given below.
import pandas as pd
import pulp as p
# Create the Problem
MaxModel = p.LpProblem("Ch6Ill1",p.LpMaximize)
# Decision Variables
x = p.LpVariable(name='X', lowBound = 0)
y = p.LpVariable(name='Y', lowBound = 0)
# Objective Function
MaxModel += 5*x + 3*y
# Constraints
MaxModel += (x + y <= 15, "Const.1")
MaxModel += (7*x + 4*y <= 75, "Const.2")
MaxModel += (y <= 12, "Const.3")
status = MaxModel.solve()
#Printing the Outputs
sensitivity_data = []
for name, constraint in MaxModel.constraints.items():
sensitivity_data.append({'Name': name,
'Constraint': constraint,
'Shadow Price': constraint.pi,
'Slack': constraint.slack
})
Modeloutput = pd.DataFrame(sensitivity_data)
print(f"status: {MaxModel.status}, {p.LpStatus[MaxModel.status]}")
for var in MaxModel.variables():
print(str(var) + ": {}".format(round(var.value(),2)))
print("Maximum: {}".format(round(MaxModel.objective.value(), 2)))
print((Modeloutput))
Obtained output is given below. Every attempt to calculate the allowable increase and decrease has failed. I have put in over 20 hours on trying everything, but I seem to be missing something critical.
I know that for non-binding constraints (slack value != 0) allowable increase is infinity and allowable decrease is equal to the value of the slack. However, I am not sure how to calculate the allowable increase and decrease for RHS values before the optimal solution changes. Similarly, I know that the allowable increase and decrease for the objective coefficients has to do with the slopes of the binding constraints, but am not sure how to calculate it in Python. For two-variable problems like this, there is a graphical method of solving, but I am trying to find a more generalizable solution for more complex problems in Python.
Gurobipy has these functions internally defined as SAObjUp
, SAObjLow
, etc., but since I am doing this for myself and am basically a beginner at Python, I don't want to purchase it at this time. Any help will be deeply appreciated. Thank you
status: 1, Optimal
X: 5.0
Y: 10.0
Maximum: 55.0
Name Constraint Shadow Price Slack
0 Const.1 {X: 1, Y: 1} 0.333333 -0.0
1 Const.2 {X: 7, Y: 4} 0.666667 -0.0
2 Const.3 {Y: 1} -0.000000 2.0