我想写一个Python脚本,解决给定的四个不等式系统,三个变量:
х * 31 + y * 2.9 + z * 25 <= 160
x * 0 + y * 23 + z * 1.3 <= 160
x * 3.6 + y * 0.9 + z * 33 <= 50
x * 165 + y * 110.9 + z * 402 <= 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
问题可能是什么,如何解决?还有,有没有更好的库来解决这些问题?
我不确定解决这个问题的最佳方法,但是使用这里已经提供的代码,您可以执行以下操作:
>>> from symyp import *
>>> from sympy.abc import x,y,z
>>> eqs = [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]
>>> eqs = [nsimplify(i, rational=True) for i in eqs]
>>> sol = solve_linear_inequalities(eqs,(x,y,z))
您将得到y的解,表明它在Interval(-oo, min(...functions of x and z...))
中。对min
中x和z的函数做同样的处理得到了类似Interval(-oo, min(...const or functions of x...))
的z的解。最后,对最小值内x的函数做同样的操作表明x在Interval(-oo, 5.16)内。所以对于(1,6)范围内的x,你可以计算出z和y对应的范围。
>>> yy = sol[y]
for xx in range(6):
for zz in range(6):
yi = yy.subs(x,xx).subs(z,zz).intersection(Range(1,oo))
if not yi:continue
print(xx,yi,zz)
,
0 Range(1, 7, 1) 0
0 Range(1, 7, 1) 1
1 Range(1, 7, 1) 0
1 Range(1, 7, 1) 1
2 Range(1, 7, 1) 0
2 Range(1, 7, 1) 1
3 Range(1, 7, 1) 0
3 Range(1, 7, 1) 1
4 Range(1, 7, 1) 0
4 Range(1, 3, 1) 1
5 Range(1, 2, 1) 0
如果没有要最大化的目标函数,看起来你的方程只有有限个整数解。也许这是足够的鼓励,让你朝着更通用的解决方案前进。此外,如果你给出x, y和z的兴趣范围,这将有所帮助,例如,如果它们都是正的,则给出每个变量的解
>>> sol = solve_linear_inequalities(eqs + [x>0,y>0,z>0], (x, y, z))
>>> for i in sol:
... print(i, sol[i])
z Interval(0, 50/33)
x Interval(0, Min(160/31 - 25*z/31, 346/33 - 134*z/55, 125/9 - 55*z/6))
y Interval(0, Min(160/23 - 13*z/230, -310*x/29 - 250*z/29 + 1600/29, -4*x - 110*z/3 + 500/9, -1650*x/1109 - 4020*z/1109 + 17300/1109))
从z的范围中选择一个值,计算x的有效范围并选择x的值,最后计算y的有效范围。