如何在Julia中快速解决中等规模的QP公式?

时间:2018-07-11 22:02:49

标签: julia julia-jump

这是一个新手问题。我正在尝试最小化以下QP问题:

x'Qx + b'x + c,对于A.x> = lb 其中:

  1. x是坐标向量
  2. Q是典型的稀疏,强对角占优势的对称矩阵 大小为500,000 x 500,000到1M x 1M
  3. b是常数的向量
  4. c是一个常数
  5. A是一个单位矩阵
  6. lb是一个包含向量x下限的向量

以下是我尝试过的软件包:

  1. Optim.jl:它们具有用于简单“盒子”约束的原始内点算法。我已经尝试过将inner_optimizer设置为GradientDescent()/ ConjugateGradient()。无论这对于我的问题集来说似乎很慢。

  2. IterativeSolver.jl:他们有一个共轭梯度求解器,但没有办法为QP问题设置约束。

  3. MathProgBase.jl:它们具有专用于二次编程的求解器,称为Ipopt()。它对于通常在3Kx3K矩阵左右的小型数据集非常有效,但是对于我正在查看的数据集来说,它花费的时间太长。我知道将线性系统求解器从MUMPS更改为HSL或WSMP可能会产生重大改进,但是有没有办法通过Julia向Ipopt()添加第三方线性系统求解器?

  4. OSQP.jl:这又花费了太长时间,无法收敛到我感兴趣的数据集。

我还想知道是否有人使用大型数据集,他们是否可以提出一种使用现有软件包在Julia中真正快速解决这种规模问题的方法?

1 个答案:

答案 0 :(得分:1)

您可以尝试使用具有不同参数的OSQP求解器来加快特定问题的收敛速度。特别是:

  • 如果您有多个内核, MKL Pardiso 可以大大减少执行时间。您可以找到有关如何安装它的详细信息here(它主要是运行默认的MKL安装程序)。之后,您可以按以下步骤在OSQP中使用它

    model = OSQP.Model()
    OSQP.setup!(model; P=Q, q=b, A=A, l=lb, u=ub, linsys_solver="mkl pardiso")
    results = OSQP.solve!(model)
    
  • 迭代次数取决于您的步长rho 。 OSQP会自动更新它以寻找最佳的。如果遇到特定问题,可以禁用自动检测并自己玩。这是尝试使用其他rho

    的示例
    model = OSQP.Model()
    OSQP.setup!(model; P=Q, q=b, A=A, l=lb, u=ub, linsys_solver="mkl pardiso",
                adaptive_rho=false, rho=1e-3)
    results = OSQP.solve!(model)
    

    我建议您尝试使用不同的rho值,也许在1e-06 and 1e06之间进行日志间隔。

  • 您可以通过缩放问题数据来减少迭代次数,以使矩阵的条件数不会过高。这样可以大大减少迭代次数。

我非常确定,如果按照以下3个步骤操作,则可以使OSQP正常运行。如果您愿意共享数据(我是开发人员之一),我很高兴尝试OSQP。

稍微不相关的您可以使用MathProgBase.jlJuMP.jl来调用OSQP。它还支持最新的MathOptInterface.jl软件包,它将用MathProgBase.jl替代最新版本的JuMP。