CVXR使用Mosek解决了二次最小化问题

时间:2019-02-05 18:29:50

标签: r optimization cvx mosek cvxr

我正在尝试使用R包CVXR解决具有线性约束的二次优化问题。尽管默认的求解器可以求解优化,但Mosek求解器不能。我希望使用Mosek的原因是因为我需要使用250多个约束来解决更大的问题,并且默认的求解器给出的解决方案不准确,所以我希望通过Mosek解决更大的问题。这是一个简单的示例,说明Mosek无法正常工作:

suppressMessages(suppressWarnings(library(CVXR)))

问题数据

set.seed(10)
n <- 10
SAMPLES <- 100
mu <- matrix(abs(rnorm(n)), nrow = n)
Sigma <- matrix(rnorm(n^2), nrow = n, ncol = n)
Sigma <- t(Sigma) %*% Sigma

表格问题

w <- Variable(n)
ret <- t(mu) %*% w
risk <- quad_form(w, Sigma)
constraints <- list(w >= 0, sum(w) == 1,ret==mean(mu))

风险厌恶参数

prob <- Problem(Minimize(risk), constraints)
result <- solve(prob,solver='MOSEK')

出现以下错误。

 Error in py_call_impl(callable, dots$args, dots$keywords) : 
  TypeError: 'int' object is not iterable 
10.stop(structure(list(message = "TypeError: 'int' object is not iterable", 
    call = py_call_impl(callable, dots$args, dots$keywords), 
    cppstack = structure(list(file = "", line = -1L, stack = c("1   reticulate.so                       0x000000010d278f9b _ZN4Rcpp9exceptionC2EPKcb + 219", 
    "2   reticulate.so                       0x000000010d27fa35 _ZN4Rcpp4stopERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE + 53",  ... 
9.mosek_intf at mosekglue.py#51
8.get_mosekglue()$mosek_intf(reticulate::r_to_py(A), b, reticulate::r_to_py(G), 
    h, c, dims, offset, reticulate::dict(solver_opts), verbose) 
7.Solver.solve(solver, objective, constraints, object@.cached_data, 
    warm_start, verbose, ...) 
6.Solver.solve(solver, objective, constraints, object@.cached_data, 
    warm_start, verbose, ...) 
5.CVXR::psolve(a, b, ...) 
4.CVXR::psolve(a, b, ...) 
3.solve.Problem(prob, solver = "MOSEK") 
2.solve(prob, solver = "MOSEK") 
1.solve(prob, solver = "MOSEK")

有人知道如何解决它,也许正在重新表达问题?

我的会话信息如下:

R version 3.5.2 (2018-12-20)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.1

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] reticulate_1.10  Matrix_1.2-15    CVXR_0.99-2      e1071_1.7-0.1    rstudioapi_0.9.0
[6] openxlsx_4.1.0  

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.0        lattice_0.20-38   class_7.3-14      gmp_0.5-13.2      R.methodsS3_1.7.1
 [6] grid_3.5.2        R6_2.3.0          jsonlite_1.6      zip_1.0.0         Rmpfr_0.7-2      
[11] R.oo_1.22.0       R.utils_2.7.0     tools_3.5.2       bit64_0.9-7       bit_1.1-14       
[16] compiler_3.5.2    scs_1.1-1         ECOSolveR_0.4    

谢谢

2 个答案:

答案 0 :(得分:4)

Python错误

TypeError: 'int' object is not iterable'

表明,对mosekglue.py中的mosek_intf的调用期望一个列表进行迭代(在未指定的地方),但是收到一个标量。这可能是由于以下事实引起的:由于所有内容都是R中的列表,因此网状结构处理单元素和多元素列表的方式有所不同(请参见其type conversions)。

仅阅读源代码,我的最佳猜测是mosekglue.py (line 102)失败,因为您的问题只有一个二阶锥(具体来说,我相信网状发送dims=dict(q: n)而不是{{ 1}})。

您的选择是向GitHub上的CVXR项目提交错误报告,然后等待,和/或努力确认我的怀疑(甚至可能提出修复并将其贡献给项目),和/或使用虚拟模型修改您的问题。材料,直到它滑过界面。

答案 1 :(得分:1)

这确实是Rails 5.1中的一个问题,已用CVXR-0.99-3及更高版本解决了;参见changelog

这是您计算出的示例:

mosekglue.py