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 lotsizing 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