I turned to CPLEX, since I have quite a big linear problem to solve.
If we use scipy.optimize.linprog notation:
minimize: c^T * x
subject to: A_ub * x <= b_ub and A_eq * x == b_eq,
then my A_ub matrix has a shape of roughly (20000, 10000): 20000 constraints, 10000 variables.
It is very fast to construct matrices A_ub, A_eq and vectors c, b_ub, b_eq using numpy.
But creating a CPLEX problem out of it takes around 30 seconds (which is not acceptable in my situation). This happens, because their Python API cannot take a matrix as an input (at least I could not find such functionality after couple of days of testing different scenarios).
The only way to create a problem is to construct it either column by column or row by row, like this:
problem = cplex.Cplex()
problem.set_problem_type(problem.problem_type.LP)
problem.objective.set_sense(problem.objective.sense.minimize)
problem.variables.add(obj=c)
n_constraints, n_vars = A_ub.shape
index = list(range(n_vars))
list_rhs = list(b_ub)
# for each row (constraint) create a SparsePair instance
sparse_pairs = [cplex.SparsePair(ind=index, val=A_ub[i]) for i in range(n_constraints)]
# this piece takes 30 seconds
problem.linear_constraints.add(
lin_expr=sparse_pairs,
rhs=list_rhs,
senses=['L'] * n_less_cons
)
I also tried to do it column by column and by directly filling coefficients, but everything is equally slow.
I cannot believe it is normal, that formulating a problem takes 6-7 times longer than actually solving the problem (solving takes 4-5 seconds).
Does anybody know, whether there is a faster way to create a problem in CPLEX?
Currently, it is faster to solve the problem with cvxopt using open-source GLPK (15 sec), because it directly takes matrices as an input, like scipy.linprog.
P.S. I also checked Gurobi's Python API and it has the same problem (it works even slower).