如何修复当前不等式求解器问题?是否有更优方案/库?
求解三元线性不等式组的问题排查与解决方案
问题描述
用户尝试编写Python脚本求解以下含三个变量的线性不等式组:
31x + 2.9y + 25z ≤ 160 23y + 1.3z ≤ 160 3.6x + 0.9y + 33z ≤ 50 165x + 110.9y + 402z ≤ 1730
用户编写的代码如下:
from sympy.abc import x, y, z from sympy import solve_rational_inequalities, Poly a = solve_rational_inequalities([ ((Poly(31*x + 2.9*y + 25*z), Poly(1)), '<=', Poly(160)), ((Poly(x), Poly(23*y), Poly(1.3*z), Poly(0)), '<=', Poly(160)), ((Poly(3.6*x), Poly(0.9*y), Poly(33*z), Poly(0)), '<=', Poly(50)), ((Poly(165*x), Poly(110.9*y), Poly(402*z), Poly(0)), '<=', Poly(1730)) ]) print(a)
执行后报错:
Traceback (most recent call last): File "/home/main.py", line 5, in <module> ((Poly(31*x + 2.9*y + 25*z), Poly(1)), '<=', Poly(160)), File "/usr/lib/python3/dist-packages/sympy/polys/polytools.py", line 164, in __new__ return cls._from_expr(rep, opt) File "/usr/lib/python3/dist-packages/sympy/polys/polytools.py", line 294, in _from_expr return cls._from_dict(rep, opt) File "/usr/lib/python3/dist-packages/sympy/polys/polytools.py", line 231, in _from_dict raise GeneratorsNeeded(sympy.polys.polyerrors.GeneratorsNeeded: can't initialize from 'dict' without generators
问题原因
- 参数格式错误:
solve_rational_inequalities要求每个不等式项是(分子多项式, 分母多项式)的二元组,你后续的不等式错误地将每个变量项单独构造为Poly,形成了多元组,不符合函数参数要求。 - 浮点数Poly兼容性问题:SymPy的Poly类对浮点数系数支持不佳,容易触发生成器初始化错误,建议改用分数系数或直接使用表达式。
- 工具选择不当:
solve_rational_inequalities更适合处理分式不等式,你的问题是线性不等式组,用reduce_inequalities更直接。
修复后的代码(SymPy实现)
使用reduce_inequalities直接处理线性不等式组,无需手动构造Poly:
from sympy.abc import x, y, z from sympy import reduce_inequalities # 定义不等式组,可按需添加变量非负约束 inequalities = [ 31*x + 2.9*y + 25*z <= 160, 23*y + 1.3*z <= 160, 3.6*x + 0.9*y + 33*z <= 50, 165*x + 110.9*y + 402*z <= 1730, x >= 0, y >= 0, z >= 0 ] # 求解并输出结果 solution = reduce_inequalities(inequalities, (x, y, z)) print(solution)
若要完全避免浮点数问题,可将系数转为分数:
from sympy.abc import x, y, z from sympy import Rational, reduce_inequalities inequalities = [ 31*x + Rational(29,10)*y + 25*z <= 160, 23*y + Rational(13,10)*z <= 160, Rational(18,5)*x + Rational(9,10)*y + 33*z <= 50, 165*x + Rational(1109,10)*y + 402*z <= 1730, x >= 0, y >= 0, z >= 0 ] solution = reduce_inequalities(inequalities, (x, y, z)) print(solution)
更适合的工具库
如果需要求解可行域顶点或进行线性规划求最优解,以下库更高效:
- SciPy linprog:专门用于线性规划,可直接求解目标函数最值,示例代码:
from scipy.optimize import linprog # 约束矩阵A(Ax <= b) A = [ [31, 2.9, 25], [0, 23, 1.3], [3.6, 0.9, 33], [165, 110.9, 402], [-1, 0, 0], # x >=0 转为 -x <=0 [0, -1, 0], # y >=0 [0, 0, -1] # z >=0 ] b = [160, 160, 50, 1730, 0, 0, 0] # 目标函数:求x+y+z最大值,转为求-(x+y+z)最小值 c = [-1, -1, -1] result = linprog(c, A_ub=A, b_ub=b, method='highs') print("最优解:", result.x) print("最优值:", -result.fun)
- PuLP:语法直观的线性规划建模库,支持多种求解器,适合复杂问题建模。
- CVXPY:专注凸优化,包括线性规划,语法简洁,支持自动约束推导。
内容的提问来源于stack exchange,提问作者Deyvid Dimitrov
相关产品推荐
相关产品推荐

