Encountered an attribute error when running SetObjective()
AnsweredHello,
I have been trying to run this code and everything went good until I added the line where I tried to set up the objective function and no matter what I did it always gave me an attribute error. I tried to google and search in the forums, but unfortunately I was not able to find any topic on similar problem. Could somebody look at it please? Thanks in advance!
from gurobipy import *
#parameters
nodes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
arcs = [(0, 4), (0, 15), (0, 19), (0, 5), (1, 5),
(1, 10), (1, 6), (2, 6), (2, 9), (2, 16),
(2, 18), (2, 7), (3, 8), (3, 4), (3, 14),
(3, 7), (3, 17), (4, 15), (4, 8), (5, 10),
(5, 13), (5, 11), (5, 19), (6, 10), (6, 12),
(6, 9), (7, 18), (7, 17), (8, 15), (8, 11),
(8, 13), (8, 14), (9, 12), (9, 16), (10, 13),
(10, 12), (11, 13), (11, 19), (11, 15), (12, 13),
(12, 16), (12, 18), (13, 18), (13, 14), (13, 17),
(14, 17), (15, 19), (16, 18), (17, 18)]
s = 0
t = 2
s_e = [0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
P_max = 100
P_min = 0
P_s = 100
P_t = 0
eps = 2
d = {(0, 4): 50.0, (0, 15): 23.08679276123039, (0, 19): 19.849433241279208,
(0, 5): 50.0, (1, 5): 50.0, (1, 10): 39.395431207184416, (1, 6): 50.0,
(2, 6): 50.0, (2, 9): 39.6232255123179, (2, 16): 34.0, (2, 18): 44.687805943008655,
(2, 7): 50.0, (3, 8): 49.33558553417604, (3, 4): 50.0, (3, 14): 46.6476151587624,
(3, 7): 50.0, (3, 17): 47.01063709417263, (4, 15): 28.861739379323623,
(4, 8): 15.297058540778355, (5, 10): 21.2602916254693, (5, 13): 30.06659275674582,
(5, 11): 31.240998703626623, (5, 19): 37.33630940518894, (6, 10): 49.51767361255979,
(6, 12): 18.973665961010276, (6, 9): 13.038404810405298, (7, 18): 33.12099032335839,
(7, 17): 24.698178070456937, (8, 15): 32.01562118716424, (8, 11): 34.785054261852174,
(8, 13): 40.22437072223754, (8, 14): 11.40175425099138, (9, 12): 12.08304597359457,
(9, 16): 12.727922061357857, (10, 13): 21.2602916254693, (10, 12): 43.86342439892262,
(11, 13): 24.16609194718914, (11, 19): 13.038404810405298, (11, 15): 19.1049731745428,
(12, 13): 42.80186911806539, (12, 16): 14.142135623730951, (12, 18): 21.93171219946131,
(13, 18): 44.77722635447623, (13, 14): 38.41874542459709, (13, 17): 47.51841748206689,
(14, 17): 24.041630560342618, (15, 19): 12.041594578792296, (16, 18): 18.027756377319946,
(17, 18): 25.709920264364882}
c_e = [0.0, 26.773232628259667, 27.890360766258304, 28.29461418679745, 0.0, 29.02698684296589,
0.0, 25.37424381214926, 0.0, 26.609738071369257, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 27.258247702379347]
c_st = 50
c_dep = 3
M = 10
try:
#variables
m = Model("arslan")
e_alpha = m.addVars(nodes, vtype=GRB.CONTINUOUS, name="e_alpha")
e_beta = m.addVars(nodes, vtype=GRB.CONTINUOUS, name="e_beta")
e_plus = m.addVars(nodes, vtype=GRB.CONTINUOUS, name="e_plus")
x = m.addVars(arcs, vtype=GRB.BINARY, name="x")
v = m.addVars(nodes, vtype=GRB.BINARY, name="v")
r = m.addVars(nodes, vtype=GRB.BINARY, name="r")
d_cs = m.addVars(arcs, vtype=GRB.CONTINUOUS, name="d_cs")
d_cd = m.addVars(arcs, vtype=GRB.CONTINUOUS, name="d_cd")
#constraints
m.addConstrs((x.sum(i, j) - x.sum(j, i) == (1 if i == s else -1 if i == t else 0) for i, j in arcs), "solution_path")
m.addConstrs((e_beta[i] == e_alpha[i] + s_e[i] * e_plus[i] for i in nodes), "ele_balance")
m.addConstrs((M * (x[i, j] - 1) <= e_alpha[j] - e_beta[i] + eps * d_cd[i, j] for i, j in arcs), "ele_balance_on_path_lb")
m.addConstrs((e_alpha[j] - e_beta[i] + eps * d_cd[i, j] <= M * (1 - x[i, j]) for i, j in arcs), "ele_balance_on_path_ub")
m.addConstrs((P_min <= e_alpha[i] for i in nodes), "ele_bounds_enter_lb")
m.addConstrs((e_alpha[i] <= P_max for i in nodes), "ele_bounds_enter_ub")
m.addConstrs((P_min <= e_beta[i] for i in nodes), "ele_bounds_leave_lb")
m.addConstrs((e_beta[i] <= P_max for i in nodes), "ele_bounds_leave_ub")
m.addConstrs((e_plus[i] <= v[i] * P_max for i in nodes),"assign_v")
m.addConstrs((v[i] <= r[i] for i in nodes), "stopping_cost")
m.addConstr((e_alpha[s] == P_s), "ele_on_start")
m.addConstr((e_alpha[t] <= P_t), "ele_on_end")
m.addConstrs((d_cs[i, j] + d_cd[i, j] == d[i, j] for i, j in arcs), "distances_sum")
# #objective
objective = quicksum(c_e[i] * e_plus[i] for i in nodes) + quicksum(d[i, j] * c_dep * x[i, j] for i, j in arcs) + quicksum(c_st * r[i] for i in nodes)
m.SetObjective(objective, GRB.MINIMIZE)
m.optimize()
except GurobiError as e:
print('Error code ' + str(e.errno) + ': ' + str(e))
except AttributeError:
print('Encountered an attribute error')
-
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?. -
Can you try using m.setObjective() (lowercase "s") instead of m.SetObjective()?
1 -
Hello Eli,
thank you very much for super fast answer. Its working now. I apologise for posting question for a rookie mistake like this. I went through the code dozen of times and this little thing eluded me. Thank you!
0 -
I have the same issue but don't know what the problem is. Could someone check it, please?
try:
# Create the primary supply chain model
primarySC = gp.Model("Primary Supply Chain Model")
# Create variables
P_n = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_n")
P_o = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_o")
Q = primarySC.addVars(set_p, set_i, set_t, set_t, vtype=GRB.CONTINUOUS, lb=0, name="q")
U_n = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_n")
U_o = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_o")
Z = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="z")
Y = primarySC.addVars(set_p, set_i, set_t, vtype=GRB.BINARY, name="y")
# Add constraint: 6b
###########################################
def tau_l(p,tau): # because in constraints 6_b, t is a function of tau it was needed to calculate each t dependent to each tau
global new_set_t
new_set_t = tau.copy()
global j
j=0
for value in tau:
if j < (len(tau) - l[p]):
new_set_t.remove(value)
j +=1
#print(j)
return new_set_t
#tau_l('p1',set_t)
cons_6b = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] + U_n[p,tau] == d_n(p,t) for i in set_i for t in tau_l(p,tau)) for tau in set_t for p in set_p)
primarySC.addConstrs(cons_6b, "cons_6b")
# Add constraint: 6c
###########################################
def tau_f(p,tau): # because in constraints 6_c, t is a function of tau it was needed to calculate each t dependent to each tau
global new_set_tau
new_set_tau = tau.copy()
global j
j=0
for value in tau:
if (j < (len(tau) - f_hat[p])) or (j > ( len(tau) - l[p]) + 1 ):
new_set_tau.remove(value)
j +=1
#print(j)
return new_set_tau
cons_6c = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] + U_o[p,tau] == d_o(p,t) for i in set_i for t in tau_f(p,tau)) for tau in set_t for p in set_p)
primarySC.addConstrs(cons_6c, "cons_6c")
# Add constraint: 6d
###########################################
def t_f_1(p,tau): # because in constraints 6_d, t is a function of tau it was needed to calculate each t dependent to each tau
t = tau - f_hat[p] - 1
return t
cons_6d = (gp.quicksum(kappa[p,(t_f_1(p,tau)),tau]*Q[p,i,(t_f_1(p,tau)),tau] for i in set_i) == Z[tau] for tau in set_t)
primarySC.addConstrs(cons_6d, "cons_6d")
# Add constraint: 6e
###########################################
def tau_t(p,t): # because in constraints 6_e, t is a function of tau it was needed to calculate each t dependent to each tau
global new_set_tau_t
new_set_tau_t = ()
new_set_tau_t = set_t.copy()
global j
j=0
for value in set_t:
if j < int(t[1])-1:
new_set_tau_t.remove(value)
j +=1
#print(j)
return new_set_tau_t
cons_6e = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] for tau in tau_t(p,t)) - delta[p,i,t]*Y[p,i,t] <= 0 for i in set_i for t in set_t)
primarySC.addConstrs(cons_6d, "cons_6e")
# Set objective
###########################################
obj_ksi = gp.quicksum(s[p,i]*Y[p,i,t] for p in set_p for t in set_t for i in set_i)
-gp.quicksum(alpha_n[p]*P_n[p] + alpha_o[p]*P_o[p] - beta_n[p]*(P_n[p]**2)
- teta_o[p]*(P_o[p]**2) + (beta_o[p] + teta_n[p])*P_n[p]*P_o[p]
for p in set_p)*len(set_t)
obj_phi = gp.quicksum(f_n_pt[p,t]*U_n[p,t] + f_o_pt[p,t]*U_o[p,t] - (P_n[p]*w_n[p,s] + P_o[p]*w_o[p,s])
+ gp.quicksum(c(p,i,t,tau)*Q[p,i,t,tau] for i in set_i for tau in set_t)
for s in set_s for t in set_t for p in set_p)
obj_func= obj_ksi + 1/len(set_s)*obj_phi
primarySC.setObjective(obj_func, GRB.MINIMIZE)
# Optimize model
primarySC.optimize()
for v in m.getVars():
print('%s %g' % (v.VarName, v.X))
print('Obj: %g' % m.ObjVal)
except gp.GurobiError as e:
print('Error code ' + str(e.errno) + ': ' + str(e))
except AttributeError:
print('Encountered an attribute error')0 -
Hi Reza,
Please edit your code to be a minimal reproducible example, remove the try-except statements and include the resulting traceback.
- Riley
0 -
Hi Riley,
I appreciate your help,
I have made my example, MRE.
import gurobipy as gp
from gurobipy import GRB
#--------------
import numpy as np
import random
print (' ------------ Libraries are imported ')
# ---------------- sets
# sets: data
set_i = ['i1', 'i2']
set_t = ['t1', 't2', 't3', 't4', 't5', 't6', 't7']
set_p = ['p1', 'p2']
set_s = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10']
# ---------------- parameters
# parameters: functions
def kappa(p,period,tau_period):
t= int(period[1])
tau= int(tau_period[1])
defer = tau - t
rhoo = rho[p]
global result
result = 1.0
for i in range(defer):
result = round(result*(1-rhoo), 4)
return result
def c(p,i,period,tau_period):
t= int(period[1])
tau= int(tau_period[1])
defer = tau - t
#rhoo = rho[p]
global result
result = 0
for n in range(defer):
result += h[p]*kappa(p,period,"t"+str(t+n+1))
return round(r[str(p) ,str(i)] + result, 4)
# parameters: data
rho = {'p1': 0.02,'p2': 0.03}
l = {'p1': 1,'p2': 2}
f_hat = {'p1': 2,'p2': 3}
h = {'p1': 1,'p2': 1.5}
f_n_pt, f_o_pt, g_n_pt, g_o_pt = {},{},{},{}
for t in set_t:
for p in set_p:
f_n_pt[p, t] = 1000
f_o_pt[p, t] = 1500
g_n_pt[p, t] = 900
g_o_pt[p, t] = 1200
w_n, w_o = {},{}
for s in set_s:
w_n['p1', s] = random.randint(0,150) # deterministic w for new products
w_n['p2', s] = random.randint(0,150) # deterministic w for new products
w_o['p1', s] = random.randint(0,175) # deterministic w for old products
w_o['p2', s] = random.randint(0,175) # deterministic w for old products
teta_o = {'p1': 1.5,'p2': 1.9}
teta_n = {'p1': teta_o['p1'] * 1.5,'p2': teta_o['p2'] * 1.9}
beta_o = {'p1': 2.5,'p2': 2}
beta_n = {'p1': beta_o['p1'] * 1.5,'p2': beta_o['p2'] * 1.9}
alpha_n = {'p1': 450,'p2': 400} # price can be p1 : 1.1 $/unit | p2 : 1.7 $/unit
alpha_o = {'p1': 150,'p2': 110} # price can be p1 : 0.8 $/unit | p2 : 1.3 $/unit
s, r = {},{}
for p in set_p:
s[p,'i1']= round(random.uniform(150,250), 2)
s[p,'i2']= round(random.uniform(250,350), 2)
r[p,'i1']= round(random.uniform(25,30), 2)
r[p,'i2']= round(random.uniform(20,25), 2)
#delta = df_delta['delta_pis'].to_dict() # scenario based delta
for t in set_t:
delta = {
('p1','i1',t): alpha_n['p1'] + random.randint(0,int(alpha_n['p1']*0.1)), # alpha + random(0.1)
('p2','i1',t): alpha_n['p2'] + random.randint(0,int(alpha_n['p2']*0.1)),
('p1','i2',t): alpha_n['p1'] + random.randint(0,int(alpha_n['p1']*0.1)),
('p2','i2',t): alpha_n['p2'] + random.randint(0,int(alpha_n['p2']*0.1)),
}
# nonstationary demand
def d_n(p,t):
demand = alpha_n[p] - beta_n[p]*P_n[p] + beta_o[p]*P_o[p] + w_n[p,s]
return demand
def d_o(p,t):
demand = alpha_o[p] - teta_o[p]*P_o[p] + teta_n[p]*P_n[p] + w_o[p,s]
return demand
print (' ------------ Data Imported ')
# Create the primary supply chain model
primarySC = gp.Model("Primary Supply Chain Model")
# Create variables
P_n = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_n")
P_o = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_o")
Q = primarySC.addVars(set_p, set_i, set_t, set_t, vtype=GRB.CONTINUOUS, lb=0, name="q")
U_n = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_n")
U_o = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_o")
Z = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="z")
Y = primarySC.addVars(set_p, set_i, set_t, vtype=GRB.BINARY, name="y")
# Add constraint: 6b
###########################################
cons_6b = (gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau] + U_n[p,tau] >= d_n(p,t) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0))) for tau in set_t for p in set_p)
primarySC.addConstrs(cons_6b, "cons_6b")
# Add constraint: 6c
###########################################
cons_6c = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] + U_o[p,tau] >= d_o(p,t) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - f_hat[p])) and (int(t[1]) <= (int(tau[1]) - l[p] + 1)) and ((int(tau[1]) - f_hat[p]) > 0))) for tau in set_t for p in set_p)
primarySC.addConstrs(cons_6c, "cons_6c")
# Add constraint: 6d
###########################################
def t_f_1(p,tau): # because in constraints 6_d, t is a function of tau it was needed to calculate each t dependent to each tau
t = "t" + str(int(tau[1]) - f_hat[p] - 1)
return t
cons_6d = (gp.quicksum(kappa[p,(t_f_1(p,tau)),tau]*Q[p,i,(t_f_1(p,tau)),tau] for i in set_i) == Z[tau] for tau in set_t if (int(tau[1]) - f_hat[p] - 1) > 0)
primarySC.addConstrs(cons_6d, "cons_6d")
# Add constraint: 6e
###########################################
cons_6e = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] for tau in set_t if tau >= t) - delta[p,i,t]*Y[p,i,t] <= 0 for i in set_i for t in set_t)
primarySC.addConstrs(cons_6d, "cons_6e")
# Set objective
###########################################
obj_ksi = gp.quicksum(s[p,i]*Y[p,i,t] for p in set_p for t in set_t for i in set_i)
-gp.quicksum(alpha_n[p]*P_n[p] + alpha_o[p]*P_o[p] - beta_n[p]*(P_n[p]**2)
- teta_o[p]*(P_o[p]**2) + (beta_o[p] + teta_n[p])*P_n[p]*P_o[p]
for p in set_p)*len(set_t)
obj_phi = gp.quicksum(f_n_pt[p,t]*U_n[p,t] + f_o_pt[p,t]*U_o[p,t] - (P_n[p]*w_n[p,s] + P_o[p]*w_o[p,s])
+ gp.quicksum(c(p,i,t,tau)*Q[p,i,t,tau] for i in set_i for tau in set_t)
for s in set_s for t in set_t for p in set_p)
obj_func= obj_ksi + 1/len(set_s)*obj_phi
primarySC.setObjective(obj_func, GRB.MINIMIZE)
# Optimize model
primarySC.optimize()
for v in m.getVars():
print('%s %g' % (v.VarName, v.X))
print('Obj: %g' % m.ObjVal)The traceback is as below:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-5-c96e14f2af17> in <module> 16 ########################################### 17 cons_6b = (gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau] + U_n[p,tau] >= d_n(p,t) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0))) for tau in set_t for p in set_p) ---> 18 primarySC.addConstrs(cons_6b, "cons_6b") 19 20 # Add constraint: 6c src\gurobipy\model.pxi in gurobipy.Model.addConstrs() src\gurobipy\model.pxi in gurobipy.Model.addConstr() TypeError: unsupported operand type(s) for -: 'gurobipy.LinExpr' and 'NoneType'
0 -
Hi Reza,
There's an issue with your d_n and d_o function, in that they try to use s as an index, e.g. w_n[p,s], but s is a dictionary. I suspect this is a typo, but it will need to be fixed.
You will also need to address the generator you are passing to the quicksum function in the creation of cons_6b. At the moment it is trying to sum together constraints of the form:kappa(p,t,tau)*Q[p,i,t,tau] + U_n[p,tau] >= d_n(p,t)
It may just be a case of mismatched parentheses.
- Riley
1 -
Hi Riley,
Thank you very much for your help,
I solved the problems thanks to your help.
I solved the second problem (quicksum) by replacing:
gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau] + U_n[p,tau] >= d_n(p) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0)))
with the following corrected code:
gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau] + U_n[p,tau] for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0))) >= d_n(p)
Thanks,
0 -
Hi Reza,
No problem, good to hear you were able to resolve it. My only other advice is that some indentation, limiting line length, and use of functions could help readability of the code.Eg
def meaningful_function_name(i,t,tau,p):
tau_1, t_1 = int(tau[1]), int(t[1])
return 0 < tau_1 - l[p] <= t_1 <= tau_1
gp.quicksum(
kappa(p,t,tau)*Q[p,i,t,tau] + U_n[p,tau]
for i in set_i
for t in set_t
if meaningful_function_name(i,t,tau,p)
)
- Riley1 -
Hi Riley,
Many thanks for your fantastic support and advice !!
Cheers.
0
Post is closed for comments.
Comments
10 comments