GurobiError: Invalid argument to LinExpr multiplication
AnsweredHi,
I'm trying to compile my model but i get this error.
Can someone help me to fix that?
Thks
-
Please provide a minimal reproducible example, i.e., try to reduce your model as far as possible with all required parameters such that the error still occurs. Moreover, don't provide screenshots, because one cannot copy paste your code from a screenshot making help more tedious (additionally, one cannot see what is going on on the right side of your code).
0 -
Hi,
Thks for the reply. I simplifly the problem like this.
import numpy as np
import gurobipy as gp
from gurobipy import GRB
from gurobipy import quicksum
import random
import string
random.seed(0)
rnd=np.random
rnd.seed(0)
nb_items=7
list_article=[]
for index in range(1,nb_items+7):
item=random.choice(string.ascii_lowercase)
while item not in list_article and len(list_article)<7:
list_article.append(item)
print(list_article)
nb_clients=4
N=[i for i in range(1,nb_clients+1)]
nber_pickers=2
lot= [j for j in range(1,nber_pickers+1)]
K=3
G=[k for k in range(1,K+1)]
L=100
W=40
M=100
Q=50
d={}
d[(1,1)]=47,76
d[(1,2)]=62,35
d[(1,3)]=0
d[(2,1)]=0
d[(2,2)]=0
d[(2,3)]=81,21
d[(3,1)]=0
d[(3,2)]=0
d[(3,3)]=0
d[(4,1)]=0
d[(4,2)]=0
d[(4,3)]=0
Qte=range(1,7)
mqte_list= []
for i in N:
limit=rnd.randint(1,7)
Order ={i:random.sample(list_article,limit)}
print(Order)
qte=random.sample(Qte,limit)
print(qte)
sum=0
for elem in range(0,len(qte)):
sum=sum+qte[elem]
mqte=sum
mqte_list.append(mqte)
print(mqte)
print(mqte_list)
A=[(i,j) for i in N for j in lot]
B=[(j, k) for j in lot for k in G ]
C=[(i, k) for i in N for k in G ]
mdl = gp.Model("OBP")
x=mdl.addVars(A,vtype=GRB.BINARY,name='x')
p=mdl.addVars(B, vtype=GRB.BINARY,name='p')
y=mdl.addVars(B, vtype=GRB.BINARY,name='y')
c=mdl.addVars(lot, vtype=GRB.BINARY, name='c')
h_r=mdl.addVars(lot,vtype=GRB.CONTINUOUS, name='h_r')
h_l=mdl.addVars(lot,vtype=GRB.CONTINUOUS, name='h_l')
u=mdl.addVars(B,vtype=GRB.CONTINUOUS,name='u')
v=mdl.addVars(lot,vtype=GRB.INTEGER, name='v')
mdl.setObjective(
2*quicksum(quicksum(u[j,k] for k in G) for j in lot)+
2*quicksum( h_r[j]+h_l[j] for j in lot)+
2*L*quicksum(v[j]-c[j] for j in lot), GRB.MINIMIZE)
mdl.addConstrs(quicksum(x[(i,j)] for j in lot)==1 for i in N)
mdl.addConstrs(x[(i,j)]<=x[(j,j)] for i in N for j in lot)
mdl.addConstrs(quicksum(mqte_list[i-1]*x[(i,j)] for i in N)<=Q for j in lot)
mdl.addConstrs(y[j,k]<= quicksum(d[(i,k)]*x[(i,j)]for i in N) for j in lot for k in G)
mdl.addConstrs(quicksum(d[(i,k)]*x[(i,j)] for i in N)<=M*y[j,k] for j in lot for k in G)
mdl.addConstrs((ka-k)*W*y[j,k]<= h_r[j] for j in lot for ka in range(k+1,K))
mdl.addConstrs((k-ka)*W*y[j,k]<= h_l[j] for j in lot for ka in range(1,k-1))
mdl.addConstrs(quicksum(y[j,k] for k in G)+c[j]==2*v[j] for j in lot)
mdl.addConstrs(d[i,k]*x[i,j]<= u[j,k]+M(1-p[j,k])+M(1-c[j]) for i in N for j in lot for k in range(2,K))
mdl.addConstrs(p[j,k]<= y[j,k] for j in lot for k in G)
mdl.addConstrs(y[j,k]- quicksum(y[j,l] for l in range(k+1,K))<= p[j,k] for j in lot for k in G)
mdl.optimize()
vals = mdl.getAttr('x',x)
selected = gp.tuplelist((i,j) for i,j in vals.keys() if vals[i,j] > 0.5)
print(selected)
print ("Optimal value=", int(mdl.ObjVal))0 -
The problematic constraints are the ones that use \( \texttt{d} \):
mdl.addConstrs(y[j,k]<= quicksum(d[(i,k)]*x[(i,j)]for i in N) for j in lot for k in G)
mdl.addConstrs(quicksum(d[(i,k)]*x[(i,j)] for i in N)<=M*y[j,k] for j in lot for k in G)
mdl.addConstrs(d[i,k]*x[i,j]<= u[j,k]+M(1-p[j,k])+M(1-c[j]) for i in N for j in lot for k in range(2,K))Three of your \(\texttt{d}\) values are tuples:
d[(1,1)]=47,76
d[(1,2)]=62,35
d[(1,3)]=0
d[(2,1)]=0
d[(2,2)]=0
d[(2,3)]=81,21As a result, you end up multiplying a tuple with a variable object, which does not make sense. For example, for \(\texttt{i=1}\), \(\texttt{j=1}\), and \(\texttt{k=1}\), the first of those constraint families attempts to multiply the variable \( \texttt{x[1,1]} \) with the tuple \( \texttt{(47, 76)} \). The variable should be multiplied by a single number.
Why do you define three \( \texttt{d} \) values to be tuples?
0 -
Hi,
i actually defined "d" as a dictionnary, so that i can call the values of the couple (i,k) in the constraint for the multiplication with the binary variables x. That was the idea but i miss something probably.
How can i do it well?
Thks
0 -
It's okay to use a tuple as the dictionary key. The problem is that some of the dictionary values are tuples. These tuples are then multiplied by variables. Here is an example showing the source of the error:
>>> d[1,1]
(47, 76)
>>> x[1,1]
<gurobi.Var x[1,1]>
>>> d[1,1]*x[1,1]
Traceback (most recent call last):
File "src/gurobipy/var.pxi", line 281, in gurobipy.Var.__rmul__
TypeError: float() argument must be a string or a number, not 'tuple'
During handling of the above exception, another exception occurred:
[...]
gurobipy.GurobiError: Invalid argument to LinExpr multiplicationWhat is \( \texttt{(47, 76) * x[1,1]} \) supposed to mean? I would expect \( \texttt{d[1,1]} \), \( \texttt{d[1,2]}\), and \(\texttt{d[2,3]}\) to be numbers instead of tuples.
0 -
ok Thks.
0
Please sign in to leave a comment.
Comments
6 comments