1

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

DESIRED OUTPUT: Excel Sensitivity Report output for same problem

Reinderien
  • 11,755
  • 5
  • 49
  • 77
KDL4ever
  • 21
  • 5
  • ChatGPT? See https://meta.stackoverflow.com/q/421831/4961700 – Solar Mike Apr 10 '23 at 20:55
  • binding constraints have 0 slack by definition. – AirSquid Apr 10 '23 at 21:51
  • @AirSquid. That is correct. My problem is how to calculate the allowable increase and allowable decrease ranges for constraints that are binding. Any ideas on that? – KDL4ever Apr 11 '23 at 00:00
  • Well, yes, I know it's correct.... re-read your paragraph about it, which is contradictory. If it is not binding, the allowable decrease in the RHS (in the case of a LTE constraint) is the slack – AirSquid Apr 11 '23 at 00:40
  • Omg!! Can’t believe I made that error. I meant to say “non-binding” ugh. Thank you for catching it. I fixed my paragraph – KDL4ever Apr 11 '23 at 03:03

0 Answers0