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

Groupby constraint Gurobipy Pandas

回答済み

コメント

7件のコメント

  • 正式なコメント
    Simranjit Kaur
    • Gurobi Staff
    This post is more than two 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.
  • Maliheh Aramon
    • Gurobi Staff

    Hi Vusal, 

    Given your explanation, it seems to me that the decision variables should be defined as \(x_{ijk}\) being equal to 1 if resource \(i\) is assigned to store \(j\) at week \(k\). You can then use the gurobipy-pandas package as below to define the variables \(x\) and the constraints that ensure a resource cannot be assigned to more than one store at a given week. 

    resource_id = ["A", "B", "C", "D", "E"]
    store_num = [27, 31, 185, 485, 52]
    week_id = ["2023_12", "2023_15", "2023_32", "2023_08", "2024_04"]

    model = gp.Model()
    x = gppd.add_vars(
    model,
    pd.MultiIndex.from_product(
    (resource_id, store_num, week_id),
    names=("resource_id", "store_num", "week_id"),
    ),
    vtype=GRB.BINARY,
    name="x",
    )

    gppd.add_constrs(
    model,
    x.groupby(["resource_id", "week_id"]).sum(),
    GRB.LESS_EQUAL,
    1,
    name="c1",
    )
    Best regards,
    Maliheh
    0
  • Vusal Babashov
    • Gurobi-versary
    • Conversationalist
    • First Question

    Hi Maliheh,

    Not really, since k is pre-defined (i.e., fixed) in reality, there was no point in adding week_id to the index list. So, I defined the variables as x_ik for specific i and k pairs and stored in the pandas dataframe df.

      total_assignments = (df.groupby(['week_id','resource_id'])['x'].sum())
    allocate_once = gppd.add_constrs(model, total_assignments, GRB.LESS_EQUAL, 1, name="allocate_once")

    Would this groupby expression work? 

    Thanks.

     

    0
  • Maliheh Aramon
    • Gurobi Staff

    since k is pre-defined (i.e., fixed) in reality, there was no point in adding week_id to the index list

    I do not understand this. The number of resources and stores are also fixed. 

    Do you have rows in your dataframe that have the same \(\texttt{resource_id}\) and \(\texttt{week_id}\) but different \(\texttt{store_num}\)?

    Let us assume the \(\texttt{df}\) as below (I added one additional row to your example dataframe):

                           week_id                      x
    resource_id store_num
    A           27         2023_12   <gurobi.Var x[A,27]>
    B           31         2023_15   <gurobi.Var x[B,31]>
    C           185        2023_32   <gurobi.Var x[C,185]>
    D           485        2023_08   <gurobi.Var x[D,485]>
    E           52         2024_04   <gurobi.Var x[E,52]>
    A           42         2023_12   <gurobi.Var x[A,42]>

    The statements

    total_assignments = (df.groupby(['week_id','resource_id'])['x'].sum())
    allocate_once = gppd.add_constrs(model, total_assignments, GRB.LESS_EQUAL, 1, name="allocate_once")

    add constraints in the form below to the model:

    x[D,485] <= 1.0
    x[A,27] + x[A,42] <= 1.0
    x[B,31] <= 1.0
    x[C,185] <= 1.0
    x[E,52] <= 1.0

    Best regards,

    Maliheh

    0
  • Vusal Babashov
    • Gurobi-versary
    • Conversationalist
    • First Question

    What I mean is that the model is useful for assigning resources to stores. Each store has a pre-defined week for the assignment. If we know, which store a resource is assigned to, we will know what the week of the assignment is because it is already predefined by decision-makers.

    Because there are many stores, and predefined assignment weeks can sometimes overlap, I need a constraint to ensure that a person can't be assigned to two stores on a given week. As you mentioned, in my df, I have X variables defined for more than one store_num for a given resource_id and week_id. Thus, a constraint is needed to ensure only one assignment happens. Let me know what you think..

    0
  • Vusal Babashov
    • Gurobi-versary
    • Conversationalist
    • First Question
    x[D,485] <= 1.0
    x[A,27] + x[A,42] <= 1.0
    x[B,31] <= 1.0
    x[C,185] <= 1.0
    x[E,52] <= 1.0

    In reality, I only need to add this one

    x[A,27] + x[A,42] <= 1.0

    and the rest of the constraints are redundant because there is no more than one store_num for the same resource_id and week_id for those. Let me know if you can come up with a more efficient version.

    0
  • Maliheh Aramon
    • Gurobi Staff

    I would not be worried too much about the redundant constraints if they are not too many. Anyways, the script below should avoid adding the redundant constraints:

    total_assignments= (
    df.groupby(["week_id", "resource_id"])
    .filter(lambda x: len(x["x"]) > 1)
    .groupby(["week_id", "resource_id"])["x"]
    .sum()
    )
    Maliheh
    0

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