Skip to main content

How to write Max[] constraint in model?

Answered

Comments

7 comments

  • Ismail Gokay Dogan
    • Gurobi-versary
    • First Comment

    Hi Haoxing,

    I could not fully understand the constraint that you are trying to generate, but have you tried using max_() function? You can find the documentation here:

    https://www.gurobi.com/documentation/current/refman/py_max_.html

    In your case I believe you can represent your constraint like (0.5 Z + max_((Z-2), constant = 0 ) + ... + max_((Z-20), constant = 0)

    0
  • Jaromił Najman
    • Gurobi Staff

    To add \(\max\) constraints in Gurobi, you will have to introduce auxiliary variables for each \(\max\) term. This means that your expression becomes

    \[\begin{align*}
    (0.5 \cdot Z &+ a_1 + a_2 + \dots + a_{10})/Z \\
    a_1 &= \max \{0, b_1\} \\
    b_1 &= Z - 2 \quad(*)\\
    a_2 &= \max \{0, b_2\}\\
    b_2 &= Z - 4 \quad(*)\\
    \dots\\
    a_{10} &= \max \{0, b_{10}\}\\
    b_{10} &= Z - 20 \quad(*)\\
    \end{align*}\]

    Note that you might need to adjust the lower bounds of the \(b_i\) variables, because the default lower bound for variables in Gurobi is \(0\). Once you have implemented all auxiliary variables \(a_i, b_i\) and all \((*)\) equality constraints, you can use the addGenConstrMax method to implement the remaining \(\max\) constraints.

    For the division by \(Z\), please refer to the Knowledge Base article How do I divide by a variable in Gurobi?

    Best regards, 
    Jaromił

    0
  • HAOXING OUYANG
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił,

    Thanks for your reply. I followed your instructions to add Max constraints, it worked.

    But I am facing the problem with the division constraint. 

    According to your reply, I refer to the Knowledge Base article How do I divide by a variable in Gurobi?

    The formula I wrote above is just a simplified version. In my model, I created an Integer variable: sumZ[i][k], and I want to divide by sumZ[i][k], so I have to calculate its reciprocal: reverseSumZ[i][k]. 

    Firstly, I creating these tow varialbes: 

    GRBVar sumZ[][] = new GRBVar[instance.nodesNum][instance.vehiclesNum];
    GRBVar reverseSumZ[][] = new GRBVar[instance.nodesNum][instance.vehiclesNum];

    Secondly, I built their bounds and types: 

    for (int k = 0; k < instance.vehiclesNum; k++) {
    for (int i = 0; i < instance.nodesNum; i++) {
    sumZ[i][k] = model.addVar(0, GRB.INFINITY, 0.0, GRB.INTEGER, "sumZ_" + i + "_" + k);
    reverseSumZ[i][k] = model.addVar(0, 1, 0.0, GRB.CONTINUOUS, "reverseSumZ_" + i + "_" + k);
    }
    }

    Thirdly, I created the constraint: 

    //reverseSumZ[i][k] * sumZ[i][k] = 1
    for (int k = 0; k < instance.vehiclesNum; k++) {
    for (int i = 1; i < instance.nodesNum - 1; i++) {
    GRBQuadExpr expr = new GRBQuadExpr();
    expr.addTerm(1, reverseSumZ[i][k], sumZ[i][k]);
    model.addQConstr(expr, GRB.EQUAL, 1, "internalVar_adverse_" + i + "_" + k);
    }
    }

    The range for i is from 1 to instance.nodesNum -1, to make sure that the sumZ[i][k] is not equal to zero.

    But running the program will prompt that the model has no solution. And I ensure that the model only has no solution after adding this constraint.

    Can you help me answer this?

    Best regards,

    Haoxing 

    0
  • HAOXING OUYANG
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił,

    I would like to add is:

    Integer variable sumZ[i][k] >=0, only when i∈N \ {0,n+1} will sumZ[i][k] ≠ 0. 

     

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Haoxing,

    But running the program will prompt that the model has no solution. And I ensure that the model only has no solution after adding this constraint.

    Is your model declared infeasible? Did you try to determine why it is infeasible, see How do I determine why my model is infeasible? and How do I use 'compute IIS' to find a subset of constraints that are causing model infeasibility? The 0 in your reverse sum might be an issue, because this would mean that you allow division by 0.

    Integer variable sumZ[i][k] >=0, only when i∈N \ {0,n+1} will sumZ[i][k] ≠ 0. 

    I am not sure what you mean. Do you mean to add constraint sumZ[i][k] >=0 for all i∈N \ {0,n+1}? Or do you mean to add sumZ[i][k] >=0 only when sumZ[i][k] ≠ 0?

    Best regards, 
    Jaromił

    0
  • HAOXING OUYANG
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromił,
    Thanks for your reply. I am sorry for my confusious  answered.
    In my model, sumZ[i][k] is >=0(sumZ[i][k] = 0 ← when i == 0 && i == instances.nodesNum), and I want to calculate its count backwards, so I construct a constraintin:

    //reverseSumZ[i][k] * sumZ[i][k] = 1
    for (int k = 0; k < instance.vehiclesNum; k++) {
        for (int i = 1; i < instance.nodesNum - 1; i++) {
            GRBQuadExpr expr = new GRBQuadExpr();
            expr.addTerm(1, reverseSumZ[i][k], sumZ[i][k]);
            model.addQConstr(expr, GRB.EQUAL, 1, "internalVar_adverse_" + i + "_" + k);
        }
    }

    In the constraint I set the range for i between 1 and instamce.nodesNum-1, to avoid divide by 0. 
    I think this is reasonable in logical, but the model is infeasible, that I consider the situation of dividing by 0 has not been ruled out yet.

    0
  • Jaromił Najman
    • Gurobi Staff

    I think this is reasonable in logical, but the model is infeasible, that I consider the situation of dividing by 0 has not been ruled out yet.

    In this case, you should try to follow the steps in  How do I determine why my model is infeasible? and How do I use 'compute IIS' to find a subset of constraints that are causing model infeasibility? With that you should be able to find the source of infeasibility for your model.

    0

Please sign in to leave a comment.