如何在CVXPY中定义目标函数 替代四重循环避免程序崩溃
解决CVXPY目标函数向量化优化问题
问题原因
你原来的四重循环实现会导致CVXPY的计算图生成O(n⁴)级别的运算节点,n只要大于10就会占用极高内存,最终卡死崩溃,必须通过矩阵运算向量化实现。
向量化实现代码
import cvxpy as cp import numpy as np # 假设已知输入: n(维度), A(n×n numpy数组), W(n×n numpy数组) # 预先计算W的行和与行和外积,都是常量不需要参与优化 d = np.sum(W, axis=1) d_matrix = np.outer(d, d) # 定义优化变量 F = cp.Variable((n, n)) # 第一项直接用Frobenius范数平方实现,替代双重循环 term1 = cp.sum_squares(A - F) / (n ** 2) # 第二项向量化实现,替代四重循环 cross_term = cp.sum(cp.multiply(W, F @ W @ F.T)) term2 = (2 * cp.sum(cp.multiply(F ** 2, d_matrix)) - 2 * cross_term) / (n ** 4) # 总目标函数 cost = term1 + term2 # 求解 objective = cp.Minimize(cost) prob = cp.Problem(objective) prob.solve() # 输出结果 print("最优F值:\n", F.value)
推导说明
将原第二项的四重求和展开平方后拆分,可以等价转换为矩阵运算形式:
- 展开平方项
(F[i,j] - F[i',j'])² = F[i,j]² + F[i',j']² - 2F[i,j]F[i',j'] - 对所有下标求和后,两个平方项的求和结果完全相等,合并为
2 * sum(F² ∘ (d d^T)),其中∘为逐元素乘法,d是W的行和向量 - 交叉项求和可以等价转换为
W和F@W@F.T逐元素相乘后的总和,和原四重循环的交叉项计算结果完全一致 - 两项合并后就得到代码中的term2表达式,运算复杂度从O(n⁴)降低到O(n³),n支持到数百维度也不会卡顿。
内容的提问来源于stack exchange,提问作者Eva Terriault
相关产品推荐
相关产品推荐

