CVXPY求解正定二次规划误判无界的原因及调试问询
二次规划问题CVXPY返回unbounded状态的疑问
我遇到一种特殊情况:对于一个确定存在解的二次规划问题,CVXPY返回了None解,状态为unbounded。
因无法输入LaTeX,约定@表示矩阵乘法,.T表示转置,小写字母为列向量,大写字母为矩阵。我要求解的最小化问题形式为:
min_w ( w.T @ A @ w + 2 w.T @ b )
当A为对称正定矩阵时,该问题应有解。通过配方可重构为:
min_w ( (U.T @ w + c).T @ (U.T @ w + c) - c.T @ c )
其中c = U^(-1) @ b,A = U @ U.T,U是特征向量矩阵乘以包含特征值平方根的对角矩阵。
但在以下示例中,A为对称正定矩阵,CVXPY却无法找到解:
import numpy as np import cvxpy as cp A = np.array([ [4.06361264e-05, 4.78152602e-05, 3.58988931e-05, 3.45978540e-05, 4.56347190e-05, 3.30402841e-05], [4.78152602e-05, 6.20243040e-05, 4.44641914e-05, 4.39168274e-05, 5.87695986e-05, 4.13444571e-05], [3.58988931e-05, 4.44641914e-05, 5.11820897e-05, 3.16788337e-05, 4.22214735e-05, 3.07681460e-05], [3.45978540e-05, 4.39168274e-05, 3.16788337e-05, 3.43880152e-05, 4.18058439e-05, 3.05503889e-05], [4.56347190e-05, 5.87695986e-05, 4.22214735e-05, 4.18058439e-05, 5.68791131e-05, 3.93696860e-05], [3.30402841e-05, 4.13444571e-05, 3.07681460e-05, 3.05503889e-05, 3.93696860e-05, 3.06327553e-05] ]) K = np.array([ [4.37566619e-05, 2.69688463e-05, 4.38180809e-05], [5.45281929e-05, 3.46869714e-05, 5.63081373e-05], [4.43561108e-05, 2.42773248e-05, 4.05177865e-05], [3.92084931e-05, 2.55688144e-05, 3.98470925e-05], [5.20176190e-05, 3.29607102e-05, 5.30698420e-05], [3.72710707e-05, 2.41940081e-05, 3.80516226e-05] ]) h = np.array([ 5151.2868695 , 1970.57848573, 10322.36834168]) b = K @ h w = cp.Variable(len(A)) objective_1 = cp.Minimize(w @ A @ w + 2 * w @ b) constraints = [True] prob = cp.Problem(objective_1, constraints) prob.solve() solution = w.value print(f"Solution: {solution}, status: {prob.status}")
输出结果:
Solution: None, status: unbounded
A的条件数并不差,我有三个疑问:
- 这类问题的原因是什么?是浮点数运算问题吗?
- 作为CVXPY和二次编程新手,该如何调试这种应有解但求解器找不到解的情况?
- 是否我有误判,该问题实际确实无解?
问题解答
1. 问题原因:浮点数精度与量级失衡
你的A矩阵理论上是对称正定,但实际浮点数计算中存在两个关键问题:
- 正定性判定的容差问题:求解器对矩阵正定性的判定有数值容差,若A的特征值非常接近0(甚至因舍入误差出现极小负值),会被误判为半正定或不定矩阵,进而认为目标函数可能无下界。
- 目标函数量级失衡:二次项系数是1e-5级别,而线性项
2*w@b中,h的数值是数千级别,导致线性项量级远大于二次项。这种失衡会让求解器在数值计算中难以稳定捕捉二次项的凸性,最终误判问题无界。
2. 调试方法
- 验证矩阵正定性:用
np.linalg.eigvalsh(A)计算A的特征值,确认所有特征值严格大于0且远离浮点数精度阈值(如1e-10)。若有特征值接近0,可给A添加小正则项,比如A + 1e-8*np.eye(len(A)),强化正定性。 - 缩放目标函数:将A和b同时放大相同倍数(如1e5),让二次项和线性项量级统一,避免数值计算不稳定。
- 更换求解器:CVXPY默认求解器对数值敏感问题表现有限,可尝试指定
prob.solve(solver=cp.ECOS)或prob.solve(solver=cp.SCS),不同求解器的数值稳定性差异较大。 - 手动计算解析解验证:无约束二次规划的解析解为
w = -A^{-1}@b,计算该解并代入目标函数,确认能得到有限最小值,以此验证问题有解。
3. 问题是否真的无解?
该问题必然有解。因为A是对称正定矩阵,目标函数是严格凸二次函数,无约束下存在唯一最小值点。出现unbounded状态完全是求解器的数值误判,而非问题本身无解。你可以手动计算解析解验证:
w_opt = -np.linalg.inv(A) @ b print(w_opt)
代入目标函数会得到有限的最小值,证明问题存在解。
内容的提问来源于stack exchange,提问作者Marses
相关产品推荐
相关产品推荐

