# sensitivity analysis in python + Docplex

I want to do a sensitivity analysis for the following problem. I know how to add new variables or constraints, but I do not know how I can change the right-hand side (RHS) of the constraint.

#**Orginal problem**

from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
ctKids=mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)

print("Same number of 40 and 30 seats buses")
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)

print("Now with buses with 50 seats")

nbbus50 = mdl.integer_var(name='nbBus50')
mdl.minimize(nbbus40*500 + nbbus30*400 + nbbus50*700)

mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)


There are several ways to do this:

1. You already used left_expr that modified the left-hand side. You can do the same thing with right_expr to modify the RHS.
2. Along the same line as above, lhs and rhs are the aliases for left_expr and right_expr, respectively. So, just simply add the new rhs to the constraints. So, for example, ctKids.rhs = 350 is another way.
3. If you had a case that you didn't save the constraint and you want to alter that constraint's rhs, then you can first retrieve the constraint and then do either 1 or 2 above. So, in your example, that's the case for mdl.add_constraint(nbbus40==nbbus30, 'samenumberofbuses') constraint (of course you could just simply save that, but I'm doing it for illustration here):
ct2 = mdl.get_constraint_by_name('samenumberofbuses')
ct2.rhs = nbbus30 + 5


Also, besides the answer by @EhsanK, you can obtain the range of the parameters for sensitivity analysis as follows to know how much you should play around with those parameters:

!pip install docplex
!pip install cplex
from docplex.mp.model import Model
from docplex.mp.relax_linear import LinearRelaxer

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
ctKids=mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()

lp = LinearRelaxer.make_relaxed_model(mdl)
m2 = lp.solve()

cpx = lp.get_engine().get_cplex()
print(cpx.solution.sensitivity.lower_bounds())
print(cpx.solution.sensitivity.upper_bounds())
print(cpx.solution.sensitivity.bounds())
print(cpx.solution.sensitivity.objective())
print(cpx.solution.sensitivity.rhs())

The results:
[(-1e+20, 7.5), (-1e+20, 10.0)]
[(7.5, 1e+20), (0.0, 1e+20)]
[(-1e+20, 7.5, 7.5, 1e+20), (-1e+20, 10.0, 0.0, 1e+20)]
[(0.0, 533.3333333333334), (375.0, 1e+20)]
[(0.0, 1e+20)]