Квадратичное программирование на Python с использованием Numpy? - PullRequest
0 голосов
/ 03 июля 2018

Я нахожусь в процессе перевода некоторого кода MATLAB на Python. Есть одна строка, которая доставляет мне немало хлопот:

[q,f_dummy,exitflag, output] = quadprog(H,f,-A,zeros(p*N,1),E,qm,[],[],q0,options);

Я посмотрел документацию в MATLAB и обнаружил, что функция quadprog используется для оптимизации (в частности, минимизации).

Я попытался найти похожую функцию в Python (используя numpy), и, похоже, ее нет.

Есть ли лучший способ перевести эту строку кода на Python? Или есть другие пакеты, которые можно использовать? Нужно ли создавать новую функцию, которая выполняет ту же задачу?

Спасибо за ваше время и помощь!

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

OSQP - это специализированный бесплатный решатель QP на основе ADMM. Я адаптировал демонстрационную документацию OSQP и вызов OSQP в репозитории qpsolvers для вашей проблемы.

Обратите внимание, что матрицы H и G должны быть разреженными в формате CSC . Вот сценарий

import numpy as np
import scipy.sparse as spa
import osqp


def quadprog(P, q, G=None, h=None, A=None, b=None,
             initvals=None, verbose=True):
    l = -np.inf * np.ones(len(h))
    if A is not None:
        qp_A = spa.vstack([G, A]).tocsc()
        qp_l = np.hstack([l, b])
        qp_u = np.hstack([h, b])
    else:  # no equality constraint
        qp_A = G
        qp_l = l
        qp_u = h
    model = osqp.OSQP()
    model.setup(P=P, q=q,
                A=qp_A, l=qp_l, u=qp_u, verbose=verbose)
    if initvals is not None:
        model.warm_start(x=initvals)
    results = model.solve()
    return results.x, results.info.status


# Generate problem data
n = 2   # Variables
H = spa.csc_matrix([[4, 1], [1, 2]])
f = np.array([1, 1])
G = spa.csc_matrix([[1, 0], [0, 1]])
h = np.array([0.7, 0.7])
A = spa.csc_matrix([[1, 1]])
b = np.array([1.])

# Initial point
q0 = np.ones(n)

x, status = quadprog(H, f, G, h, A, b, initvals=q0, verbose=True)
0 голосов
/ 04 июля 2018

Есть библиотека с именем CVXOPT , в которой есть квадратичное программирование.

def quadprog_solve_qp(P, q, G=None, h=None, A=None, b=None):
    qp_G = .5 * (P + P.T)   # make sure P is symmetric
    qp_a = -q
    if A is not None:
        qp_C = -numpy.vstack([A, G]).T
        qp_b = -numpy.hstack([b, h])
        meq = A.shape[0]
    else:  # no equality constraint
        qp_C = -G.T
        qp_b = -h
        meq = 0
    return quadprog.solve_qp(qp_G, qp_a, qp_C, qp_b, meq)[0] 
...