Skip to main content

Collecting decision variables together

Answered

Comments

5 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff
    This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?.
  • Jaromił Najman
    • Gurobi Staff

    Hi Guy,

    In your case, it is enough to just add the floating point numbers instead of working with variable expressions. So it would be enough to

    import gurobipy as gp
    import numpy as np

    m = gp.Model("test")
    x = m.addVar()
    y = 0
    for i in range(10):
    y += np.random.randn(1)

    obj = gp.LinExpr(y[0]*x)

    In general, it is best to use the LinExpr() constructor or the addTerms() function. In both cases, you should sum the coefficient of individual variables by using floating point operations only instead of working with variable expressions.

    Best regards,
    Jaromił

    0
  • Guy Scher
    • Gurobi-versary
    • First Comment
    • First Question

    Hi, thanks for the answer but my case is more complicated than the example I've shown.

    Think of an iterative computation involving N Boolean variables with decisions and computations at each iteration. Although the result is linear in the variables, trying to maintain a coefficient list to then multiply the variables would be very hard.

    Is there no way to reduce or simplify an expression?

    0
  • Jaromił Najman
    • Gurobi Staff

    Is there no way to reduce or simplify an expression?

    You could call the Model.update() function, but this will result in additional overhead.

    The expressions objects are not meant to be used for actual computations but rather only to be constructed once. You could try using the add() function. However, in long term, I think that coming up with a data structure for maintaining the coefficients only during your computations is the best way to go.

    0
  • Guy Scher
    • Gurobi-versary
    • First Comment
    • First Question

    I think that model.update() would not help because I can't reach adding the objective expression to the model since my expression gets huge and gets stuck even before I reach the final expression I want. What's worse, is that it even carries expressions like 0.0 * x.

    I know the right way to go would be to express the iterations in matrix notation and try to simplify the math, but at least for now, I want to check that my program is at least in the right direction.

    For future reference, if anybody searches and have the same problem as I did, I'm posting my quick and dirty solution where I wrap my expression with this function in every iteration to keep the expressions manageable:

    # helper function to simplify and reduce all the coefficients of an expression of variables
    def simplify_expression(expr):
    try:
    N = expr.size()
    coeff_dict = {}
    C = expr.getConstant()
    for i in range(N):
    coeff = expr.getCoeff(i)
    dv = expr.getVar(i) # .VarName
    if(coeff_dict.get(dv) is None):
    # first time, initialize
    coeff_dict[dv] = coeff
    else:
    coeff_dict[dv] += coeff

    new_tuple = [ (val, key) for key, val in coeff_dict.items() ]
    new_expr = gp.LinExpr(new_tuple) + C
    except:
    # we sent something else, like a scalar / numpy array, so return the input
    new_expr = expr

    return new_expr

     

    0

Post is closed for comments.