Skip to main content

How can I get values of variables awaiting model update in Gurobi python

Answered

Comments

8 comments

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    The code snippet you provided is not executable and does not lead to the errors you described. It makes it harder to provide help in this case.

    If you get the "Awaiting Model Update" error, you can execute the update method to make variable's properties accessible before optimization. Please note that the X attribute is only available if a feasible solution point is available, e.g., through a previous optimization run. You can check whether a solution is available via the SolCount attribute.

    Best regards,
    Jaromił

    0
  • Matthias Miltenberger
    Gurobi Staff Gurobi Staff

    The same question has also been posted on StackOverflow: How can I get values of variables awaiting model update in Gurobi python - Stack Overflow

    0
  • Namkyoung Lee
    First Comment
    First Question

    Firstly, I apologize insufficient previous inquiry.
    The point is value extraction of variables before optimization, which cannot be captured with X attribute and it's hard to search update method cases.
    I present the simple code as below but real quadratic function represented by cal_module() in the sample is much more complicated. In other word, the quadratic function is the object to be combined like MIP + domain function -> MIQP. Therefore during optimizing steps, the decision variables such as x, y need to be converted to numpy or pandas as input for quadratic formulation included in objective function. This is why I asked how to get values of variables which is uncertain at every model iteration?


    ---------------------- sample ---------------------------

    import numpy as np
    import gurobipy as gp
    from gurobipy import GRB

    def cal_module(x,y):
    m = np.array([])
    for i in np.arange(len(x)-1):
    r = x[i]**2 + y[i+1]**3
    m = np.append(m, r)
    return m

    mdl = gp.Model()

    x = mdl.addVars(20, lb=-5, ub=5, vtype=GRB.INTEGER)
    y = mdl.addVars(20, lb=-5, ub=5, vtype=GRB.INTEGER)

    mdl.addConstrs(x[t] + y[t] <= 3 for t in range(20))

    pre_x, pre_y = [], []
    for i in range(20):
    pre_x = x[i].value_method or any other approach
    pre_y = y[i].value_method or any other approach

    obj = gp.quicksum(-2*x[t] + y[t] for t in range(20)) + cal_module(pre_x,pre_y)
    mdl.setObjective(obj, GRB.MINIMIZE)

    mdl.optimize()

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    If I understand correctly, you are trying to construct a quadratic expression, add it to the objective function, and optimize it. You can and should work with the variable objects directly to achieve this. The following code should do what you have in mind

    import gurobipy as gp
    from gurobipy import GRB

    def cal_module(x, y, model):
    qExpr = gp.QuadExpr(0)
    for i in range(len(x)-1):
    z = model.addVar(lb=0, ub=25, vtype=GRB.INTEGER, name="aux_y_sqr_%d"%(i+1))
    model.addConstr(z == y[i+1]*y[i+1], name="aux_y_sqr_constr_%d"%(i+1))
    qExpr.add(x[i]**2 + y[i+1]*z)
    return qExpr

    mdl = gp.Model()
    x = mdl.addVars(20, lb=-5, ub=5, vtype=GRB.INTEGER, name="x")
    y = mdl.addVars(20, lb=-5, ub=5, vtype=GRB.INTEGER, name="y")
    mdl.addConstrs(x[t] + y[t] <= 3 for t in range(20))
    obj = gp.quicksum(-2*x[t] + y[t] for t in range(20)) + cal_module(x,y,mdl)
    mdl.setObjective(obj, GRB.MINIMIZE)
    mdl.setParam("NonConvex",2)
    mdl.write("myLP.lp")
    mdl.optimize()

    Note that the variable tupledicts \(\texttt{x,y}\) are directly passed to the \(\texttt{def_module}\) function.

    Since Gurobi does not support cubic terms \(y^3\), you have to add an auxiliary variable to model the cubic term as a quadratic and a bilinear term \(z = y^2\) and \(y\cdot z\), see How do I model multilinear terms in Gurobi?

    Your model is nonconvex, thus the parameter NonConvex has to be set. I used the write method to write an LP file, which makes analyzing whether the model is indeed a correct one, easier.

    Best regards,
    Jaromił

    0
  • Namkyoung Lee
    First Comment
    First Question

    Hi Jaromił,

    Your comments were really helpful to understand Gurobi's solving flow. Many thanks.

    When it comes to the quadratic expression, my problem is actually nonlinear (not quadratic), which represents a physical formulation and seems like almost impossible to convert into model using gurobi library based variable because of its complexity. 

    As a result, I want to capture any attribute of variable before solved with update() method. The attribute I look for is something like a state that the variable contains 0(zero) or other value, however I couldn't find such attributes in the gurobi document, https://www.gurobi.com/documentation/9.5/refman/attributes.html#sec:Attributes.

    Rephrasing the question, I wonder I can get to know if the value of variable before optimization is zero(0) or not.

    Best regards,

    Namkyoung Lee

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Namkyoung Lee,

    If I understand your comment correctly, you are trying to model a conditional statement, i.e., something like if variable \(x=0\) then use constraint \(a\) otherwise use constraint \(b\). Is this correct?

    If yes, then the article How do I model conditional statements in Gurobi? should be what you are looking for.
    If not, could you please elaborate a bit further? Maybe provide a small example of what you are tying to model.

    Best regards, 
    Jaromił

    0
  • Namkyoung Lee
    First Comment
    First Question

    Hi Jaromił,

    I appreciate your continuance of help.
    This is another sample code, which contains an error about indicator constraint.
    I pursue constructing formulation with input whether variables have value of 0 or positive integer.

    Best regards,

    Nam-kyoung

    import gurobipy as gp
    from gurobipy import GRB

    def tmp_f(x):
        k = np.array([1 for i in range(10)])
        for j in x:
            k[j] = 0
        return sum((k+1)**2)
        
    m = gp.Model("qp")

    x = m.addVars(10 ,lb=0, ub=10, vtype=GRB.INTEGER, name="x")
    y = m.addVars(10, lb=0, ub=10, vtype=GRB.INTEGER, name="y")
    b = m.addVars(10, vtype=GRB.BINARY, name="b")

    # Basic constraints
    m.addConstrs(x[i] + 2 * y[i] <= 21 for i in range(10))
    m.addConstrs(x[i] - y[i] >= 0 for i in range(10))
    m.addConstr(x.sum('*') == 9)

    # big-M approach
    eps = 0.000001
    M   = 100 + eps

    # Model if x > 0 then b = 1, otherwise b = 0
    m.addConstrs(x[i] >= eps - M * (1 - b[i]) for i in range(10))
    m.addConstrs(x[i] <= M * b[i] for i in range(10))

    # Indicator constraints
    z = []     #  ←  ←  ← Initialization of an input for nonlinear-type formulation
    t = -1
    for i in range(10):
        m.addConstr((b[i] == 1) >> (t == i))
        z.append(t)

    # Objective function
    obj = gp.quicksum(x[i] + y[i] for i in range(10))
    m.setObjective(obj + tmp_f(z), GRB.MAXIMIZE)

    m.optimize()
    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    This thread is continued in Indicator constraint which contains constant value.

    0

Please sign in to leave a comment.