CVXPY尝试提出大问题:ValueError:不允许使用负尺寸。这是RAM使用率问题吗?

时间:2019-09-25 07:34:33

标签: cvxpy

我认为尝试运行相当大的优化问题时遇到了问题。您可以在下面看到代码。变量b的大小为500 x96。我想做的是通过最小化它们之间的差异,使时间序列概要文件的总和(351236 x 15分钟时间步长)与较大的概要文件匹配。使用相同的公式和较小的问题(672个时间步长和b大小为10 x 5的变量),可以在2秒内解决问题,而不会出现问题。但是,当我针对全尺寸问题运行它时,出现下面的错误。

我正在Jupyter Lab和python 3.7.4上运行它。 python安装使用conda完成。

我希望这个问题能够像更小的问题一样得到解决。但是,当我运行这一程序时,RAM的使用量会爆炸高达100 GB(约占服务器上可用RAM的99%)。一段时间后,RAM使用率下降,然后开始周期性摆动(RAM每隔几分钟从50%上升到100%)。从错误和经过大量搜索之后,我怀疑问题对于内存而言太大,并且在某些时候数据正在分解成较小的部分。我认为解决方案无法完成工作。我试图通过对所有内容(当前版本)进行矢量化来优化代码,并尝试在配方中不包含循环等。但这并没有改变任何东西。如果这是错误或限制,你们有什么线索吗?或者您可能对如何解决这个问题有想法?

X_opt = cp.Constant(np.asarray(X.iloc[:,:500])) # the array size is (35136,500)
K_opt = cp.Constant(np.asarray(K.YearlyDemand)) # the vector size is 96
b = cp.Variable((500,96),boolean = True, value = np.zeros((500,96)))
Y_opt = cp.Constant(np.asarray(y)) # the vector size is 35136

constraints = []

constraints.append( cp.sum(b, axis = 0) == 1 ) # the sum of the elements of every column of b must be equal to 1
constraints.append( cp.sum(b, axis = 1) <= 1 ) # the sum of the elements of every row of b must be smaller or equal to 1

objective = cp.Minimize(cp.sum(cp.abs(Y_opt-cp.sum((cp.diag(K_opt)*((X_opt@b).T)).T, axis = 1))))

prob = cp.Problem(objective, constraints)

prob.solve(solver = cp.GLPK_MI, verbose = True)

ValueError跟踪(最近一次通话最近) 在

D:\Anaconda3\envs\py37DuAL\lib\site-packages\cvxpy\problems\problem.py in solve(self, *args, **kwargs)
287 else:
288 solve_func = Problem._solve
--> 289 return solve_func(self, *args, **kwargs)
290
291 @classmethod

D:\Anaconda3\envs\py37DuAL\lib\site-packages\cvxpy\problems\problem.py in _solve(self, solver, warm_start, verbose, parallel, gp, qcp, **kwargs)
567 self._construct_chains(solver=solver, gp=gp)
568 data, solving_inverse_data = self._solving_chain.apply(
--> 569 self._intermediate_problem)
570 solution = self._solving_chain.solve_via_data(
571 self, data, warm_start, verbose, kwargs)

D:\Anaconda3\envs\py37DuAL\lib\site-packages\cvxpy\reductions\chain.py in apply(self, problem)
63 inverse_data = []
64 for r in self.reductions:
---> 65 problem, inv = r.apply(problem)
66 inverse_data.append(inv)
67 return problem, inverse_data

D:\Anaconda3\envs\py37DuAL\lib\site-packages\cvxpy\reductions\matrix_stuffing.py in apply(self, problem)
98 # Batch expressions together, then split apart.
99 expr_list = [arg for c in cons for arg in c.args]
--> 100 Afull, bfull = extractor.affine(expr_list)
101 if 0 not in Afull.shape and 0 not in bfull.shape:
102 Afull = cvxtypes.constant()(Afull)

D:\Anaconda3\envs\py37DuAL\lib\site-packages\cvxpy\utilities\coeff_extractor.py in affine(self, expr)
76 size = sum([e.size for e in expr_list])
77 op_list = [e.canonical_form[0] for e in expr_list]
---> 78 V, I, J, b = canonInterface.get_problem_matrix(op_list, self.id_map)
79 A = sp.csr_matrix((V, (I, J)), shape=(size, self.N))
80 return A, b.flatten()

D:\Anaconda3\envs\py37DuAL\lib\site-packages\cvxpy\cvxcore\python\canonInterface.py in get_problem_matrix(linOps, id_to_col, constr_offsets)
65
66 # Unpacking
---> 67 V = problemData.getV(len(problemData.V))
68 I = problemData.getI(len(problemData.I))
69 J = problemData.getJ(len(problemData.J))

D:\Anaconda3\envs\py37DuAL\lib\site-packages\cvxpy\cvxcore\python\cvxcore.py in getV(self, values)
320
321 def getV(self, values):
--> 322 return _cvxcore.ProblemData_getV(self, values)
323
324 def getI(self, values):

ValueError: negative dimensions are not allowed

1 个答案:

答案 0 :(得分:0)

此问题已在此处解决

https://github.com/cvxgrp/cvxpy/issues/826#issuecomment-648618636

请注意,一般的问题是,大的问题会导致基础矩阵对于CVXPY使用的numpy.int32太大。您可以相当轻松地在CVXPY中修改代码,以继续使用SCS求解器。

您将必须在此处修改文件canonInterface.py:

D:\ Anaconda3 \ envs \ py37DuAL \ lib \ site-packages \ cvxpy \ cvxcore \ python \

如果找不到要修改的第二个文件,只需修改第一个文件,然后使用回溯找到第二个文件。