Stochastic Optimizationproblem with 3 Stages
AnsweredI have a Problem with 3 Stage stochastic Optimization Program i writting right now:
The goal is, that in the first stage raw materials are harvested, in the second stage the product ist produced and in the final stage the product get to the customer.
My problem is in the objectiv function: the error i get from python is: "'int' object is not subscriptable" and i think its because of the "q in produce[i]" but i dont know a different solution
from gurobipy import *
#Raw Materials
I,M = multidict({1:[(3000,2800,2500)], 2:[(3000,2700,2600)], 3:[(3000.2500,2800)], 4:[(3000,2900,2300)]})
#Production
J,Max,Min = multidict({1:[3000,200], 2:[3000,200],3:[3000,200], 4:[3000,200]})
#Raw materials q at localisation i
produce = {1:['switch'], 2:['seed'], 3:['salz'], 4:['süß']}
#Demand for product p at demandcenter k in scenario s and period t
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))
}
#Capacity of raffinerie j
Kapa = [0,500,600,500,300,250]
# Probability of scenario s
Prob = [0.333,0.333,0.333]
EPS = 1.e6
K = set([k for (k,p) in d])
P = set([p for (k,p) in d])
#Periods
T = [1,2,3]
#Scenarios
S = [1,2,3]
#Fix costs
f = 4000
f_Bio = 5000
#transportation costs
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("multicommodity 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,t1]  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)
#Problem is in the objectiv line: i think its something with q in produce[i]
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()

It looks like this was answered in Optimizationproblem with Exception Unable to convert argument to an expression – Gurobi Support Portal: there is a parenthesis error causing this problem.
If you wind up with a similar issue, I recommend making sure each quicksum's final end parenthesis is in the right spot.To troubleshoot, it may help to create each term one at a time. Once you know that each is written correctly, you can combine them.
For example, you can start with the first term in your objective. Try setting an objective with only this term. Then make sure your code executes properly in model.setObjective(). Then you can do the same for term 2. Here is how it should look:
# Test for term 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)))
, GRB.MINIMIZE)
# Test for term 2
model.setObjective( quicksum(Prob[s]* quicksum(f*y[j] for j in J )for s in range(0,len(S)))
, GRB.MINIMIZE)If those two terms run without error, then you have their parenthesis correct. Now, you can combine them as follows:
# Test with term 1 + term 2
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)))
, GRB.MINIMIZE)Next, you can do this for the remainder of your objective.
Please sign in to leave a comment.
Comments
1 comment