Optimizationproblem with Exception Unable to convert argument to an expression
AnsweredI have the following problem:
i wrote a little programm to minimize the CO2 cost from transportation between to points I and J.
The only Constraint is, that not more products will be send to location j then there are products from location i.
I get the error "Unable to convert argument to an expression". Can someone help me please?
from gurobipy import *
#Amount of products at location i
I = (500,300,200)
J =(1,2,3)
Dij = {(0,0): 100, (0,1):200, (0,2): 200, (0,3): 400, (1,2):200, (1,3):600, (2,3):150}
#Mulitiplikator
α = 2.5
model = Model('Probe')
model.modelSense = GRB.MINIMIZE
X = {}
for i in range(len(I)):
for j in range(len(J)):
X[i,j]=model.addVar(vtype=GRB.INTEGER, lb=0)
model.update()
model.setObjective(α*Dij[i,j]*X[i,j] for i in range(len(I)) for j in range(len(J))
)
for i in range(len(I)):
for j in range(lenJ):
model.addConstrs(X[i,j] <= I[i])
model.optimize()
-
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?. -
Your objective is currently defined as 9 separate elements (\(\texttt{len(I) * len(J)}\)):
\(\alpha \cdot D_{ij} \cdot X_{ij} \quad \forall i \in I, j \in J\)
Gurobi is expecting a single expression as the objective. Did you intend to make a nested summation for your objective like the following?
\(\displaystyle \sum_{i\in I} \displaystyle \sum_{j \in J} \alpha \cdot D_{ij} \cdot X_{ij} \)
If so, there are a number of ways to do this. For example, you could use the quicksum() or tupledict.sum(). These are both shown in the netflow.py example. If you want a more detailed look at how to do this, check out Python I: Introduction to Modeling with Python - Gurobi. It includes a video tutorial and examples with jupyter notebooks for you to follow. It also includes an example of using nested summations.
1 -
Hello Alison,
thank you really much i got quiet further with your answer! now i have a little different problem:
I have a supply chain with 3 stages: 1. stage i, 2. stage j and 3. stage k
Now when i try to implement the first stage to the second and third stage i get this problem:
'int' object is not subscriptable in the objective function. I think its because of the part "q in produce[i] but i dont know how i coul implement it otherwise?
from gurobipy import *
I,M = multidict({1:[(3000,2800,2500)], 2:[(3000,2700,2600)], 3:[(3000.2500,2800)], 4:[(3000,2900,2300)]})
J,Max,Min = multidict({1:[3000,200], 2:[3000,200],3:[3000,200], 4:[3000,200]})
produce = {1:['switch'], 2:['seed'], 3:['salz'], 4:['süß']}
d = {(1,'Butanol'):((0,0,0),(80,70,90),(80,70,90),(100,110,90)), (1,'Biodiesel'):((0,0,0),(90,80,100),(95,85,75),(85,75,95)),
(2,'Butanol'):((0,0,0),(280,270,290),(280,300,290),(280,260,270)), (2,'Biodiesel'):((0,0,0),(120,130,110),(150,170,160),(110,120,130)),
(3,'Butanol'):((0,0,0),(240,250,260),(230,250,240),(240,250,260)), (3,'Biodiesel'):((0,0,0),(140,150,130),(150,140,130),(120,150,110)),
(4,'Butanol'):((0,0,0),(180,170,160),(130,120,140),(150,160,170)), (4,'Biodiesel'):((0,0,0),(80,70,60),(60,70,50),(80,70,60)),
(5,'Butanol'):((0,0,0),(180,170,190),(180,170,190),(180,170,190)), (5,'Biodiesel'):((0,0,0),(80,70,90),(80,100,90),(100,80,90))
}
Kapa = [0,500,600,500,300,250]
Prob = [0.333,0.333,0.333]
EPS = 1.e-6
K = set([k for (k,p) in d])
P = set([p for (k,p) in d])
T = [1,2,3]
S = [1,2,3]
f = 4000
f_Bio = 5000
weight = {'Butanol':5, 'Biodiesel':2}
cost = {(1,1):4, (1,2):6, (1,3):9, (1,4):3,
(2,1):5, (2,2):4, (2,3):7, (2,4):5,
(3,1):6, (3,2):8, (3,3):4, (3,4):6,
(4,1):8, (4,2):5, (4,3):3, (4,4):6,
(5,1):10, (5,2):8, (5,3):4, (5,4):9
}
weight_bio = {'switch':5, 'seed':2, 'salz':4, 'süß':4}
cost_bio = {(1,1):4, (1,2):6, (1,3):9, (1,4):3,
(2,1):5, (2,2):4, (2,3):7, (2,4):5,
(3,1):6, (3,2):8, (3,3):4, (3,4):6,
(4,1):8, (4,2):5, (4,3):3, (4,4):6,
(5,1):10, (5,2):8, (5,3):4, (5,4):9
}
c_bio = {}
for i in I:
for j in J:
for q in produce[i]:
c_bio[i, j, q] = cost_bio[i,j] * weight_bio[q]
c = {}
for k in K:
for j in J:
for p in P:
c[k, j, p] = cost[k,j] * weight[p]
model = Model("multi-commodity transportation")
x,y = {},{}
xBio,yBio = {},{}
L = {}
z = {}
for k,j,p in c:
for t in range(1,len(T)+1):
for s in range(0,len(S)):
x[k,j,p,t,s] = model.addVar(vtype="C", name="x[%s,%s,%s,%s,%s]" % (k, j, p, t,s))
for j in J:
y[j] = model.addVar(vtype="B", name="y(%s)"%j)
for j in J:
for p in P:
z[j,p] = model.addVar(vtype="B", name="z(%s,%s)"%(j,p))
for k in K:
for p in P:
for t in range(0,len(T)+1):
L[k,p,t] = model.addVar(vtype="C", name="L[%s,%s,%s]"%(k,p,t))
for i,j,q in c_bio:
for t in range(1,len(T)+1):
for s in range(0,len(S)):
xBio[i,j,q,t,s] = model.addVar(vtype="C", name="x[%s,%s,%s,%s,%s]" % (i, j, q, t,s))
for i in I:
yBio[i]= model.addVar(vtype="B", name="y(%s)"%i)
model.update()
for k in K:
for p in P:
model.addConstr(L[k,p,0] == 0)
for k in K:
for t in range(0,len(T)+1):
model.addConstr(quicksum(L[k,p,t] for p in P) <= Kapa[k])
for k in K:
for p in P:
for t in range(1,len(T)+1):
for s in range(0,len(S)):
model.addConstr(quicksum(x[k,j,p,t,s]*z[j,p]for j in J if (k,j,p,t,s) in x) + L[k,p,t-1] - d[k,p][t][s] == L[k,p,t])
for j in J:
for t in range(1,len(T)+1):
for s in range(0,len(S)):
model.addConstr(quicksum(x[k,j,p,t,s]*z[j,p] for (k,j2,p,t2,s) in x if j2 == j if t == t2) <= Max[j]*y[j], "Capacity[%s]" % j)
for j in J:
for t in range(1,len(T)+1):
for s in range(0,len(S)):
model.addConstr(quicksum(x[k,j,p,t,s]*z[j,p] for (k,j2,p,t2,s) in x if j2 == j if t == t2) >= Min[j]*y[j], "Capacity[%s]" % j)
for j in J:
for t in range(1,len(T)+1):
for s in range(0,len(S)):
for q in produce[i]:
model.addConstr(quicksum(x[k,j,p,t,s]*z[j,p] for (k,j2,p,t2,s) in x if j2 == j if t == t2) <= quicksum(xBio[i,j,q,t,s]*yBio[i] for (i,j,q,t,s) in xBio))
for j in J:
model.addConstr(quicksum(z[j,p] for p in P)<=1)
model.setObjective(quicksum(Prob[s] *quicksum(c[k,j,p]*x[k,j,p,t,s] for k in K for j in J for p in P for t in range(1,len(T)+1))for s in range(0,len(S))) + quicksum(Prob[s]* quicksum(f*y[j] for j in J )for s in range(0,len(S))+
quicksum(Prob[s] *quicksum(c_bio[i,j,q]*xBio[i,j,q,t,s] for i in I for j in J for q in produce[i] for t in range(1,len(T)+1))for s in range(0,len(S))) + quicksum(Prob[s]* quicksum(f_Bio*y[i] for i in I )for s in range(0,len(S)))), GRB.MINIMIZE)
model.update()
model.optimize()
print ("Optimale Emissionen:", model.ObjVal, "kgCo2")
for k,j,p,t,s in x:
if x[k,j,p,t,s].X > EPS:
print ("Sende %10g Einheiten %s von Raffinerie %3d zu Distributionszenter %3d in Periode %3d in Szenario %3d" % (x[k,j,p,t,s].X, p, j, k,t,s) )
for k,p,t in L:
if L[k,p,t].X > EPS:
print ("Lagerbestand von %10g Einheiten %s an Nachfragezentrum %3d in Periode %3d" % (L[k,p,t].X, p,k,t) )
Raffinerien=[]
for k,j,p,t,s in x:
volume1 = ([k,j], x[k,j,p,t,s].x)
if(volume1[1] > 0):
facilities1 = ([j],y[j].x)
Raffinerien.append(facilities1[0])
GenutzteRaffinerien=[]
for element in Raffinerien:
if element not in GenutzteRaffinerien:
GenutzteRaffinerien.append(element)
print ("Genutze Raffinerien:", GenutzteRaffinerien)
0 -
I suspect this is a parenthesis issue. Right now, you have the following objective:
\( \displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{k\in K}\displaystyle \sum_{j\in J}\displaystyle \sum_{p\in P}\displaystyle \sum_{t = 1}^{|T|+1} c_{kjp}x_{kjpts} \\ + \displaystyle \sum_{s=0}^{|S|} p_s \left( \displaystyle \sum_{j\in J}f\cdot y_j + \displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{i\in I}\displaystyle \sum_{j\in J}\displaystyle \sum_{q\in \mathrm{product}_i}\displaystyle \sum_{t = 1}^{|T|+1} c^\mathrm{bio}_{ijq}x^\mathrm{bio}_{ijqts} + \displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{i\in I} f^\mathrm{bio}y_i \right) \)
This is defined by this setObjective() call:
model.setObjective(quicksum(Prob[s] *quicksum(c[k,j,p]*x[k,j,p,t,s] for k in K for j in J for p in P for t in range(1,len(T)+1))for s in range(0,len(S))) + quicksum(Prob[s]* quicksum(f*y[j] for j in J )for s in range(0,len(S))+
quicksum(Prob[s] *quicksum(c_bio[i,j,q]*xBio[i,j,q,t,s] for i in I for j in J for q in produce[i] for t in range(1,len(T)+1))for s in range(0,len(S))) + quicksum(Prob[s]* quicksum(f_Bio*y[i] for i in I )for s in range(0,len(S)))), GRB.MINIMIZE)Here there is a nested summation over \(s\) inside of a summation over \(s\). The nesting of a summation over the same index is causing the error.
Instead, I suspect you wanted to write:
\(\displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{k\in K}\displaystyle \sum_{j\in J}\displaystyle \sum_{p\in P}\displaystyle \sum_{t = 1}^{|T|+1} c_{kjp}x_{kjpts} + \displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{j\in J}f\cdot y_j \\ + \displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{i\in I}\displaystyle \sum_{j\in J}\displaystyle \sum_{q\in \mathrm{product}_i}\displaystyle \sum_{t = 1}^{|T|+1} c^\mathrm{bio}_{ijq}x^\mathrm{bio}_{ijqts} + \displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{i\in I} f^\mathrm{bio}y_i \)
This can be made by moving one end parentheses with the following code:
model.setObjective(quicksum(Prob[s] *quicksum(c[k,j,p]*x[k,j,p,t,s] for k in K for j in J for p in P for t in range(1,len(T)+1))for s in range(0,len(S))) + quicksum(Prob[s]* quicksum(f*y[j] for j in J )for s in range(0,len(S)))+
quicksum(Prob[s] *quicksum(c_bio[i,j,q]*xBio[i,j,q,t,s] for i in I for j in J for q in produce[i] for t in range(1,len(T)+1))for s in range(0,len(S))) + quicksum(Prob[s]* quicksum(f_Bio*y[i] for i in I )for s in range(0,len(S))), GRB.MINIMIZE)Is this the objective you were intending to write?
1 -
One last item, I suspect you want the last term in the objective to be
\(\displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{i\in I} f^\mathrm{bio}y^\mathrm{bio}_i \)
rather than
\(\displaystyle \sum_{s=0}^{|S|} p_s \cdot \displaystyle \sum_{i\in I} f^\mathrm{bio}y_i \)
1 -
Hello Alison,
yes you´re totally right, this was my intending objectiv! I wrote the code so often that i didn´t recognised this error, thank you very much! Without your help i would have sit there hours to find this...
0
Post is closed for comments.
Comments
6 comments