Incompatible dimensions in Gurobi python
AnsweredI am trying to solve a linear programming problem with Gurobi, although i am running in to the problem where I have incompatible dimensions already in my first constraint. My vector b has a shape of (3, 1) and my decision variable lamb_obj has shape (3,). Could someone help me on how to fix this dimension incompatability?
My linear programming problem is depicted in this picture.
The first constraint is a vector multiplication added up by a sum of two multiplied values. My code looks like this:
import gurobipy as gp
from gurobipy import GRB
from gurobipy import *
import numpy as np
import numpy.random as rd
import matplotlib.pyplot as plt
import pandas as pd
import math
# Parameters of the lot-sizing problem
N = 2
c = [3.901260342, 1.948694185]
t = np.array([[0, 8.40717256], [2.550951155, 0]])
dmax = 20
Gamma = 20*np.sqrt(N)
b = np.array(([20],[20],[Gamma]))
I = np.identity(2)
A = np.vstack((I, [1,1]))
model = gp.Model('RO') # Define a model
x = model.addVars(N, lb=0, ub=20, vtype=GRB.CONTINUOUS, name='x')
V = model.addVars(N, N, vtype=GRB.CONTINUOUS, name='v')
u = model.addVars(N, N, vtype=GRB.CONTINUOUS, name='u')
tau = model.addVar(name='tau')
lamb_obj = model.addMVar((N + 1,), lb=0, vtype=GRB.CONTINUOUS, name='lamb_obj')
lamb_1 = model.addMVar((N, N + 1), ub=0, vtype=GRB.CONTINUOUS, name='lamb_1')
lamb_2 = model.addMVar((N, N, N + 1), ub=0, vtype=GRB.CONTINUOUS, name='lamb_2')
model.addConstrs(b.T @ lamb_obj + quicksum(t[(i,j)]*u[(i,j)] for i in range(N) for j in range(N)) <= tau, name='blambobj')
model.optimize()
-
Hi Timo,
The MVar objects are meant to build matrix expression. The term \(b^T \cdot \lambda^{obj}\) is in your case a simple vector times vector, i.e., just a \(\sum_i^{N+1} b_i \cdot \lambda^{obj}_i\).
You can model the constraint as
N = 2
t = np.array([[0, 8.40717256], [2.550951155, 0]])
Gamma = 20*np.sqrt(N)
b = [Gamma for i in range(N+1)]
model = gp.Model('RO')
u = model.addVars(N, N, vtype=GRB.CONTINUOUS, name='u')
tau = model.addVar(name='tau')
lamb_obj = model.addVars(N + 1, lb=0, vtype=GRB.CONTINUOUS, name='lamb_obj')
model.addConstr( quicksum( b[i]*lamb_obj[i] for i in range(N+1)) + quicksum(t[i,j]*u[i,j] for i in range(N) for j in range(N)) <= tau, name="blambobj")
model.write("myLP.lp")
model.optimize()You can also keep the \(\texttt{lamb_obj}\) variables as \(\texttt{MVar}\) and still get access to the variables as a list by using the tolist() function.
lamb_obj = model.addMVar((N + 1,), lb=0, vtype=GRB.CONTINUOUS, name='lamb_obj')
lamb_obj_list = lamb_obj.tolist()
model.addConstr( quicksum( b[i]*lamb_obj_list[i] for i in range(N+1)) + quicksum(t[i,j]*u[i,j] for i in range(N) for j in range(N)) <= tau, name="blambobj")Note that I added the write() function to analyze the \(\texttt{myLP.lp}\) file and check whether the constructed problem has the desired form. You can proceed with the rest of your constraints in an analogous way.
On a side note. You can drop the
from gurobipy import GRB
line, since you import everything from the \(\texttt{gurobipy}\) module in the subsequent line by using the asterisk.
Best regards,
Jaromił -
Crosspost to stackoverflow.
-
Thank you very much. Using your first suggestion is very helpfull for the constrains containing the b vector. Although, now I seem to get lost trying to set up the first constraint containing the A matrix. How would I be able to set up the constraint containing matrix A? Should I treat the variables as normal variables or as matrix variables? As A is a matrix and lamb_obj a vector, and tij is a scalar and Vij a vector.
I have tried multiple things, but I am completely lost and I am getting this error: unsupported operand type(s) for *: 'float' and 'tupledict'.
My code now looks like this:
import gurobipy as gp
from gurobipy import *
import numpy as np
N = 2
t = np.array([[0, 8.40717256], [2.550951155, 0]])
Gamma = 20*np.sqrt(N)
b = [Gamma for i in range(N+1)]
I = np.identity(2)
A = np.vstack((I, [1,1]))
model = gp.Model('RO')
u = model.addVars(N, N, vtype=GRB.CONTINUOUS, name='u')
V = model.addVars(N, N, N, vtype=GRB.CONTINUOUS, name='v')
tau = model.addVar(name='tau')
lamb_obj = model.addVars(N + 1, lb=0, vtype=GRB.CONTINUOUS, name='lamb_obj')
model.addConstr(quicksum(b[i]*lamb_obj[i] for i in range(N+1)) + quicksum(t[i,j]*u[i,j] for i in range(N) for j in range(N)) <= tau, name="blambobj")
model.addConstr(A.T * lamb_obj >= quicksum(t[i,j]*V[i,j,k] for i in range(N) for j in range(N) for k in range(N)))
model.write("myLP.lp")
model.optimize()I hope you are able to support me. Thanks in advance
-
Hi Timo,
The problem with the constraint containing \(A^T\) is that while \(A^T \cdot \lambda^{obj}\) can be modeled with a Matrix API, the right hand side cannot because it does not have a vector form.
You can model this constraint as
N = 2
t = np.array([[0, 8.40717256], [2.550951155, 0]])
Gamma = 20*np.sqrt(N)
b = [Gamma for i in range(N+1)]
I = np.identity(2)
A = np.vstack((I, [1,1]))
print(A)
model = gp.Model('RO')
u = model.addVars(N, N, vtype=GRB.CONTINUOUS, name='u')
V = model.addVars(N, N, N, vtype=GRB.CONTINUOUS, name='v')
tau = model.addVar(name='tau')
lamb_obj = model.addVars(N + 1, lb=0, vtype=GRB.CONTINUOUS, name='lamb_obj')
model.addConstr( quicksum( b[i]*lamb_obj[i] for i in range(N+1)) + quicksum(t[i,j]*u[i,j] for i in range(N) for j in range(N)) <= tau, name="blambobj")
expr = quicksum(t[i,j]*V[i,j,k] for i in range(N) for j in range(N) for k in range(N))
for j in range(2):
model.addConstr( quicksum( A[i][j] * lamb_obj[i] for i in range(N+1)) >= expr, name="nextConstraint")
model.write("myLP.lp")
model.optimize()Note that I added the \(\texttt{expr}\) object to compute the right hand side of this constraint only once as it has 3 \(\texttt{for}\)-loops.
Best regards,
Jaromił
Please sign in to leave a comment.
Comments
5 comments