Как исправить текущий решатель неравенства и есть ли лучший подход/библиотека?

Я пытаюсь написать скрипт 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

В чем может быть проблема, и как ее можно исправить? Кроме того, есть ли лучшая библиотека для решения таких проблем?

Ошибка генерируется ((Poly(31*x + 2.9*y + 25*z), Poly(1)), '<=', Poly(160)). Дело даже не в том, чтобы назвать решение. Я не работал с этим решателем, но ваши выражения не похожи на его задокументированные примеры.

hpaulj 13.04.2023 01:32

На первый взгляд, у системы неравенств может не быть единственного решения, поэтому, может быть, вам нужна характеристика выпуклой оболочки точек, удовлетворяющих неравенствам? или на картинке есть целевая функция, которую вы хотите минимизировать или максимизировать? Выглядит как интересная проблема, но, возможно, вы могли бы рассказать больше о том, что вы подразумеваете под словом «решить» в этом контексте.

Robert Dodier 13.04.2023 02:02

@RobertDodier Контекст таков, что я хочу найти все комбинации целых чисел X, Y, Z, которые удовлетворяют неравенствам. Кроме того, такие коэффициенты, как 31, 2,9, 25 и т. д., каждый раз будут разными числами, выступая в качестве параметров a, b и c. В приведенном примере даже X = Y = Z (> 0 и <= 1) удовлетворяют условиям.

Deyvid Dimitrov 13.04.2023 09:13

Посмотреть работу можно на github.com/sympy/sympy/pull/22389

smichr 13.04.2023 17:39

@DeyvidDimitrov Хорошо, потрясающе. Может быть, это поможет, если вы отредактируете свой вопрос, чтобы упомянуть об этом. Если я не ошибаюсь, оказывается, что эта проблема относится к рубрике «диофантовых неравенств»; веб-поиск находит некоторые ресурсы, например: mathoverflow.net/questions/69966/…

Robert Dodier 13.04.2023 18:42
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не уверен, как лучше это решить, но с помощью кода, который уже доступен здесь, вы можете сделать следующее:

>>> 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...)). Выполнение того же для функций x и z в min дает решение для z, подобное Interval(-oo, min(...const or functions of x...)). Наконец, то же самое для функций x в min показывает, что x находится в интервале (-oo, 5.16). Таким образом, для x в диапазоне (1,6) вы можете вычислить соответствующие диапазоны для 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.

Другие вопросы по теме