CVXR调用SCS求解凸优化问题时误报无界,求排查原因
CVXR调用SCS求解凸优化问题时误报无界,求排查原因
首先看你的问题描述,数学上目标函数确实有明确上界,但R版本的CVXR代码里藏着一个极易忽略的小错误——约束条件根本没被正确添加到优化问题中,这才导致SCS误判问题无界。
问题根源:R中append的使用误区
在R语言里,append()函数不会直接修改原列表,而是返回一个包含新增元素的新列表。你原代码里循环添加约束时,只是调用了append(constraints, list(...))但没有把结果赋值回constraints变量,所以最终constraints还是一个空列表!
对比Julia代码里的push!()——这个函数是直接在原数组上追加元素,约束能被正确添加。而你的R代码相当于完全没有约束,变量b和p可以任意取值:目标函数里的sum(b*logu),因为你的示例中u的元素都大于等于1,logu非负,b可以无限增大,目标函数会趋向正无穷,SCS报无界也就不奇怪了。
修正后的R代码
把约束构建部分改成下面这样,每次append后都将结果赋值回constraints:
library(CVXR) assemble_problem <- function(u, B) { # Get size of problem, number of goods and bidders m = nrow(u) # bidders n = ncol(u) # goods # Define variables b <- Variable(m, n, name="spending", nonneg=TRUE) p <- Variable(n, name="prices") # Assemble objective logu = apply(u, 1:2, log) # apply the log function to each entry in u objective <- Maximize(sum(b*logu) + sum(entr(p))) # Assemble constraints constraints <- list() # Budget constraints for (i in 1:m) { constraints <- append(constraints, list(sum(b[i,]) == B[i])) } # Spending constraints for (j in 1:n) { constraints <- append(constraints, list(sum(b[,j]) == p[j])) } # Create and return problem problem <- Problem(objective, constraints) return(problem) } # Example u <- matrix(c(1, 2, 3, 4), 2, 2) B <- c(1, 1) problem <- assemble_problem(u, B) solution <- solve(problem, solver = "SCS", FEASTOL = 1e-4, RELTOL = 1e-3, verbose = TRUE) # Check solution status now print(solution$status)
补充验证技巧
修正后你可以用length(constraints)在构建完约束后检查一下,确认约束数量是否符合预期(比如你的示例里应该有2个预算约束+2个价格约束,共4个),这样能快速排查这类“约束未生效”的问题。
备注:内容来源于stack exchange,提问作者grapher
相关产品推荐
相关产品推荐

