使用CVXPY调用CVXOPT求解LP问题失败,求故障原因
问题:CVXOPT求解简单线性规划问题失败,切换ECOS可正常求解
我尝试用CVXPY结合CVXOPT求解一个简单的线性规划问题,代码如下:
import cvxpy as cp import numpy as np n = 2 x = cp.Variable(n) prob = cp.Problem(cp.Maximize(cp.sum(x)), [cp.sum(x) <= 10]) prob.solve(solver=cp.CVXOPT, verbose=True) print("\nThe optimal value is", prob.value) print("A solution x is") print(x.value) print("A dual solution is") print(prob.constraints[0].dual_value)
运行后得到错误输出:
=============================================================================== CVXPY v1.4.3 =============================================================================== (CVXPY) Apr 17 08:41:27 PM: Your problem has 2 variables, 1 constraints, and 0 parameters. (CVXPY) Apr 17 08:41:27 PM: It is compliant with the following grammars: DCP, DQCP (CVXPY) Apr 17 08:41:27 PM: (If you need to solve this problem multiple times, but with different data, consider using parameters.) (CVXPY) Apr 17 08:41:27 PM: CVXPY will first compile your problem; then, it will invoke a numerical solver to obtain a solution. (CVXPY) Apr 17 08:41:27 PM: Your problem is compiled with the CPP canonicalization backend. ------------------------------------------------------------------------------- Compilation ------------------------------------------------------------------------------- (CVXPY) Apr 17 08:41:27 PM: Compiling problem (target solver=CVXOPT). (CVXPY) Apr 17 08:41:27 PM: Reduction chain: FlipObjective -> Dcp2Cone -> CvxAttr2Constr -> ConeMatrixStuffing -> CVXOPT (CVXPY) Apr 17 08:41:27 PM: Applying reduction FlipObjective (CVXPY) Apr 17 08:41:27 PM: Applying reduction Dcp2Cone (CVXPY) Apr 17 08:41:27 PM: Applying reduction CvxAttr2Constr (CVXPY) Apr 17 08:41:27 PM: Applying reduction ConeMatrixStuffing (CVXPY) Apr 17 08:41:27 PM: Applying reduction CVXOPT (CVXPY) Apr 17 08:41:27 PM: Finished problem compilation (took 2.427e-03 seconds). ------------------------------------------------------------------------------- Numerical solver ------------------------------------------------------------------------------- (CVXPY) Apr 17 08:41:27 PM: Invoking solver CVXOPT to obtain a solution. Traceback (most recent call last): File "/home/me/test2.py", line 8, in <module> prob.solve(solver=cp.CVXOPT, verbose=True) File "/home/me/venv/lib/python3.10/site-packages/cvxpy/problems/problem.py", line 503, in solve return solve_func(self, *args, **kwargs) File "/home/me/venv/lib/python3.10/site-packages/cvxpy/problems/problem.py", line 1086, in _solve self.unpack_results(solution, solving_chain, inverse_data) File "/home/me/venv/lib/python3.10/site-packages/cvxpy/problems/problem.py", line 1411, in unpack_results raise error.SolverError( cvxpy.error.SolverError: Solver 'CVXOPT' failed. Try another solver, or solve with verbose=True for more information.
切换为默认求解器ECOS后能返回正确解,为何CVXOPT无法解决该问题?已尝试重装相关包并查阅文档,未解决问题。
解答
核心原因分析
这个问题的根源在于你的线性规划问题存在无穷多最优解,CVXOPT与ECOS对这种退化情况的处理逻辑存在差异:
- 目标是最大化
sum(x),约束为sum(x) ≤10,所有满足sum(x)=10的x都是最优解(比如[10,0]、[5,5]等),属于典型的退化LP问题。 - CVXOPT的内部收敛判定逻辑对这类无唯一最优解的情况鲁棒性较弱,容易触发求解失败;而ECOS对退化问题的数值稳定性处理更友好,能够正常返回可行的最优解。
- 此外,CVXPY将LP问题转换为锥形式时,可能给CVXOPT传递了不符合其默认收敛阈值的问题形式,进一步加剧了求解失败的概率。
解决办法
添加约束消除解的退化性:给变量增加简单的边界约束,让问题拥有唯一或更稳定的最优解,示例代码:
prob = cp.Problem(cp.Maximize(cp.sum(x)), [cp.sum(x) <= 10, x >= 0])此时CVXOPT通常能正常求解,最优解会是
[10,0]这类顶点解。调整CVXOPT的求解参数:放宽收敛阈值(如
abstol绝对误差、reltol相对误差),让CVXOPT接受退化问题的解,示例代码:prob.solve(solver=cp.CVXOPT, verbose=True, abstol=1e-6, reltol=1e-6)直接使用CVXOPT原生接口:绕开CVXPY的转换层,直接用CVXOPT的LP接口定义问题,避免锥转换带来的额外问题,示例代码:
from cvxopt import matrix, solvers # CVXOPT默认求解最小化问题,因此将目标取反 c = matrix([-1.0, -1.0]) A = matrix([[1.0, 1.0]]) b = matrix([10.0]) sol = solvers.lp(c, A, b) print("最优解:", sol['x']) print("最优值:", -sol['primal objective'])
内容的提问来源于stack exchange,提问作者asfiwefewrno
相关产品推荐
相关产品推荐

