Skip to main content

GurobiError: Invalid argument to LinExpr multiplication

Answered

Comments

6 comments

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    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
  • Eli Towle
    Gurobi Staff Gurobi Staff

    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,21

    As 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
  • Eli Towle
    Gurobi Staff Gurobi Staff

    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 multiplication

    What 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.