How to Define a Constraint for Calculating the Maximum of Two Multi-Dimensional Variables in Gurobi
回答済みHi team,
The max_ function for the 1-dimension variable works. However, I need to add the constraint below:
model.addConstrs(X_3[m,r] == max_( X_1[m,r] , X_2[m,r] ) for m in range(M) for r in range(R))
Where X_1, X_2, and X_3 are multi-dimensional variables. When I run my code, I get the error below:
GurobiError: Invalid data in vars array
How can I consider this type of constraint? I do not want to use binary variables to linearize this constraint. I do not want to replace it with the two constraints below because there are some other challenges regarding my objective function and other constraints.
model.addConstrs(X_3[m,r] >= X_1[m,r] for m in range(M) for r in range(R))
model.addConstrs(X_3[m,r] >= X_2[m,r] for m in range(M) for r in range(R))
Also, I cannot write the constraints for each m and r individually because the input parameters M and R are big.
What about the constraint below which the variables have different dimensions?
model.addConstrs(X_6[m,r,y,d,h] == min_( X_4[m,r,y,d,h] , X_5[m,r] ) for m in range(M) for r in range(R) for y in range(Y) for d in range(D) for h in range(H))
Thanks for your time in advance
-
Hi Amir,
It is possible to use the max_() helper function regardless of the variables dimension and there is no need for the variables to have similar dimensions. See the code snippet below:
import gurobipy as gp
model = gp.Model()
M, R = 5, 4
x1 = model.addVars(M, R, name="x1")
x2 = model.addVars(M, R, name="x2")
x3 = model.addVars(M, R, name="x3")
model.addConstrs((x3[m,r] == gp.max_(x1[m,r], x2[m,r]) for m in range(M) for r in range(R)), name="c_max")Could you please post a small working example so that we can reproduce the error you see?
Best regards,
Maliheh
0 -
Thanks for your response.
Could you please check the code below? It works correctly without the constraint regarding the max function.
" model.addConstrs((con_SCG[m,r] == gp.max_(x_SCG[m,r], min_con_SCG[m,r]) for m in range(M) for r in range(R)), name="c_max") "
However, when I deactivate it (excluded from the optimization problem), I get the error "GurobiError: Invalid data in vars array"import gurobipy as gp
from gurobipy import *
import numpy as np# Create a new model
model = Model()M = 2
R = 2
N = 2P_tot = np.zeros((M,R))
P_tot[0,0] = 5000
P_tot[0,1] = 2000
P_tot[1,0] = 3000
P_tot[1,1] = 1000min_con_SCG = np.zeros((M,R))
min_con_SCG[0,0] = 200
min_con_SCG[0,1] = 200
min_con_SCG[1,0] = 300
min_con_SCG[1,1] = 300
# Define decision variables
x_SCG = model.addVars(M,R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="x_SCG")
x_ON_SCG = model.addVars(M,R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="x_ON_SCG")
x_act_SCG = model.addVars(M,R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="x_act_SCG")
con_SCG = model.addVars(M,R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="con_SCG")
Total_con_SCG = model.addVars(R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="con_RES")x_SCG[0,0].ub = 1000
x_SCG[1,0].ub = 800
x_SCG[0,1].ub = 500
x_SCG[1,1].ub = 600x_RES = model.addVars(N,R, lb=0.0, ub=400, vtype=GRB.CONTINUOUS, name="x_RES")
con_RES = model.addVars(N,R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="con_RES")
Total_con_RES = model.addVars(R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="con_RES")
z = model.addVar(lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="z")
delta_P = model.addVars(R, lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="delta_P")
SSS_1 = model.addVar(lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="SSS_1")
SSS_2 = model.addVar(lb=0.0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="SSS_2")
# objective_expr = 10 * x_SCG + 5 * x_act_SCG + 3 * x_RES + ( SSS_1 + SSS_2 )*1000 + con_SCGobjective_expr = gp.quicksum( gp.quicksum( 10 * x_SCG[m,r] for r in range(R) ) for m in range(M) ) + gp.quicksum( gp.quicksum( 5 * x_act_SCG[m,r] for r in range(R) ) for m in range(M) ) + gp.quicksum( gp.quicksum( 3 * x_RES[n,r] for r in range(R) ) for n in range(N) )
model.addConstr(gp.quicksum( x_SCG[m,0] for m in range(M) ) + gp.quicksum( x_RES[n,0] for n in range(N) ) == 2500 , name="Demand")
model.addConstr(gp.quicksum( x_SCG[m,1] for m in range(M) ) + gp.quicksum( x_RES[n,1] for n in range(N) ) == 500 , name="Demand")
model.addConstrs(x_SCG[m,r] <= x_ON_SCG[m,r] for m in range(M) for r in range(R))
model.addConstrs(x_ON_SCG[m,r] <= x_act_SCG[m,r] for m in range(M) for r in range(R))
model.addConstrs(x_act_SCG[m,r] <= P_tot[m,r] for m in range(M) for r in range(R))model.addConstrs((con_SCG[m,r] == gp.max_(x_SCG[m,r], min_con_SCG[m,r]) for m in range(M) for r in range(R)), name="c_max")
model.addConstrs(Total_con_SCG[r] == max_( con_SCG[0,r] , con_SCG[1,r]) for r in range(R))
# model.addConstr(con_SCG <= x_SCG , name="Constraint555")
# model.addConstr(con_SCG <= 200 , name="Constraint555")# model.addConstr(con_SCG >= x_SCG - SSS_1 - SSS_2 , name="Constraint3")
# model.addConstr(con_SCG >= 200 - SSS_1 - SSS_2 , name="Constraint4")
# model.addConstr(SSS_1 >= x_SCG - 200, name="Constraint5")
# model.addConstr(SSS_2 >= 200 - x_SCG , name="Constraint6")
model.addConstrs(con_RES[n,r] == 0.25 * x_RES[n,r] for n in range(N) for r in range(R))
model.addConstrs(Total_con_RES[r] == max_( con_RES[0,r] , con_RES[1,r]) for r in range(R))
model.addConstrs(delta_P[r] == max_( Total_con_SCG[r] , Total_con_RES[r]) for r in range(R))
# model.addConstr(delta_P >= con_SCG , name="Constraint555")
# model.addConstr(delta_P[r] >= con_RES[n,r] for n in range(N) for r in range(R) )
model.addConstrs(3 * gp.quicksum( x_act_SCG[m,r] for m in range(M) ) >= 50 * delta_P[r] for r in range(R))
model.setObjective(objective_expr, GRB.MINIMIZE)
model.optimize()# Access the values of decision variables
x_SCG_values = model.getAttr('X', x_SCG)
x_ON_SCG_values = model.getAttr('X', x_ON_SCG)
x_act_SCG_values = model.getAttr('X', x_act_SCG)
con_SCG_values = model.getAttr('X', con_SCG)
x_RES_values = model.getAttr('X', x_RES)
con_RES_values = model.getAttr('X', con_RES)
Total_con_RES_values = model.getAttr('X', Total_con_RES)
Total_con_SCG_values = model.getAttr('X', Total_con_SCG)
z_value = z.X
delta_P_values = model.getAttr('X', delta_P)
SSS_1_value = SSS_1.X
SSS_2_value = SSS_2.X# You can access the values of variables, one by one, like the examples above.
# For example, to print the values of x_SCG for all indices:
for m in range(M):
for r in range(R):
print(f'x_SCG[{m}, {r}] = {x_SCG_values[m, r]}')
print(f'x_ON_SCG[{m}, {r}] = {x_ON_SCG_values[m, r]}')
print(f'x_act_SCG[{m}, {r}] = {x_act_SCG_values[m, r]}')
print(f'con_SCG[{m}, {r}] = {con_SCG_values[m, r]}')
print()for n in range(N):
for r in range(R):
print(f'x_RES[{n}, {r}] = {x_RES_values[n, r]}')
print(f'con_RES[{n}, {r}] = {con_RES_values[n, r]}')
print()
for r in range(R):
print(f'Total_con_SCG[{r}] = {Total_con_SCG_values[r]}')
print(f'Total_con_RES[{r}] = {Total_con_RES_values[r]}')
print(f'delta_P[{r}] = {delta_P_values[r]}')
print()
# Close the model
model.close()
In my main code, I want to add these constraints:
SCG_type_con[m,r,y,d,h] == min ( SCG_dis[m,r,y,d,h] , x_1[m,r] ) ∀ m, r, y, d, h
SCG_con[r,y,d,h] == max ( SCG_type_con[m,r,y,d,h] ) over all m and ∀ r, y, d, h
## For example: SCG_con[r,y,d,h] == max ( SCG_type_con[0,r,y,d,h] , SCG_type_con[1,r,y,d,h] , SCG_type_con[2,r,y,d,h] )
## However, I want to define generally not manually like the above example
RES_con[r,y,d,h] == max ( RES_type_con[n,r,y,d,h] ) over all n and ∀ r, y, d, h
delta_P[r,y,d,h] == max ( SCG_con[r,y,d,h] , RES_con[r,y,d,h] ) ∀ r, y, d, h0 -
Hi,
In the constraint below:
model.addConstrs(
(
con_SCG[m,r] == gp.max_(x_SCG[m,r], min_con_SCG[m,r])
for m in range(M)
for r in range(R)
),
name="c_max",
)The \(\texttt{min_con_SCG[m,r]}\) is a constant and not a Gurobi variable. According to the Gurobi documentation, the signature of the max_() function is:
max_(*args, constant=None )Therefore, your constraint needs to change to:
model.addConstrs(
(
con_SCG[m, r] ==gp.max_(x_SCG[m, r], constant=min_con_SCG[m, r])
for m in range(M)
for r in range(R)
),
name="c_max",
)Best regards,
Maliheh0 -
Thanks Maliheh.
0
サインインしてコメントを残してください。
コメント
4件のコメント