在python中,如何减少重复优化约束所使用的内存?

在python中,如何减少重复优化约束所使用的内存?,python,numpy,optimization,ram,cvxpy,Python,Numpy,Optimization,Ram,Cvxpy,我有一个简化形式的数学优化问题: min ∑Pxy s.t. Pxy≥Pyz, ∀x,y,z Pxy ∈ {0,1} 此问题具有XYZ约束。我编写以下代码来执行优化。我想到的唯一方法是引入两个新矩阵,通过与向量Pxy和Pyz相乘来重复约束。这些矩阵的大小分别为(XYZ*YZ)和(XYZ*XY)。随着问题维数的增加,这些矩阵的大小将变得巨大,我的RAM无法处理它。是否可以以一种对约束要求更少内存的方式重新编写此代码?(可能更少的内存使用会导致更快的速度) 下面的代码使用了google colab

我有一个简化形式的数学优化问题:

min ∑Pxy
s.t. Pxy≥Pyz, ∀x,y,z
Pxy ∈ {0,1}
此问题具有XYZ约束。我编写以下代码来执行优化。我想到的唯一方法是引入两个新矩阵,通过与向量Pxy和Pyz相乘来重复约束。这些矩阵的大小分别为(XYZ*YZ)和(XYZ*XY)。随着问题维数的增加,这些矩阵的大小将变得巨大,我的RAM无法处理它。是否可以以一种对约束要求更少内存的方式重新编写此代码?(可能更少的内存使用会导致更快的速度)

下面的代码使用了google colab上的所有RAM并崩溃了!(而优化问题很容易,可以手工解决)


感谢@sascha的评论,我使用
scipy.sparse.coo_matrix
重新编写了代码,内存问题得到了解决

我在这里发布修改后的代码:

import cvxpy as cp
import numpy as np
import scipy.sparse as sp

np.random.seed(55)
X_max, Y_max, Z_max = 70, 70, 50

P_yz = np.random.choice([0, 1], size=(Y_max, Z_max), p=[9./10, 1./10])
P_yz = P_yz.reshape(-1)

row = []
col = []
for x in range(X_max):
  for y in range(Y_max):
    for z in range(Z_max):
      ids = np.unravel_index(np.ravel_multi_index((x,y,z,x,y), (X_max, Y_max, Z_max, X_max, Y_max)), (X_max * Y_max * Z_max, X_max * Y_max))
      row.append(ids[0])
      col.append(ids[1])
z_repetition_sparse = sp.coo_matrix((np.ones(len(row)), (row, col)), shape=(X_max * Y_max * Z_max, X_max * Y_max))

row = []
col = []
for x in range(X_max):
  for y in range(Y_max):
    for z in range(Z_max):
      ids = np.unravel_index(np.ravel_multi_index((x,y,z,y,z), (X_max, Y_max, Z_max, Y_max, Z_max)), (X_max * Y_max * Z_max, Y_max * Z_max))
      row.append(ids[0])
      col.append(ids[1])
x_repetition_sparse = sp.coo_matrix((np.ones(len(row)), (row, col)), shape=(X_max * Y_max * Z_max, Y_max * Z_max))

P_xy = cp.Variable((X_max * Y_max), boolean=True)
constraints = [] 
constraints.append(z_repetition_sparse * P_xy >= sp.csr_matrix.dot(x_repetition_sparse, P_yz))
problem = cp.Problem(cp.Minimize(cp.sum(P_xy)), constraints) 
objective = problem.solve(verbose=True)
print(P_xy.value.reshape(X_max,-1))

这个问题对我来说没有多大意义,但这里的重要信息是:使用稀疏矩阵。无论如何,这些后端解算器都不会使用密集矩阵。不利用稀疏性的优化是很好的。。。稀有的查找lp标准表单,查看每个约束都是一行,只有2个非零条目,然后比较一些密集矩阵和一些csr_格式。同样重要的是:不仅存储稀疏,而且工作/构建稀疏。看看哪一个有点相似(及物性结构)。@sascha谢谢你的评论。它解决了我的记忆问题。这个问题是合成的,没有多大意义。我用它作为我的原始问题的一个最小的例子,这个问题有很多约束条件。
import cvxpy as cp
import numpy as np
import scipy.sparse as sp

np.random.seed(55)
X_max, Y_max, Z_max = 70, 70, 50

P_yz = np.random.choice([0, 1], size=(Y_max, Z_max), p=[9./10, 1./10])
P_yz = P_yz.reshape(-1)

row = []
col = []
for x in range(X_max):
  for y in range(Y_max):
    for z in range(Z_max):
      ids = np.unravel_index(np.ravel_multi_index((x,y,z,x,y), (X_max, Y_max, Z_max, X_max, Y_max)), (X_max * Y_max * Z_max, X_max * Y_max))
      row.append(ids[0])
      col.append(ids[1])
z_repetition_sparse = sp.coo_matrix((np.ones(len(row)), (row, col)), shape=(X_max * Y_max * Z_max, X_max * Y_max))

row = []
col = []
for x in range(X_max):
  for y in range(Y_max):
    for z in range(Z_max):
      ids = np.unravel_index(np.ravel_multi_index((x,y,z,y,z), (X_max, Y_max, Z_max, Y_max, Z_max)), (X_max * Y_max * Z_max, Y_max * Z_max))
      row.append(ids[0])
      col.append(ids[1])
x_repetition_sparse = sp.coo_matrix((np.ones(len(row)), (row, col)), shape=(X_max * Y_max * Z_max, Y_max * Z_max))

P_xy = cp.Variable((X_max * Y_max), boolean=True)
constraints = [] 
constraints.append(z_repetition_sparse * P_xy >= sp.csr_matrix.dot(x_repetition_sparse, P_yz))
problem = cp.Problem(cp.Minimize(cp.sum(P_xy)), constraints) 
objective = problem.solve(verbose=True)
print(P_xy.value.reshape(X_max,-1))