How to sum variables that are not dimensionally incomplete
Answeredx (i,j,k) :
{(1, 1, 1) : < gurobi. Var x >,1,1 (1), (1, 1, 2) : < gurobi. Var x (1,1,2) >,
(1, 2, 1) : < gurobi. Var x > (1, 2, 1), (1, 2, 2) : < gurobi. Var x >,2,2 (1), (1, 2, 3) : < gurobi. Var (1, 2, 3) x >, (1, 2, 4) : <gurobi.Var x(1,2,4)>,
(1, 3, 1) : < gurobi. Var x >,3,1 (1), (1, 3, 2) : < gurobi. Var x > 31 (1), (1, 3, 3) : < gurobi. Var (filling) 1 x >, (1, 3, 4) : <gurobi.Var x(1,3,4)>,
(1, 4, 3) : < gurobi. Var (1, 3) x >, (1, 4, 4) : < gurobi. Var x (1,4,4) >,
(2, 1, 1) : < gurobi. Var x >,1,1 (2), (2, 1, 2) : < gurobi. Var (2,1,2) x >,
(2, 2, 1) : < gurobi. Var x > (2, 2, 1), (2, 2, 2) : < gurobi. Var x >,2,2 (2), (2, 2, 3), (2, 2, 3) > < gurobi. Var x, (2, 2, 4) : <gurobi.Var x(2,2,4)>,
(2, 3, 1) : < gurobi. Var x >,3,1 (2), (2, 3, 2) : < gurobi. Var x > 31 (2), (2, 3, 3) : < gurobi. Var (filling) 2 x >, (2, 3, 4) : <gurobi.Var x(2,3,4)>,
(2, 4, 3) : < gurobi. Var (2, 3) x >, (2, 4, 4) : < gurobi. Var (2,4,4) x >,
(3, 1, 1) : < gurobi. Var (3,1,1) x >, (3, 1, 2) : < gurobi. Var (3,1,2) x >,
(3, 2, 1) : < gurobi. Var x > (3, 2, 1), (3, 2, 2) : < gurobi. Var (3,2,2) x >, (3, 2, 3) : < gurobi. Var (3, 2, 3) x >, (3, 2, 4) : <gurobi.Var x(3,2,4)>,
(3, 3, 1) : < gurobi. Var (3,3,1) x >, (3, 3, 2) : < gurobi. Var x > 31 (3), (3, 3, 3) : < gurobi. Var x (filling) >, (3, 3, 4) : <gurobi.Var x(3,3,4)>,
(3, 4, 3) : < gurobi. Var (3, 3) x >, (3, 4, 4) : < gurobi. Var (3,4,4) x >,
(4, 1, 1) : < gurobi. Var (4,1,1) x >, (4, 1, 2) : < gurobi. Var (4,1,2) x >,
(4, 2, 1) : < gurobi. Var x > (4, 2, 1), (4, 2, 2) : < gurobi. Var (4,2,2) x >, (4, 2, 3) : < gurobi. Var (4, 2, 3) x >, (4, 2, 4) : <gurobi.Var x(4,2,4)>,
(4, 3, 1) : < gurobi. Var x >,3,1 (4), (4, 3, 2) : < gurobi. Var x > 31 (4), (4, 3, 3) : < gurobi. Var (4 filling) x >, (4, 3, 4) : <gurobi.Var x(4,3,4)>,
(4, 4, 3) : < gurobi. Var (4, 3) x >, (4, 4, 4) : < gurobi. Var (4,4,4) x >}
Hello I am in the debugging process to see the value of variable x, he is an incomplete three-dimensional matrix variable I designed
I want to write a constraint that looks like this:
for i in J:
# for u in J:
# for k in operations_machines[i,u] :
for k in range(1,5) :
Model. AddConstr (sum (x (I, j, k] for j in range (1, 5)) = = 1, "cons_x () % s, % s" % (I, j))
For each i, k can only be used once in all j phases
The obvious problem with such code is the following:
File "D:\Desktop\gurobi new \untitled0.py", line 164, in <genexpr>
Model. AddConstr (sum (x (I, j, k] for j in range (1, 5)) = = 1, "cons_x () % s, % s" % (I, j))
KeyError: (1, 4, 1)
How to modify it?
Explanation:
operations_machines (i,j) are as follows, whose values represent the range of k (corresponding to k in x above) : for convenience I have temporarily used for k in range(1,5) : to represent k
{(1, 1) : [1, 2], [1, 2), (3, 1, 4, 2), (1, 3), (3, 1, 4, 2), (1, 4) : [3, 4], (2, 1) : [1, 2], (2, 2) : [4, 1, 2, 3], (2, 3) : [4, 1, 2, 3], (2, 4) : [3, 4], (3, 1) : [1, 2], (3, 2) : [1, 2, 3, 4), (3, 3) : [1, 2, 3, 4), (3, 4) : [3, 4), (4, 1) : [1, 2], (4, 2) : [1, 3, 2, 4), (4, 3) : [1, 3, 2, 4), (4, 4) : [3, 4]}
-
Hi 子龙 王,
The problem you're encountering occurs because your code is trying to find certain keys in the x dictionary that actually don't exist, resulting in a KeyError.
This issue pops up due to the way your loop is set up—it goes through a set range of numbers (from 1 to 4), implicitly assuming that for every possible combination of (i, j, k), there's a corresponding entry in your x dictionary. However, the reality, as outlined by your operations_machines setup, is that not every (j, k) pair is appropriate for each i. That mismatch leads to the error you see because the code attempts to look up keys that simply aren't there.
Here is one possible way to fix it.from gurobipy import Model, GRB
# Indices for operations/items and phases/stages
I = [1, 2]
J = [1, 2, 3, 4]
# Let Valid k values for some (i, j) combination
operations_machines = {
(1, 1): [1, 2],
(1, 4): [3, 4],
(2, 2): [1, 3],
(2, 3): [2, 4]
}
# Initialize the model
model = Model("ExampleModel")
# Decision variables x[i,j,k]
x = {}
for i in I:
for j in J:
for k in range(1, 5): # Assuming k should also iterate over 1 to 4
x[i, j, k] = model.addVar(vtype=GRB.BINARY, name=f"x[{i},{j},{k}]")
for i in I:
for j in J:
if (i, j) in operations_machines: # Only proceed if (i, j) has valid k values
valid_k_values = operations_machines[(i, j)]
for k in valid_k_values: # Iterate only over valid k values
model.addConstr(sum(x[i, j, k_prime] for k_prime in valid_k_values) == 1,
f"constraint_{i}_{j}_{k}")You can check the constraint expression for this example
# Print constraint expressions
model.update() # Ensure the model is updated before accessing constraints
constraints = model.getConstrs() # Retrieve list of constraints
for constr in constraints:
expr = model.getRow(constr) # Get the linear expression for the constraint
print(f"{constr.ConstrName}: {expr} == 1")You can also use more concise ways of defining the constraints using tupledict and inserting an if statement inside Model.addConstrs()
I hope this helps
Thanks
- Ahmed
0
Please sign in to leave a comment.
Comments
1 comment