Создание целочисленного диапазона из нескольких строковых математических выражений в python

У меня возникла проблема в проекте, и я перерыл весь Интернет, не найдя четкого ответа. Как я могу преобразовать математические выражения As 3x + 5y >= 100 И x,y < 500 В диапазон x и диапазон y для использования в качестве ограничения в математической задаче, Например: f = x^2+4y Конечным результатом является нахождение наибольшего ответа с помощью генетических алгоритмов, где x и y ограничены по значению.

Пробовал sympy и eval безрезультатно. Обыскал все и нашел только несколько полезных, но недостаточных ресурсов. Мне нужно просто перевести пользовательский ввод в код для использования генетическим алгоритмом.

Ваш набор линейных неравенств определяет многоугольник на плоскости.

Краями этого многоугольника являются линии, определяемые каждым равенством, которое получается при замене знака неравенства на знак равенства в неравенстве.

Вершины этого многоугольника являются пересечениями двух смежных ребер; эквивалентно, они являются пересечениями двух ребер, которые удовлетворяют системе (больших) неравенств.

Итак, один из способов найти все вершины многоугольника - это найти каждую точку пересечения, решая каждую подсистему двух равенств, затем отфильтровывая точки, которые находятся вне многоугольника.

import numpy as np
from numpy.linalg import solve, LinAlgError
from itertools import combinations
import matplotlib.pyplot as plt

A = np.array([[-3, -5],[1,0],[0,1]])
b = np.array([-100,500,500])

# find polygon for system of linear inequations
# expects input in "less than" form:
# A X <= b
def get_polygon(A, b, tol = 1e-5):
    polygon = []
    for subsystem in map(list, combinations(range(len(A)), 2)):
        try:
            polygon.append(solve(A[subsystem], b[subsystem])) # solve subsystem of 2 equalities
        except LinAlgError:
            pass
    polygon = np.array(polygon)
    polygon = polygon[(polygon @ A.T <= b + tol).all(axis=1)] # filter out points outside of polygon
    return polygon

polygon = get_polygon(A, b)
polygon = np.vstack((polygon, polygon[0])) # duplicate first point of polygon to "close the loop" before plotting
plt.plot(polygon[:,0], polygon[:,1])
plt.show()

Обратите внимание, что get_polygon найдет все вершины многоугольника, но если их больше 3, они могут быть расположены не по часовой стрелке.

Если вы хотите отсортировать вершины по часовой стрелке перед построением многоугольника, я отсылаю вас к этому вопросу:

Использование подхода @Stef в SymPy даст треугольную область интереса следующим образом:

>>> from sympy.abc import x, y
>>> from sympy import intersection, Triangle, Line
>>> eqs = Eq(3*x+5*y,100), Eq(x,500), Eq(y,500)
>>> Triangle(*intersection(*[Line(eq) for eq in eqs], pairwise=True))
Triangle(Point2D(-800, 500), Point2D(500, -280), Point2D(500, 500))

Итак, x находится в диапазоне [-800, 500], а y находится в диапазоне [m, 500], где m - значение y, вычисленное из уравнения диагонали:

m = solve(eqs[0], y)[0]  # m(x)
def yval(xi):
    if xi <-800 or xi > 500:
        return
    return m.subs(x,xi)
yval(300) # -> -160
Вернуться на верх