Skip to main content

Using value of a decision variable as index of another decision variable

Answered

Comments

3 comments

  • Gurobot AI-generated response
    Gurobi Staff Gurobi Staff

    The issue you're encountering arises from attempting to use the value of a decision variable (i_d[m]) as an index for another decision variable (x[i,t,j,t',m]). In Gurobi, decision variables are not evaluated until the model is solved, so using them directly as indices can lead to errors, such as the "KeyError" you've mentioned.

    To address this, you can consider the following approaches:

    1. Big-M Formulation: Instead of directly indexing x with i_d[m], introduce additional binary variables and constraints to link i_d[m] with the relevant entries of x. For instance, you could define a set of binary variables z[i, m] where z[i, m] = 1 if i_d[m] = i and 0 otherwise. You can then model the selection of x variables based on the values of z[i, m].

    2. Reformulate the Problem: If possible, reformulate the problem to avoid the need for decision variables as indices. This might involve rethinking how the problem is represented and how constraints are applied.

    3. Piecewise Linear Approximations: If the mapping between i_d[m] and the relevant indices of x can be approximated linearly, you could use piecewise linear approximations to model the relationship.

    Here's a conceptual example using the Big-M approach:

    from gurobipy import Model, GRB

    # Define model
    model = Model()

    # Example data
    M = 5  # Number of vehicles
    N = 10  # Number of locations
    T = 15  # Number of time periods

    # Decision variables
    i_d = model.addVars(M, vtype=GRB.INTEGER, name="i_d")  # Location indices
    x = model.addVars(N, T, N, T, M, vtype=GRB.BINARY, name="x")  # Binary decision variables
    z = model.addVars(N, M, vtype=GRB.BINARY, name="z")  # Auxiliary binary variables

    # Constraints to link i_d[m] and z[i, m]
    for m in range(M):
        model.addConstr(sum(z[i, m] for i in range(N)) == 1, name=f"link_z_{m}")
        for i in range(N):
            model.addConstr(i_d[m] == i * z[i, m], name=f"link_id_z_{i}_{m}")

    # Additional constraints using z to select x
    for m in range(M):
        for t in range(T):
            for t_prime in range(T):
                for i in range(N):
                    model.addConstr(x[i, t, i_d[m], t_prime, m] <= z[i, m], name=f"select_x_{i}_{t}_{t_prime}_{m}")

    # Objective and model optimization
    model.setObjective(0, GRB.MINIMIZE)  # Dummy objective
    model.optimize()

    In this example:

    • z[i, m] indicates whether the vehicle m is at location i.
    • The constraints ensure that only one z[i, m] can be 1 for each m, effectively selecting the location.
    • The x[i, t, i_d[m], t', m] variables are linked through z[i, m].

    This approach ensures that the value of i_d[m] is properly accounted for in the constraints and decision-making process, avoiding the direct use of decision variables as indices.

    If you encounter further issues or need a more specific example, feel free to provide additional details about your problem.

    0
  • Yizhi ZHEN
    Gurobi-versary
    First Question
    First Comment

    Hi,

    Thanks for your reply. But the error " KeyError: (0, 1, <gurobi.Var i_d_1>, 10, 1) " still shown up when the code as below is performed:

    model.addConstr(x[i, t, i_d[m], t_prime, m] <= z[i, m], name=f"select_x_{i}_{t}_{t_prime}_{m}")

    Thanks

    Best regards

    0
  • Matthias Miltenberger
    Gurobi Staff Gurobi Staff

    You are absolutely right! Gurobot has been giving the wrong example code here.

    The rest is still fine, though, and you need to find a way to reformulate your model. You simply cannot have decision variables as indices because they are not static. You need to define auxiliary variables that model that connection.

    If you want to use Gurobot yourself, you can check it out here: ChatGPT - Gurobot

    0

Please sign in to leave a comment.