二次程序(QP)求解器仅依赖于NumPy/SciPy?

flx*_*lxb 31 python numpy mathematical-optimization scipy

我希望学生在任务中解决一个二次方程,而不必安装额外的软件,如cvxopt等.是否有可用的python实现只依赖于NumPy/SciPy?

ali*_*i_m 39

我不太熟悉二次规划,但我认为你可以使用scipy.optimize约束最小化算法来解决这类问题.这是一个例子:

import numpy as np
from scipy import optimize
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D

# minimize
#     F = x[1]^2 + 4x[2]^2 -32x[2] + 64

# subject to:
#      x[1] + x[2] <= 7
#     -x[1] + 2x[2] <= 4
#      x[1] >= 0
#      x[2] >= 0
#      x[2] <= 4

# in matrix notation:
#     F = (1/2)*x.T*H*x + c*x + c0

# subject to:
#     Ax <= b

# where:
#     H = [[2, 0],
#          [0, 8]]

#     c = [0, -32]

#     c0 = 64

#     A = [[ 1, 1],
#          [-1, 2],
#          [-1, 0],
#          [0, -1],
#          [0,  1]]

#     b = [7,4,0,0,4]

H = np.array([[2., 0.],
              [0., 8.]])

c = np.array([0, -32])

c0 = 64

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

b = np.array([7., 4., 0., 0., 4.])

x0 = np.random.randn(2)

def loss(x, sign=1.):
    return sign * (0.5 * np.dot(x.T, np.dot(H, x))+ np.dot(c, x) + c0)

def jac(x, sign=1.):
    return sign * (np.dot(x.T, H) + c)

cons = {'type':'ineq',
        'fun':lambda x: b - np.dot(A,x),
        'jac':lambda x: -A}

opt = {'disp':False}

def solve():

    res_cons = optimize.minimize(loss, x0, jac=jac,constraints=cons,
                                 method='SLSQP', options=opt)

    res_uncons = optimize.minimize(loss, x0, jac=jac, method='SLSQP',
                                   options=opt)

    print '\nConstrained:'
    print res_cons

    print '\nUnconstrained:'
    print res_uncons

    x1, x2 = res_cons['x']
    f = res_cons['fun']

    x1_unc, x2_unc = res_uncons['x']
    f_unc = res_uncons['fun']

    # plotting
    xgrid = np.mgrid[-2:4:0.1, 1.5:5.5:0.1]
    xvec = xgrid.reshape(2, -1).T
    F = np.vstack([loss(xi) for xi in xvec]).reshape(xgrid.shape[1:])

    ax = plt.axes(projection='3d')
    ax.hold(True)
    ax.plot_surface(xgrid[0], xgrid[1], F, rstride=1, cstride=1,
                    cmap=plt.cm.jet, shade=True, alpha=0.9, linewidth=0)
    ax.plot3D([x1], [x2], [f], 'og', mec='w', label='Constrained minimum')
    ax.plot3D([x1_unc], [x2_unc], [f_unc], 'oy', mec='w',
              label='Unconstrained minimum')
    ax.legend(fancybox=True, numpoints=1)
    ax.set_xlabel('x1')
    ax.set_ylabel('x2')
    ax.set_zlabel('F')
Run Code Online (Sandbox Code Playgroud)

输出:

Constrained:
  status: 0
 success: True
    njev: 4
    nfev: 4
     fun: 7.9999999999997584
       x: array([ 2.,  3.])
 message: 'Optimization terminated successfully.'
     jac: array([ 4., -8.,  0.])
     nit: 4

Unconstrained:
  status: 0
 success: True
    njev: 3
    nfev: 5
     fun: 0.0
       x: array([ -2.66453526e-15,   4.00000000e+00])
 message: 'Optimization terminated successfully.'
     jac: array([ -5.32907052e-15,  -3.55271368e-15,   0.00000000e+00])
     nit: 3
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 您的学生需要解决的问题有多难?SLSQP在大约1.33毫秒内解决了我(当然相当简单)的例子.它还可以处理边界,不等式和等式约束的任何组合.如果您的心脏被设置为使用针对QP优化的特定求解器,那么您可能必须(A)让您的学生安装额外的依赖项,或者(B)自己编写. (8认同)
  • 值得将 'jac':(lambda x:-A) 添加到约束定义中,以使求解器更加稳健。 (3认同)

Cur*_*ous 10

这可能是一个迟到的答案,但我发现CVXOPT- http://cvxopt.org/ - 作为常用的免费python库Quadratic Programming.但是,安装起来并不容易,因为它需要安装其他依赖项.

  • 这个库是我切换到Anaconda以便于管理依赖项的原因之一.我只是无法用pip安装它.如果您已经拥有Anaconda,请使用`conda install -c https://conda.anaconda.org/omnia cvxopt`并完成.我在Windows 10和Python 2.7上. (3认同)
  • 请注意,该问题明确要求求解器“不需要”安装“cvxopt” (3认同)
  • 好吧,正如您所描述的,安装并不容易:-) 投票作为我对建议的感谢,但我想我会先尝试其他选项。 (2认同)
  • @JimRaynor我在OS X中直接用`pip install cvxopt`安装`cvxopt`没问题。就是这样。pip负责一切。而且我已经在多台机器上安装了`cvxopt`。当然,您需要安装编译器,但这也很简单,如果您使用的是`scipy`,则很可能已经安装了它们。如果有帮助,我将Anaconda用作Python发行版(完全免费),并且安装Anaconda也很简单。您不需要管理员权限,也不需要配置任何内容。只需下载,安装并准备就绪即可。 (2认同)

Tom*_*cek 5

我遇到了一个很好的解决方案,想要把它拿出来.在NICTA的ELEFANT机器学习工具包中有一个关于LOQO的python实现(http://elefant.forge.nicta.com.au截至本文).看看optimization.intpointsolver.这是由Alex Smola编写的,我使用了相同代码的C版本并取得了巨大成功.

  • 我不相信该项目是活跃的。下载链接已损坏,但此链接有效:https://elefant.forge.nicta.com.au/download/release/0.4/index.html 该项目有一个 C++ 分支,位于 http://users.cecs。 anu.edu.au/~chteo/BMRM.html,但我也不相信它是活跃的。 (2认同)

Tas*_*ian 5

qpsolvers包似乎也符合要求。它仅依赖于 NumPy,并且可以通过pip install qpsolvers. 然后,你可以这样做:

from numpy import array, dot
from qpsolvers import solve_qp

M = array([[1., 2., 0.], [-8., 3., 2.], [0., 1., 1.]])
P = dot(M.T, M)  # quick way to build a symmetric matrix
q = dot(array([3., 2., 3.]), M).reshape((3,))
G = array([[1., 2., 1.], [2., 0., 1.], [-1., 2., -1.]])
h = array([3., 2., -2.]).reshape((3,))

# min. 1/2 x^T P x + q^T x with G x <= h
print "QP solution:", solve_qp(P, q, G, h)
Run Code Online (Sandbox Code Playgroud)

您还可以通过更改关键字参数来尝试不同的 QP 求解器(例如 Curious 提到的 CVXOPT)solver,例如solver='cvxopt'solver='osqp'