Skip to main content

Optimizationproblem with Exception Unable to convert argument to an expression

Answered

Comments

6 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff Gurobi Staff
    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?.
  • Alison Cozad
    • Gurobi Staff Gurobi Staff

    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
  • Leon Breukel
    • Gurobi-versary
    • First Comment
    • First Question

    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
  • Alison Cozad
    • Gurobi Staff Gurobi Staff

    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
  • Alison Cozad
    • Gurobi Staff Gurobi Staff

    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
  • Leon Breukel
    • Gurobi-versary
    • First Comment
    • First Question

    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.