メインコンテンツへスキップ

How to formulate conditional constaints

回答済み

コメント

11件のコメント

  • 正式なコメント
    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 try Gurobot, our chatbot interface offering instant, expert-level support.
  • Jaromił Najman
    • Gurobi Staff

    In the following I assume that all \(B2R_{b,i}\) variables are binary variables. For simplicity, I will omit the \(b\) index.

    First, we define an auxiliary integer variable \(x \in \{0,\dots,r\}\) and the equality constraint

    \[x = \sum_{i=0}^{r-1} B2R_{i}\]

    We model the statement if \(x=1\) then \(y=1\) and \(y=0\) else.

    \[\begin{align*}
    y + 1.5y^+ \leq x &\leq 0.5 y^- + y + r y^+\\
    y^- + y^+ + y &= 1\\
    y^-,y^+, y &\in \{0,1\}
    \end{align*}\]

    You can now use Gurobi's indicator constraint to model

    \[y = 1 \rightarrow \text{Constraint-1}\]

    From the above, we know that \(y^+=1\) if \(x \geq 2\). You can introduce an additional binary variable \(z\) and use Gurobi's And Constraint to model

    \[z= B2R_{r} \land y^+\]

    and then use Gurobi's indicator constraint to model

    \[z = 1 \rightarrow \text{Constraint-2}\]

    Best regards, 
    Jaromił

    0
  • Deepak Nagar
    • Gurobi-versary
    • Conversationalist
    • First Question

    Thank you jaromil for the solution. I am facing some challenge while implementation, in the following part

    x = model.addVars(lb=0, ub=10, vtype=GRB.INTEGER, name="x")

    for b in range(self.no_of_bags):
    for r in range(self.no_of_rooms):
    self.model.addConstr(self.x == gp.quicksum([self.b2r[(self.bag_id[b], self.room_id[i])]
    for i in range(r)]))

      

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Deepak,

    You have to introduce a new \(x,y,y^+,y^-\) variable for every loop iterate, i.e., for every index \(b\) and \(r\).

    So your code should look something like

    import gurobipy as gp
    from gurobipy import GRB

    B = 3
    R = 4
    m = gp.Model()

    btwor = m.addVars(B, R, vtype=GRB.BINARY, name="b2r")
    x     = m.addVars(B, R, ub=R, vtype=GRB.INTEGER, name="x")
    y     = m.addVars(B, R, vtype=GRB.BINARY, name="y")
    ym    = m.addVars(B, R, vtype=GRB.BINARY, name="ym")
    yp    = m.addVars(B, R, vtype=GRB.BINARY, name="yp")
    z     = m.addVars(B, R, vtype=GRB.BINARY, name="z")

    for b in range(B):
      for r in range(2,R):
        m.addConstr(x[b,r] == gp.quicksum(btwor[b,i] for i in range(r-1)), name="x_eq_sum_%d_%d"%(b,r))
        m.addConstr(y[b,r] + 1.5 *yp[b,r] <= x[b,r], name="aux_leq_constr_%dd_%d"%(b,r))
        m.addConstr(x[b,r] <= 0.5*ym[b,r] + y[b,r] + r*yp[b,r], name="aux_geq_constr_%dd_%d"%(b,r))
        # here you have to introduce your constraint1
        m.addConstr((y[b,r] == 1) >> (constraint1), name="constraint1_indicator_%d_%d"%(b,r))

        m.addGenConstrAnd(z[b,r], [btwor[b,r],yp[b,r]], name="andconstr_%d_%d"%(b,r))
        # here you have to introduce your constraint2
        m.addConstr((z[b,r] == 1) >> (constraint2), name="constraint2_indicator_%d_%d"%(b,r))

    m.write("myLP.lp")

    Note that you still have to adjust a few things, because I just used some fixed values for your \(b\) and \(r\) indices.

    Best regards, 
    Jaromił

    0
  • Deepak Nagar
    • Gurobi-versary
    • Conversationalist
    • First Question

    Thanks for the reply. It worked.

     

    0
  • Deepak Nagar
    • Gurobi-versary
    • Conversationalist
    • First Question

    Hi jaromil,

    I am not able to define the following constraint

    Here B2R is binary and others are constant, can you please help me to define this

    self.model.addConstr((self.z2[(b, r)] == 1) >>
    (b2r[(b, r)] * d[r]) <= gp.min_((c[b] + 100), (c[b] + 100 + Q * (s[r] - gp.max_(b2r[(b, i)] * e[i] for i in range(r))))
    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Deepak,

    When you are using one of the general constraints such as max or min, you have to introduce auxiliary variables for all of your linear expressions passed as arguments to the general function. In you case, you have to introduce an auxiliary variable for every \(z_i = B2R_{b,r} \cdot E_i \) for every \(i\) and an additional variable holding the result of the \(\max\) function. Your code might look something like

    z = self.model.addVars(lb=-GRB.INFINITY, name="auxvar")
    self.model.addConstrs(z[i] == b2r[(b, i)] * e[i] for i in range(r), name="aux_constr")
    auxmax = self.model.addVars(lb=-GRB.INFINITY, name="auxmax)
    self.model.addConstr(auxmax = gp.max_(z), name="max_constr")

    The min function works analogously.

    Best regards, 
    Jaromił

    0
  • Deepak Nagar
    • Gurobi-versary
    • Conversationalist
    • First Question

    Hello Jaromił,

    I am try to formulate the following constraint but getting failed optimization error, can you please help me in this regards.

    thanks

    formulation:

    code:

            b2r = model.addVars(b, r, vtype=GRB.BINARY, name="B2R")
            x = model.addVars(b, r, ub=10, vtype=GRB.INTEGER, name="x")
            y = model.addVars(b, r, vtype=GRB.BINARY, name="y")
            ym = model.addVars(b, r, vtype=GRB.BINARY, name="ym")
            yp = model.addVars(b, r, vtype=GRB.BINARY, name="yp")
            z1 = model.addVars(b, r, vtype=GRB.BINARY, name="z1")
            z2 = model.addVars(b, r, vtype=GRB.BINARY, name="z2")
            t1 = model.addVars(b, vtype=GRB.CONTINUOUS, name="t1")
            t2 = model.addVars(b, r, vtype=GRB.CONTINUOUS, name="t2")
            t3 = model.addVars(b, r, vtype=GRB.CONTINUOUS, name="t3")
            new = model.addVars(b, r, vtype=GRB.CONTINUOUS, name="new")
            E = model.addVars(b, ii, vtype=GRB.INTEGER, name="E")
            et = model.addVars(b, ii, vtype=GRB.CONTINUOUS, name="et")


            for b in range(bags):

                model.addConstr(t1[b] == cap[b] * (100 - margin) / 100)
                ii = 0

                for r in range(balls):

                    model.addConstr(x[b, r]
                                         == gp.quicksum([b2r[b, i] for i in range(r + 1)]))

                    model.addConstr(y[b, r] + 1.5 * yp[b, r] <= x[b, r])

                    model.addConstr(x[b, r] <= 0.5 * ym[b, r] + y[b, r] + r * yp[b, r])

                    model.addGenConstrAnd(z1[b, r], [b2r[b, r)], y[b, r]])


                    # Here introduce constraint-1
                    model.addConstr((z1[b, r] == 1) >>
                                         (E[b, ii] == cap[b] * (C[b] - margin) / 100 - D[r] * F[b, r)]))

                    model.addConstr((z1[b, r] == 1) >> (et[b, ii] == end[r]))

                    model.addConstr((z1[b, r] == 1) >> (b2r[b, r] * D[r] * F[b, r] <=
                                          E[b, ii] + D[r] * F[b, r]))

                    model.addGenConstrAnd(z2[b, r], [b2r[b, r], yp[b, r]])


                    # Here introduce constraint-2
                    model.addConstr((z2[b, r] == 1) >> (ii == ii + 1))

                    model.addConstr((z2[b, r] == 0) >> (t2[b, r] == 0))

                    model.addConstr((z2[b, r] == 1) >> (t2[b, r] == E[b, ii - 1] + Q * (start[r] - et[b, ii - 1])))

                    max_list = [t2[b, r], t1[b, r]]

                    model.addGenConstrMin(t3[b, r], max_list)

                    model.addConstr((z2[b, r] == 1) >> (new[b, ii] == t3[b, r]))

                    model.addConstr((z2[b, r] == 1) >> (E[b, ii] == new[b, ii] - D[r] * F[b, r]))

                    model.addConstr((z2[b, r] == 1) >> (et[b, ii] == end[r]))

                    model.addConstr((z2[b, r] == 1) >> (b2r[b, r] * D[r] * F[b, r] <= E[b, ii] + D[r] * F[b, r]))

     

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Deepak,

    What exactly do you mean by a "failed optimization error"? Do you mean that your model is declared to be infeasible? If yes, then the article How do I determine why my model is infeasible? should be helpful.

    Best regards, 
    Jaromił

    0
  • Deepak Nagar
    • Gurobi-versary
    • Conversationalist
    • First Question

    Hi  Jaromił,

    I am getting the following error

    (E[b,ii] ==
    KeyError: ('120', 0)

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Deepak,

    The error means that you are trying to access the value \(\texttt{E[120,0]}\) which is not defined. From your post, it is not evident what your \(b\) and \(ii\) are. You should try removing parts of the code containing \(\texttt{E[,]}\) to locate the source of error.

    Best regards, 
    Jaromił

    0

投稿コメントは受け付けていません。