Существует ли библиотека-обертка для решения задач оптимизации путем объявления известных и неизвестных переменных? - PullRequest
0 голосов
/ 10 ноября 2019

cvxpy имеет очень аккуратный способ выписать форму оптимизации, не слишком заботясь о преобразовании ее в «стандартную» матричную форму, поскольку это делается каким-то образом внутри. Лучше всего объяснить на примере:

def cvxpy_implementation():

    var1 = cp.Variable()
    var2 = cp.Variable()

    constraints = [
            var1 <= 3,
            var2 >= 2
    ]

    obj_fun = cp.Minimize(var1**2 + var2**2)

    problem = cp.Problem(obj_fun, constraints)
    problem.solve()

    return var1.value, var2.value


def scipy_implementation1():

    A = np.diag(np.ones(2))
    lb = np.array([-np.inf, 2])
    ub = np.array([3, np.inf])

    con = LinearConstraint(A, lb, ub)

    def obj_fun(x):
        return (x**2).sum()
    result = minimize(obj_fun, [0, 0], constraints=con)
    return result.x

def scipy_implementation2():

    con = [
        {'type': 'ineq', 'fun': lambda x: 3 - x[0]},
        {'type': 'ineq', 'fun': lambda x: x[1] - 2},]

    def obj_fun(x):
        return (x**2).sum()

    result = minimize(obj_fun, [0, 0], constraints=con)
    return result.x

Все вышеперечисленное дает правильный результат, но реализацию cvxpy гораздо «проще» записать, особенно мне не нужно беспокоиться о неравенствах и могуИмя переменной полезно мыслить при выписывании неравенств. Сравните это с реализациями scipy1 и scipy2, где в первом случае я должен выписать эти дополнительные inf s, а во втором случае я должен вспомнить, какая переменная какая. Вы можете представить себе случай, когда у меня есть 100 переменных, и в то время как их объединение, в конечном счете, должно быть выполнено, я бы хотел написать его, как в cvxpy.

Вопрос: Кто-нибудь реализовал это для scipy? или есть альтернативная библиотека, которая могла бы сделать эту работу?

спасибо

1 Ответ

0 голосов
/ 13 ноября 2019

Написал что-то, что сделало бы это, и, кажется, покрывает основные проблемы, которые я имел в виду.

Общая идея состоит в том, что вы определяете переменные, а затем создаете простое выражение, как обычно выписываете его, а затемкласс решателя оптимизируется по определенным переменным

https://github.com/evan54/optimisation/blob/master/var.py

Пример ниже иллюстрирует простой пример использования

# fake data 
a = 2
m = 3 
x = np.linspace(0, 10) 
y = a * x + m + np.random.randn(len(x)) 
a_ = Variable() 
m_ = Variable() 
y_ = a_ * x + m_ 
error = y_ - y 
prob = Problem((error**2).sum(), None) 
prob.minimize() print(f'a = {a}, a_ = {a_}') print(f'm = {m}, m_ = {m_}')
...