Skip to main content

TypeError: 1.0 + 0.0007 <gurobi.Var *Awaiting Model Update*> is not a variable

Answered

Comments

7 comments

  • Maliheh Aramon
    • Gurobi Staff

    Hi, 

    A general constraint of type LogA is in the form (Var, Var, a) where Var is a Gurobi variable object and not a Gurobi Linear Expression (LinExpr).

    To implement the expression \(\log_2(1+\frac{c}{w_n})\), you need to define three auxiliary variables to represent \(z = \frac{1}{w_n}\), \(v = 1+ cz\), and then \(y=\log_2(v)\). 

    w = m.addVars(N, lb=0.1, ub=1, name="w")
    z = m.addVars(N, name="z")
    v = m.addVars(N, name="v")
    y = m.addVars(N, name="y")

    m.addConstrs((z[i] * w[i] == 1 for i in range(N)), name="c_bilinear")
    m.addConstrs((v[i] == 1 + c * z[i] for i in range(N)), name="c_linexpr")
    for i in range(N):
    m.addGenConstrLogA(v[i], y[i], 2, name="c_log")

    Best regards,
    Maliheh
    0
  • Rabbitutu Yang
    • Gurobi-versary
    • Conversationalist
    • First Question

    Hi Maliheh,

    your comment helps me a lot, thank you very much!

    However, I have a new problem.

    The problem can be modeled as follows:

    For the problem, only b_n and w_n are decision variables, other notations, such as Q_n, W_n, are constants. We have proven that the objective function and all constraints are convex.

    The values of these constants are as follows:

    Q = [4200, 3000, 600, 5400, 1700] # each item can be denoted as Q_n
    H = [300, 1500, 300, 800, 1100] # each item can be denoted as H_n
    M = [200, 300, 120, 300, 200] # each item can be denoted as M_n
    M_e = [100, 50, 70, 260, 80] # each item can be denoted as M^e_n
    M_l = [100, 250, 50, 40, 120] # each item can be denoted as M^l_n
    F_l = [5.5, 3, 7, 8, 10] # each item can be denoted as F^l_n
    D = [10, 15, 20, 25, 30] # each item can be denoted as D_n
    W = 10000
    p = [7, 5, 7.5, 6, 8] # each item can be denoted as p_n
    h = [1, 1, 1, 1, 1] # each item can be denoted as h_n
    N_0 = 1

    Moreover, the corresponding code is:

    # define the decision variable b_n, which is the integer variable
    b = W_LP.addVars(N, lb=0, ub=GRB.INFINITY, vtype=GRB.INTEGER, name="b")

    # define the decision variable w_n
    w = W_LP.addVars(N, lb=0.1, ub=1, vtype=GRB.CONTINUOUS, name="w")

    # define the auxiliary variable z_n, so as to add the constraint z_n*w_n=1 and instead 1/w_n with z_n
    z = W_LP.addVars(N, lb=1, ub=10, vtype=GRB.CONTINUOUS, name="z")

    # define the auxiliary variable v_n, which can be used instead of 1+(p_n*h_n/W*N_0)/w_n in log2(1+(p_n*h_n/W*N_0)/w_n)
    v = W_LP.addVars(N, name="v")

    # define the auxiliary variable y_n
    y = W_LP.addVars(N, name="y")

    # define the auxiliary variable tmp_n
    tmp = W_LP.addVars(N, name="tmp")

    # construct the objective function
    obj = LinExpr(0)
    for i in range(N):
    a = -Q[i] * M[i] + H[i] * M_e[i]
    obj.addTerms(a, b[i])
    W_LP.setObjective(obj, GRB.MINIMIZE)

    # add the constraint the sum of w_n is 1
    constr_1 = LinExpr(0)
    for i in range(N):
    constr_1.addTerms(1, w[i])
    W_LP.addConstr(constr_1 == 1, name="w1")

    # add the constraint z_n*w_n=1
    W_LP.addConstrs((z[i] * w[i] == 1 for i in range(N)), name="c2_linear")

    # add the constraint v_n=1+(p_n*h_n/W*N_0)/w_n
    W_LP.addConstrs((v[i] == 1 + (p[i] * h[i] * z[i])/(W * N_0) for i in range(N)), name="c_linexpr")

    # log2(1+(p_n*h_n/W*N_0)/w_n)
    for i in range(N):
    W_LP.addGenConstrLogA(v[i], y[i], 2, name="c_log")

    # b_n=min{F^l_n/M^l_n, (w_n*W*log2(1+(p_n*h_n/W*N_0)/w_n))/D_n},where the two items in min{} must be rounded down
    for i in range(N):
    name = 'b_min' + str(i)
    W_LP.addConstr(tmp[i] == W_LP.addGenConstrMin(F_l[i]/M_l[i], (y[i]*w[i]*W)/D[i]), name=name)
    W_LP.addConstrs((b[i] == int(tmp[i]) for i in range(N)), name="b2_min")

    W_LP.optimize()

    print("Obj: ", W_LP.objVal)

    the bug shows that

    Great thanks for your help!

    Huan

    0
  • Maliheh Aramon
    • Gurobi Staff

    Hi, 

    It seems that you are interested in modeling the constraint below:

    \[b_n = \min \Big\{ \big\lfloor \frac{F^l_n}{M^l_n} \big\rfloor, \big\lfloor \frac{w_n W \log_2(1 + \frac{p_nh_n}{w_nWN_0})}{D_n} \big\rfloor \Big \}\]

    • You have already defined the auxiliary variables \(y\) to represent \(\log_2(1 + \frac{p_nh_n}{w_nWN_0})\).
    • Please note that the Python int() function can only be used on real numbers not on Gurobi expression objects.
      • The expression \(\frac{w_n W y_n}{D_n}\) is a Gurobi QuadExpr() object. To model \(\lfloor \frac{w_n W y_n}{D_n} \rfloor\), you would need to define new auxiliary variables \(u\).
    • See the code snippet below on how to implement this:
    u = W_LP.addVars(N, vtype=gp.GRB.INTEGER, name="u")
    # Model u_i to represent the greatest integer less than y[i] * w[i] * W / D[i]
    W_LP.addConstrs((u[i] <= y[i] * w[i] * W / D[i] for i in range(N)))
    W_LP.addConstrs((u[i] >= y[i] * w[i] * W / D[i] - 1 for i in range(N)))

    # Model b = min(int(F^l_n/M^l_n), u)
    for i in range(N):
    W_LP.addGenConstrMin(b[i], [u[i]], int(F_l[i] / M_l[i]), name="b_min")

    Please also note that your model is non-convex because of the following two constraints \(z_i w_i = 1\) and \(u_i \geq  \frac{W}{D_i} y_i w_i  - 1\). You would need to set the parameter NonConvex to 2.

    Best regards,

    Maliheh

    0
  • Rabbitutu Yang
    • Gurobi-versary
    • Conversationalist
    • First Question

    Your reply helps me a lot, thank you very much!!

    Best regards,

    Huan

    0
  • Rabbitutu Yang
    • Gurobi-versary
    • Conversationalist
    • First Question

    Hi Maliheh,

    Sorry to disturb you again.

    I met a new bug for the above mentioned problem.

    During the assignment process, and the constraint with respect to v_n can be written as:

    W_LP.addConstrs((v[i] == 1 + (4 * z[i] * 10**11)/(W * N_0) for i in range(N)), name="c_linexpr")

    the model is infeasible.

    However, if the constraint with respect to v_n is written as:

    W_LP.addConstrs((v[i] == 1 + (4 * z[i] * 10**8)/(W * N_0) for i in range(N)), name="c_linexpr")

    the model is feasible.

    Moreover, the full code is shown as follows:

    Q = [4200, 3000, 600, 5400, 1700] # each item can be denoted as Q_n 
    H = [300, 1500, 300, 800, 1100] # each item can be denoted as H_n
    M = [200, 300, 120, 300, 200] # each item can be denoted as M_n
    M_e = [100, 50, 70, 260, 80] # each item can be denoted as M^e_n
    M_l = [100, 250, 50, 40, 120] # each item can be denoted as M^l_n
    F_l = [5.5, 3, 7, 8, 10] # each item can be denoted as F^l_n
    D = [10, 15, 20, 25, 30] # each item can be denoted as D_n
    W = 10000
    N_0 = 1

    # define the decision variable b_n, which is the integer variable
    b = W_LP.addVars(N, lb=0, ub=GRB.INFINITY, vtype=GRB.INTEGER, name="b")

    # define the decision variable w_n
    w = W_LP.addVars(N, lb=0.1, ub=1, vtype=GRB.CONTINUOUS, name="w")

    # define auxiliary variable z_n, so as to add the constraint z_n*w_n=1 and instead 1/w_n with z_n
    z = W_LP.addVars(N, vtype=GRB.CONTINUOUS, name="z")

    # define the auxiliary variable v_n, which can be used instead of 1+(4*10**11/W*N_0)/w_n in log2(1+(4*10**11/W*N_0)/w_n)
    v = W_LP.addVars(N, name="v")

    # define the auxiliary variable y_n
    y = W_LP.addVars(N, name="y")

    # define the auxiliary variable u_n
    u = W_LP.addVars(N, vtype=GRB.INTEGER, name="u")

    # the objective function
    obj = LinExpr(0)
    for i in range(N):
    a = Q_t[i] * M[i] - H_t[i] * M_e[i]
    obj.addTerms(a, b[i])
    W_LP.setObjective(obj, GRB.MAXIMIZE)

    # add the constraint the sum of w_n is 1
    constr_1 = LinExpr(0)
    for i in range(N):
    constr_1.addTerms(1, w[i])
    W_LP.addConstr(constr_1 == 1, name="w1")

    # add the constraint z_n*w_n=1
    W_LP.addConstrs((z[i] * w[i] == 1 for i in range(N)), name="c2_linear")

    # add the constraint v_n=1+(4*10**11/W*N_0)/w_n
    W_LP.addConstrs((v[i] == 1 + (4 * z[i] * 10**11)/(W * N_0) for i in range(N)), name="c_linexpr")

    # log2(1+(4*10**11/W*N_0)/w_n)
    for i in range(N):
    W_LP.addGenConstrLogA(v[i], y[i], 2, name="c_log")

    # Model u_i to represent the greatest integer less than y[i] * w[i] * W / D[i]
    W_LP.addConstrs((u[i] <= y[i] * w[i] * W / D[i] for i in range(N)))
    W_LP.addConstrs((u[i] >= y[i] * w[i] * W / D[i] - 1 for i in range(N)))

    # Model b = min(int(F^l_n/M^l_n), u)
    for i in range(N):
    W_LP.addGenConstrMin(b[i], [u[i]], int(F_l[i] / M_l[i]), name="b_min")

    # set the parameter NonConvex to 2
    W_LP.params.NonConvex = 2

    W_LP.optimize()
    W_LP.computeIIS()
    W_LP.write("model.ilp")

    the bug shows that:

    the model.ilp file shows that:

    Great thanks for your help!

    Huan

    0
  • Maliheh Aramon
    • Gurobi Staff

    Hi Huan, 

    I cannot run your code because some of the input parameters such as \(\texttt{N}\), \(\texttt{Q_t}\), and \(\texttt{H_t}\) are not included. 

    The IIS indicates that if you relax the upper bound of the variables \(w\) to infinity, the IIS sub-system will be feasible. 

    I guess the infeasibility occurs because the bounds of the variables participating in the general function constraints is limited to 1e+6 by default to guard against numerical issues. In your current snippet the variables \(v\) are greater than or equal to \(1+4 \times 10^7\) which is greater than the default value for the FuncMaxVal parameter.

    Please post the complete code snippet such that I can run it.

    Best regards,

    Maliheh

    0
  • Rabbitutu Yang
    • Gurobi-versary
    • Conversationalist
    • First Question

    Hi Maliheh,

    The reason you guessed that the model is not feasible is completely correct.

    Based on this, I first reduced the value of v by a certain multiple, and then increased the value of y by the same multiple as y=log2(v).

    In this way, the model becomes feasible and I can obtain the optimal solution.

    Thank you very much for your help! ^_^

    0

Please sign in to leave a comment.