简体   繁体   English

cplex.linear_constraints.add对于大型模型太慢

[英]cplex.linear_constraints.add too slow for large models

I've been trying to use cplex to solve an optimal transportation problem. 我一直在尝试使用cplex解决最佳运输问题。 The problem model is normally very large (in my description below the total number of variables are 1048576 (= 1024^2), and the number of constraints is 2048). 问题模型通常非常大(在我的描述中,变量的总数为1048576(= 1024 ^ 2),约束的数量为2048)。 My problem is that the process of adding constraints is far too slow to be practical ( the time spent in solving the model is fine though). 我的问题是添加约束的过程太慢而无法实用(尽管求解模型花费的时间很好)。 I googled this issue, there are some tips, but still I couldn't find a feasible solution. 我用谷歌搜索了这个问题,有一些技巧,但仍然找不到可行的解决方案。

The problem is as follows: Given two nonnegative vectors a and b of the same length 1024, and a 1024-by-1024 nonnegative matrix C . 问题如下:给定两个长度为1024的非负向量ab ,以及1024 x 1024的非负矩阵C。 Assuming that the sum over all elements of a is the same as that of b (np.sum(a) == np.sum(b)). 假设在所有元素的和是相同B的(np.sum的(a)== np.sum(B))。 I want to find a 1024-by-1024 nonnegative matrix X such that the sum of C[i,j] * X[i,j] is minimized, subject to the constraints that the sum of all elements of the i -th row of X equals to the i -th element of a and the sum of all elements of the j -th column of X equals to the j -th element of b , for all possible i and j , ie 我想找到一个1024 x 1024非负矩阵X ,使得C [i,j] * X [i,j]的总和最小,但要受第i行所有元素的总和的约束的X等于X的第j列的所有元素的总和i个元件,并且等于第j b的个元素,对于所有可能的ij,

Minimize:
C[0,0] * X[0,0] + C[0,1] * X[0,1] + ...  + C[1023,1023] * X[1023,1023]
Subject to:
All X[i,j] >= 0
X[0,0] + X[0,1] + ... + X[0,1023] == a[0]
X[1,0] + X[1,1] + ... + X[1,1023] == a[1]
...
X[1023,0] + X[1023,1] + ... X[1023,1023] == a[1023]
X[0,0] + X[1,0] + ... + X[1023,0] == b[0]
X[0,1] + X[1,1] + ... + X[1023,1] == b[1]
...
X[0,1023] + X[1,1023] + ... X[1023,1023] == b[1023]

My code is roughly like: (in the following code DOT is the transportation model; a and b are lists with length 1024, C is a list with length 1048576(= 1024 ** 2). 我的代码大致像这样:(在下面的代码中DOT是运输模型; a和b是长度为1024的列表,C是长度为1048576(= 1024 ** 2)的列表。

from __future__ import print_function
import cplex

DOT = cplex.Cplex()
DOT.objective.set_sense(DOT.objective.sense.minimize)

size = 1024
# set up names of variables
nms = ["x{0}".format(i) for i in range(size * size)]
# add variables to the model
DOT.variables.add(obj = C, names = nms) # C is a nonnegative list with length 1048576

constraints = list()
for i in range(size):
    constraints.append([nms[i * size : (i + 1) * size], [1.0] * size])

for i in range(size):
    constraints.append(cplex.SparsePair(nms[i : size * size : size], [1.0] * size))
rhs = a + b # a, b are nonnegative lists with the same length and sum
constraint_senses = ["E"] * (size * 2)
# the following line: adding constraints to model is too slow
DOT.linear_constraints.add(lin_expr = constraints, senses = constraint_senses, rhs = rhs)
# solve the model
DOT.solve()
# print some information
print("Solution status :", DOT.solution.get_status())
print("Cost            : {0:.5f}".format(DOT.solution.get_objective_value()))
print()

As I write in the comment, the process of adding constraints to the model is too slow. 正如我在评论中所写,向模型添加约束的过程太慢。 Is there any way to speed up it? 有什么办法可以加快速度吗?

Any help will be appreciated. 任何帮助将不胜感激。 Thanks in advance! 提前致谢!

You will get much better performance using indices rather than names. 使用索引而不是名称将获得更好的性能。 This is discussed in the documentation here . 此处的文档中对此进行了讨论。

Here is a modified version of your example (just the model building part) that uses indices: 这是使用索引的示例的修改版本(仅是模型构建部分):

from __future__ import print_function
import cplex

DOT = cplex.Cplex()
DOT.objective.set_sense(DOT.objective.sense.minimize)

size = 1024
C = [1.0] * (size * size)  # dummy data
# set up names of variables
nms = ["x{0}".format(i) for i in range(size * size)]
# add variables to the model and store indices as a list
nmindices = list(DOT.variables.add(obj = C, names = nms))

constraints = list()
for i in range(size):
    constraints.append([nmindices[i * size : (i + 1) * size], [1.0] * size])

for i in range(size):
    constraints.append(cplex.SparsePair(nmindices[i : size * size : size], [1.0] * size))
rhs = [1.0] * (size * 2)  # dummy data
constraint_senses = ["E"] * (size * 2)
# the following line: adding constraints to model is faster now
DOT.linear_constraints.add(lin_expr = constraints, senses = constraint_senses, rhs = rhs)
# write out the model in LP format for debugging
DOT.write("test.lp")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM