Есть ли функция квадратичного программирования, которая может иметь как нижнюю, так и верхнюю границы - Python - PullRequest
2 голосов
/ 22 апреля 2019

Обычно я использую GNU Octave для решения задач квадратичного программирования.

Я решаю проблемы типа

x = 1/2x'Qx + c'x

С учетом

A*x <= b
lb <= x <= ub

Где lb и ub - нижние и верхние границы, например, ограничения для x

Мой код Octave выглядит следующим образом, когда я решаю. Всего одна простая строка

U = quadprog(Q, c, A, b, [], [], lb, ub);

Квадратные скобки [] пусты, потому что мне не нужны ограничения на равенство

Aeq*x = beq,

Итак, мой вопрос: Существует ли простой в использовании квадратичный решатель в Python для решения задач

x = 1/2x'Qx + c'x

С учетом

A*x <= b
lb <= x <= ub

или с учетом

b_lb <= A*x <= b_ub
lb <= x <= ub

1 Ответ

1 голос
/ 04 мая 2019

Вы можете написать свой собственный решатель на основе scipy.optimize, вот небольшой пример того, как кодировать ваш собственный питон quadprog():

# python3
import numpy as np
from scipy import optimize

class quadprog(object):

    def __init__(self, H, f, A, b, x0, lb, ub):
        self.H    = H
        self.f    = f
        self.A    = A
        self.b    = b
        self.x0   = x0
        self.bnds = tuple([(lb, ub) for x in x0])
        # call solver
        self.result = self.solver()

    def objective_function(self, x):
        return 0.5*np.dot(np.dot(x.T, self.H), x) + np.dot(self.f.T, x)

    def solver(self):
        cons = ({'type': 'ineq', 'fun': lambda x: self.b - np.dot(self.A, x)})
        optimum = optimize.minimize(self.objective_function, 
                                    x0          = self.x0.T,
                                    bounds      = self.bnds,
                                    constraints = cons, 
                                    tol         = 10**-3)
        return optimum

Вот как это использовать, используя те же переменныеиз первого примера, представленного в matlab-quadprog :

# init vars
H  = np.array([[ 1, -1],
               [-1,  2]])

f  = np.array([-2, -6]).T

A  = np.array([[ 1, 1],
               [-1, 2],
               [ 2, 1]])

b  = np.array([2, 2, 3]).T
x0 = np.array([1, 2])
lb = 0
ub = 2

# call custom quadprog
quadprog  = quadprog(H, f, A, b, x0, lb, ub)
print(quadprog.result)

Вывод этого короткого фрагмента:

     fun: -8.222222222222083
     jac: array([-2.66666675, -4.        ])
 message: 'Optimization terminated successfully.'
    nfev: 8
     nit: 2
    njev: 2
  status: 0
 success: True
       x: array([0.66666667, 1.33333333])

Для получения дополнительной информации о том, как использовать scipy.optimize.minimize пожалуйста, обратитесь к документам .

...