Unbound Local Error
AnsweredHello, I am trying to code an algorithm using defined functions in python and then add a lazy constraint, I took the work done in tsp.py as an example and guide. However, I get the following error:
UnboundLocalError: local variable 'vis' referenced before assignment
Exception ignored in: 'gurobipy.gurobipy.callbackstub' Traceback (most recent call last): File "src\gurobipy\callback.pxi", line 180, in gurobipy.gurobipy.CallbackClass.callback File "<ipython-input-5-e0036d7dd796>", line 31, in cut File "<ipython-input-5-e0036d7dd796>", line 19, in inner UnboundLocalError: local variable 'vis' referenced before assignment
This is the code I wrote:
met = ['A','B','C','D','E']
reac = ['v1','v2','v3','v4','v5','v6','v7']
reactions = [i for i in range(len(reac))]
metabolites = [ i for i in range(len(met))]
LB =[0,-10,0,0,-10,-10,-10]
UB =[10,10,10,10,10,10,10]
S = {(0,0):-1,(0,1):0,(0,2):1,(0,3):0,(0,4):0,(0,5):0,(0,6):0,
(1,0):1,(1,1):-1,(1,2):0,(1,3):-1,(1,4):0,(1,5):0,(1,6):0,
(2,0):0,(2,1):1,(2,2):0,(2,3):0,(2,4):1,(2,5):0,(2,6):0,
(3,0):-1,(3,1):0,(3,2):0,(3,3):0,(3,4):0,(3,5):1,(3,6):0,
(4,0):1,(4,1):0,(4,2):0,(4,3):0,(4,4):0,(4,5):0,(4,6):1}
v4 = reac.index('v4')
v1 = reac.index('v1')
def inner(yoj): # from this model I want the list of solutions
i = gp.Model()
vi = i.addVars(range(len(reac)),lb=-GRB.INFINITY, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name='vi')
i.setObjective(2000*vi[v4], GRB.MAXIMIZE)
i.addConstrs((gp.quicksum(S[i,j] * vi[j] for j in reactions) == 0 for i in metabolites), name='IFFBA')
i.addConstrs((LB[j]*yoj[j] <= vi[j] for j in reactions), name='iLB')
i.addConstrs((vi[j] <= UB[j]*yoj[j] for j in reactions), name='iUB')
if i.status == GRB.OPTIMAL:
soi = i.getAttr('X',i.getVars())
vis = soi.copy()
return vis
def cut(model,where): #this will add the lazy constraint
if (where == GRB.Callback.MIPSOL):
voj = model.cbGetSolution(model._vars) #solutions
yoj = model.cbGetSolution(model._varsy)# retrieve the yj's solution from m.model
keys = model._vars.keys() #keys
vjs = model._vars #variables master's vj
yjs = model._varsy #variables master's yj
eps = .00001
vij = inner(yoj) #calls the first function to get the solution list
if abs(vij[v4]-voj[v4]) >= eps:
model.cbLazy(vij[v4] <= vjs[v4] + 2000*(gp.quicksum((1-yjs[j])*abs(vij[j]) for j in keys)))
else:
print('Outer Growth Rate','-->',voj[v4])
print('Inner Growth Rate','-->',vij[v4])
m = gp.Model()
v = m.addVars(range(len(reac)), lb=-GRB.INFINITY, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name= 'v')
y = m.addVars(range(len(reac)), vtype=GRB.BINARY, name= 'y')
m.setObjective(1*v[v1], GRB.MAXIMIZE)
m.addConstrs((gp.quicksum(S[i,j] * v[j] for j in reactions) == 0 for i in metabolites), name='OFFBA')
m.addConstrs((LB[j]*y[j] <= v[j] for j in reactions), name='oLBy')
m.addConstrs((v[j] <= UB[j]*y[j] for j in reactions), name='oUBy')
m.addConstr(sum(1-y[j] for j in reactions) == k, name='Knapsack')
m._vars = v
m._varsy = y
m.Params.lazyConstraints = 1
m.optimize(cut)
if m.status == GRB.OPTIMAL:
sol = m.getAttr('X',m.getVars())
sol1= sol.copy()
The idea is to solve a master problem and get \(v_j\) and \(y_j\), then use the \(y_j\) in the inner problem defined in the function (inner) then get the \(vi_j\) to evaluate a value against a value from the master problem (criteria) to add the lazy constraint. That's why I defined a function called inner takes the \(ys\) list as an argument and returns values called \(vi\).
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
I tried to declare vis as global but still can't get it to work, any ideas?
0 -
It looks like you are missing a call to i.optimize(). As a result, the model's status is not \( \texttt{GRB.OPTIMAL} \), so \( \texttt{vis} \) is never assigned a value.
0 -
Such a rookie mistake! I can't believe I missed this, thanks for your reply!
0
Post is closed for comments.
Comments
4 comments