Coding two variables
AnsweredI am used to using AMPL and Cplex solver, and I recently I started to learn Gurobipy. I would appreciate your help in the following:
I have a set of Patients (P1,P2,P3) and parameter T=3 days.
For each patient i on each day t, there is a parameter Sti, let us say Sti=2 for all t in 1..T and i in Patients
I need to formulate two variables:
1) Xtis where t in 1..T, i in Patients, and s in 1..S[t,i].
2) Ytisjz wheret t in 1..T, i in Patients, s in 1..S[t,i], j in Patients, and z in S[t,j]
How can I formualte such variables?
#AMPL code:
set PATIENTS;
param T;
param S {t in 1..T, i in PATIENTS};
var X {t in 1..T, i in PATIENTS, s in 1..S[t,i]} binary;
var Y {t in 1..T, i in PATIENTS, s in 1..S[t,i], j in PATIENTS, z in 1..S[t,j]} binary;
-
One way of implementing your variables would be
import gurobipy as gp
from gurobipy import GRB
Patients = ["P1","P2","P3"]
T = [1,2,3]
S = {
(1,"P1"): 1,
(2,"P1"): 2,
(3,"P1"): 3,
(1,"P2"): 4,
(2,"P2"): 5,
(3,"P2"): 6,
(1,"P3"): 7,
(2,"P3"): 8,
(3,"P3"): 9}
model = gp.Model()
X = {}
Y = {}
for t in T:
for i in Patients:
s = S[t,i]
X[t,i,s] = model.addVar(name = "X[%d,%s,%d]"%(t,i,s))
for j in Patients:
z = S[t,j]
Y[t,i,s,j,z] = model.addVar(name = "Y[%d,%s,%d,%s,%d]"%(t,i,s,j,z))
# Access variables
model.update() # only needed to actually print something useful
print(X[1,"P1",S[1,"P1"]])
print(Y[2,"P2",S[2,"P2"],"P3",S[2,"P3"]])You should also have a look at our Python examples. In particular, the diet and workforce example should be useful for you.
Additionally you might want to have a look at Python I: Introduction to Modeling with Python - Gurobi. It includes a video tutorial and examples with jupyter notebooks for you to follow.
0 -
Thank you very much. I think you mean:
for s in S[t,i] in stead of s = S[t,i]
It works now.
I already watched the three gurobipy videos and examples before I started. Please, I have three questions:
I have a large model and I'm trying to use benders decomposition to solve it. Thus, I have a master problem (m.model) and a sub problem (s.model).
The first question:
y[t] is a variable in the master problem, and its value should be used as a parameter in the subproblem. To define its value in the subproblem, I wrote:y_ = {}
for t in T:
y_[t] = y[t].XIs this way correct ?
The second question:
I need to formulate the following:
" if the subproblem is infeasible:
do .... "s.optimize()
if s.model infeasible:
do ....How can a condition like this be formulated?
The third question is:
What is difference between m.update() and m.reset()?
Let us say the master problem is solved, then since the subproblem is infeasible, a new constraint should be added to the master problem. Thus, should I use a reset or update parameter before the second iteration to the master problem? knowing that I am using While-loop to swap between the master and sub problem.
While (....):
m.update() or m.reset() ??
m.optimize
for t in T:
s.optimze
if s.model infeasible:
m.addConstr (......)I'm really very grateful for your wonderful help
0 -
The first question:
y[t] is a variable in the master problem, and its value should be used as a parameter in the subproblem. To define its value in the subproblem, I wrote:y_ = {}
for t in T:
y_[t] = y[t].XIs this way correct ?
Yes, the way you access the X attribute is correct if you are not in a callback.
The second question:
I need to formulate the following:
" if the subproblem is infeasible:
do .... "s.optimize()
if s.model infeasible:
do ....How can a condition like this be formulated?
It looks like \(\texttt{s}\) is your model so you have to access its Status attribute.
if s.status == GRB.INFEASIBLE:
# do somethingThe third question is:
What is difference between m.update() and m.reset()?
A model.update() processes all pending model modifications. It is usually not required when working on a local machine. You can find more details on Gurobi's update mode in its respective documentation. Model.reset() should be used after an optimization call to discard all solution information. This will make Gurobi start from scratch and no re-use any information gained from previous optimization calls.
0 -
Hey!
Thank you very much for your reply!
Please, I have one last question: As I mentioned earlier, I'm trying to apply benders decomposition to solve the model, and I'm getting a very strange situation.Note that I already know the optimal solution because I solved the instance without decomposition .
# master problem variables, objective function and constraints are presented here.
# Only one variable in the master problem (y[t])
#define two inputs
feasibility = "False"
y_ = {}
#start while-loop
while feasibilty = "False"
m.optimize()
m.printAttr('X')
feasibility = "TRUE"
for t in T:
y_[t] = y[t].X
#subproblem variables, objective function and constraints are presented here.
#variable y_[t] is only used in one constraint:
r.addConstr(g[t] + y_[t] - quicksum(Xoc[t]) == 0)
r.optimize()
if r.status == GRB.INFEASIBLE:
#add cut-off constraint to the master problem:
m.addConstr (y[t] > 1 if y_[t]=0)
m.update()
feasibility = "False"
#lets us consider T = [1], hence I think that there is no need to focus on the break statment of while-loop.After several iterations, the master problem gives the optimal value of y[t] , whose value should be used as input to the sub-problem, but the solver does not consider it and gives me that the sub-problem is not feasible!. In other words, if the sub-problem takes into account the last value of y_[t], the problem will certainly be feasible.
Are there any mistakes I seem to have made? Any tips?
Thank you from the heart.
0 -
Adding a constraint with an \(\texttt{if}\)-clause like this will not work.
m.addConstr (y[t] > 1 if y_[t]=0)
You should rather go with
if y_[t] == 0:
m.addConstr(y[t] >= 1 + eps)where \(\epsilon > 0\) is a small constant. This is because Gurobi does not support strict inequality constraints.
0
Please sign in to leave a comment.
Comments
5 comments