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

Use index of decision variable in max_ constraint

回答済み

コメント

4件のコメント

  • 正式なコメント
    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?.
  • Eli Towle
    • Gurobi Staff

    You are on the right track. Here is one way to do this, though this formulation can certainly be modified a few different ways. I'll assume your index sets are \( N \), \( I \), and \( K \).

    First, we introduce a variable \( y_{ik} \) for all \( i \in I \) and \( k \in K\). We set \( y_{ik} \) equal to \( \max_{n \in N} T_{nik} \):

    y = m.addVars(I, K, name='y')
    m.addConstrs((y[i, k] == gp.max_(T.select('*', i, k)) for i in I for k in K), name='max_value')

    Then, we add your \( V_k \) variables and set \( V_k \geq \max_{n \in N, i \in I} T_{nik} \) for all \( k \in K \):

    V = m.addVars(K, name='V')
    m.addConstrs((V[k] >= y[i, k] for i in I for k in K), name='v_con')

    Next, we introduce binary variables \( u_{ik} \) for all \( i \in  I \) and \( k \in K \). For each \( k \), exactly one \( u_{ik} \) is \( 1 \). Additionally, \( u_{ik} \) is equal to \( 1 \) only if \( T_{nik} \) is "maximal" for some \( n \in N \). If multiple indices \( i \in I \) are maximal, then \( u_{ik} \) is \( 1 \) for only one of them.

    u = m.addVars(I, K, vtype=gp.GRB.BINARY, name='u')
    m.addConstrs((u.sum('*', k) == 1 for k in K), name='sum_to_one')

    Finally, for all \( i \in I \) and \( k \in K \), we add indicator constraints that set \( y_{ik} \geq V_k \) if \( u_{ik} = 1 \):

    m.addConstrs(((u[i, k] == 1) >> (y[i, k] >= V[k]) for i in I for k in K), name='indicator')   

    Let's see if this formulation makes sense. Consider a fixed \( k \in K \). Let \( i \in I\) satisfy \( u_{ik} = 1 \). The indicator constraint gives us \( y_{ik} \geq V_{k} \). By our other constraints, \( \max_{n \in N} T_{nik} = y_{ik} \leq V_k \). Altogether, this gives us \( u_{ik} = 1 \implies \max_{n \in N} T_{nik} = V_k \), as desired.

    Note that we moved the max_ constraints to the new \( y_{ik} \) variables instead of the \( V_k \) variables. We no longer need these constraints on the \( V_k \) variables. To see this, consider a fixed \( k \in K \). By the indicator constraints, there exists \( \hat{i} \in I \) such that \( \max_{n \in N} T_{n\hat{i}k} \geq V_k \). Together with the constraints \( V_k \geq \max_{n \in N} T_{nik} \) for all \( i \in I, \) this implies \( V_k = \max_{n \in N, i \in I} T_{nik} \).

    Now, for a fixed \( k \in K \), we can use the expression \( \sum_{i \in I} i u_{ik} \) to obtain an \( i \in I \) satisfying \( \max_{n \in N} T_{nik} = V_k \).

    0
  • Ana Sofia Ariza Cardona
    • Gurobi-versary
    • First Comment
    • First Question

    Hi, I got the same problem but I´m doing it on Python, do you know how can I write this:

    T.select('*', i, k)

    on python?

    0
  • Eli Towle
    • Gurobi Staff

    The code is written in Python. It assumes \( \texttt{T} \) is a tupledict object (see tupledict.select()), which is the type of object returned by Model.addVars(). For example:

    >>> x = m.addVars(3, 4, 5, name='x')
    >>> type(x)
    <class 'gurobipy.tupledict'>
    >>> m.update()
    >>> x.select('*', 1, 2)
    [<gurobi.Var x[0,1,2]>, <gurobi.Var x[1,1,2]>, <gurobi.Var x[2,1,2]>]
    0

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