You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Clarabel作为CVXPY后端求解最小二乘问题为何显示原问题不可行?

三变量最小二乘优化问题:CVXPY调用Clarabel报错但直接调用正常的原因分析

问题背景

针对三变量三测量的最小二乘优化问题,分别采用两种方式求解,结果不一致:

  • 通过CVXPY调用Clarabel后端:构建带变量上下界及线性约束的优化问题后,调用prob.solve(solver="CLARABEL")返回PrimalInfeasible,无法得到解;
  • 直接调用Clarabel:手动构建二次规划问题的P、q、Ac、bc矩阵及锥约束,求解后可正常得到结果。

疑惑:是CVXPY使用存在认知缺失,还是CVXPY存在bug?

复现代码

import scipy
import numpy as np
import cvxpy as cvx
import clarabel

A = np.array([[-43.83695965,   0.34990409,  -1.32935518],
              [-48.86811152,   0.57411847,  -1.38219424],
              [-49.25621142,   0.75738835,  -1.2979702 ]])

b = np.array([  53897.91898074, -159390.11128713,  -62013.59835614])

bounds_arr = np.array([[-1., -1., -1.],
                       [ 1.,  1.,  1.]])

#------- 使用CVXPY调用CLARABEL后端---------------
x = cvx.Variable(A.shape[1])
cost = cvx.sum_squares(A @ x - b)

constraints = []
constraints += [xv >= bnd for (xv, bnd) in zip(x, bounds_arr[0])]
constraints += [xv <= bnd for (xv, bnd) in zip(x, bounds_arr[1])]
constraints += [x[0] + x[1] + x[2] >= -np.sqrt(3)] 
# constraints += [cvx.sum(x) >= -np.sqrt(3)] # 这种写法也无效

prob = cvx.Problem(cvx.Minimize(cost), constraints)
prob.solve(solver="CLARABEL", verbose=True) # 返回'PrimalInfeasible'
print("x: ", x.value)

#------- 直接调用CLARABEL---------------
P = A.T @ A
P = scipy.sparse.triu(P).tocsc()
q = -b.T @ A
# 注:常数项不影响优化解,故忽略

Ac = scipy.sparse.vstack([-scipy.sparse.identity(A.shape[1]), 
                           scipy.sparse.identity(A.shape[1]), 
                           np.array([[-1.0, -1.0, -1.0]])]).tocsc()

bc = np.concat([-bounds_arr[0], bounds_arr[1], [np.sqrt(3)]], axis=0)

cones = [clarabel.NonnegativeConeT(A.shape[1]), clarabel.NonnegativeConeT(A.shape[1]), clarabel.NonnegativeConeT(1)]
settings = clarabel.DefaultSettings()
solver = clarabel.DefaultSolver(P, q, Ac, bc, cones, settings)
solution = solver.solve() # 正常求解
print("x: ", solution.x)

问题分析与解决方案

核心结论

两种实现的约束逻辑完全一致,目标函数仅存在缩放差异(不影响可行性判断),因此问题大概率出在CVXPY与Clarabel的接口转换环节,而非用户的使用错误。

排查与解决步骤

  1. 对比问题转换结果
    开启verbose=True查看CVXPY生成的Clarabel问题参数(P、q、Ac、bc),与手动构建的逐一对比,重点检查线性约束行的符号、数值是否完全匹配。若存在差异,说明CVXPY的约束转换存在bug。

  2. 调整求解器参数
    手动传递Clarabel的配置参数,放宽可行性容忍度,尝试规避数值精度问题:

    settings = clarabel.DefaultSettings()
    settings.feasibility_tolerance = 1e-6  # 可根据情况调整
    prob.solve(solver="CLARABEL", verbose=True, settings=settings)
    
  3. 交叉验证求解器
    使用其他CVXPY支持的求解器(如ECOS、OSQP)运行同一问题:

    prob.solve(solver="ECOS", verbose=True)
    
    • 若其他求解器能得到解,说明CVXPY与Clarabel的接口存在bug,建议更新CVXPY和Clarabel到最新版本;
    • 若其他求解器也报不可行,则需重新检查手动构建的Clarabel问题是否存在约束转换错误(从当前代码看,手动转换逻辑是正确的)。
  4. 临时替代方案
    若确认是接口bug,可暂时采用手动构建Clarabel问题的方式实现,或等待CVXPY/Clarabel修复对应问题。

内容的提问来源于stack exchange,提问作者Charlie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 02:50:59