Skip to main content

gurobipy.GurobiError: Invalid argument to QuadExpr multiplication

Answered

Comments

4 comments

  • Zeynel Batuhan Organ
    Gurobi-versary
    First Comment
    First Question

    I think the problem is in this line, I need this multiplication. I can't find a way to fix it.

    o = o * nt[t] * 1.0/n
    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    It seems like the term computed via \(\texttt{quicksum}\) is a quadratic expression, because \(\texttt{nkt}\) and \(\texttt{nt_div}\) are both optimization variables. Is this correct? If yes, then you get the error because you try to construct a multilinear term

    nkt[t,k]*nt_div[t]*nt[t]

    which is not supported by Gurobi. You can model multilinear terms via auxiliary variables and constraints, cf. How do I model multilinear terms in Gurobi?

    In your particular case, for a fixed \(t\), you are actually computing

    \[\left(\sum_k 2\cdot \text{nkt}_{t,k}\cdot \text{ntdiv}_{t} \right)\cdot \text{nt}_{t}\]

    with \(\text{ntdiv}_{t} = \frac{1}{\text{nt}_t}\) which simplifies to

    \[\sum_k 2\cdot \text{nkt}_{t,k} \]

    meaning that you don't need the additional multiplication at all.

    Best regards, 
    Jaromił

    0
  • Zeynel Batuhan Organ
    Gurobi-versary
    First Comment
    First Question

    Hi, 

    Thanks for your response. I think I was lost while coding so there are some typo's. Better send you the expression itself.

    For every t, I want to calculate this expression in objective function. Not sure if this is possible.

    where ntdiv is like below, since gurobi does not allow division with a d.v,

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Thanks for the update. This clarifies a lot. There are couple of possibilities here to approach the term you want to model. In any approach, you have to introduce auxiliary variables and constraints to model your term in a quadratic model. In the following, index \(t\) is fixed.

    \[\begin{align}
    w_{t,k} &= \text{ntdiv}_t \cdot \text{nkt}_{k,t} \,\, \forall k\\
    z_{t} &= \sum_k w_{t,k}^2
    \end{align}\]

    From here you can use \(z_t\) to model \(\text{nt}_t \cdot z_t  \cdot \frac{1}{n}\).

    In your code, this would be similar to

    w = m.addVars(nodes, K, lb=-GRB.INFINITY)
    z = m.addVars(nodes)
    sum_t = 0
    for t in nodes:
    m.addConstrs(w[t,k] == ntdiv[t] * nkt[k,t] for k in K)
    m.addConstr(z[t] == w[t,k]*w[t,k])
    sum_t += z[t] * nt[t] * 1.0/n
    #[...]

    Note that I explicitly set the lower bound of \(w\) variables to \(-\infty\) because it might get negative (depending on the bounds of your other optimization variables) and the default lower bound for variables is \(0\).

    Alternatively, you could model

    \[
    \frac{\text{ntdiv}_{t}}{n} \sum_k \text{nkt}_{k,t}^2
    \]

    in a similar way as above.

    z = m.addVars(nodes)
    sum_t = 0
    for t in nodes:
    m.addConstr(z[t] == gp.quicksum(nkt[k,t]*nkt[k,t] for k in K))
    sum_t += z[t] * ntdiv[t] * 1.0/n
    #[...]

    One cannot say which formulation will perform better (although I think that the second one might be better) so it is best to try both to be sure.

     

    Best regards, 
    Jaromił

    0

Please sign in to leave a comment.