【问题标题】:constrained optimization R: another example约束优化 R:另一个例子
【发布时间】:2016-09-12 13:30:36
【问题描述】:

我正在尝试在 R 中执行约束优化。我查看了这些帖子和其他一些帖子:

constrained optimization in R

function constrained optimization in R

上面的第一篇文章很有帮助,但我仍然没有得到我的问题的正确答案。

我的功能是:

Fd <- 224 * d1 + 84 * d2 + d1 * d2 - 2 * d1^2 - d2^2

我的约束是:3 * d1 + d2 = 280

首先我使用无约束穷举搜索找到正确答案,然后是受限穷举搜索:

my.data <- expand.grid(x1 = seq(0, 200, 1), x2 = seq(0, 200, 1))
head(my.data)
dim(my.data)

d1     <- my.data[,1]
d2     <- my.data[,2]

Fd <- 224 * d1 + 84 * d2 + d1 * d2 - 2 * d1^2 - d2^2

new.data <- data.frame(Fd = Fd, d1 = d1, d2 = d2)
head(new.data)

# identify values of d1 and d2 that maximize Fd without the constraint
new.data[new.data$Fd == max(new.data$Fd),]
# **This is the correct answer**
#         Fd d1 d2
# 6157 11872 76 80


# Impose constraint
new.data <- new.data[(3 * new.data$d1 + new.data$d2) == 280, ]

# identify values of d1 and d2 that maximize Fd with the constraint
new.data[new.data$Fd == max(new.data$Fd),]
# **This is the correct answer**
#          Fd d1 d2
# 14743 11774 69 73

现在使用optim 找到不受约束的最大值。这行得通。

    Fd <- function(betas) {

         b1 = betas[1]
         b2 = betas[2]

         (224 * b1 + 84 * b2 + b1 * b2 - 2 * b1^2 - b2^2)

    }

    # unconstrained
    optim(c(60, 100), Fd, control=list(fnscale=-1), method = "BFGS", hessian = TRUE)
    # $par
    # [1] 75.99999 79.99995

现在使用constrOptim 找到约束最大值。这不起作用。

b1.lower.bound <- c(0, 280)
b1.upper.bound <- c(93.33333, 0)
b2.lower.bound <- c(93.33333, 0)
b2.upper.bound <- c(0, 280)

theta = c(60,100)                         # starting values
ui = rbind(c(280,0), c(0,93.33333))       # range of allowable values
theta %*% ui                              # obtain ci as -1 * theta %*% ui
#       [,1]     [,2]
# [1,] 16800 9333.333

constrOptim(c(60,100), Fd, NULL, ui = rbind(c(280,0), c(0,93.33333)), ci = c(-16800, -9333.333), control=list(fnscale=-1))
# $par
# [1] 75.99951 80.00798

我尝试过使用uici,但似乎无论我为它们使用什么值,我总是得到与不受约束的optim 相同的答案。

感谢您的建议。

【问题讨论】:

  • 请注意,在这种情况下,您可以解决 d1(或 d2)的约束并将其代入目标函数,将问题简化为一个变量中的无约束问题。
  • 谢谢。这是个好主意。虽然,为了完整起见,我仍然希望学习如何使用约束优化来解决它。

标签: r optimization


【解决方案1】:

constrOptim() 使用线性不等式 约束,并通过ui %*% param - ci &gt;= 0 定义可行域。如果约束为3 * d1 + d2 &lt;= 280,则uic(-3, -1)ci-280

构造优化(); 不等式约束为:3 * d1 + d2
Fd <- function(betas) {
    b1 = betas[1]
    b2 = betas[2]
   (224 * b1 + 84 * b2 + b1 * b2 - 2 * b1^2 - b2^2)
}

theta = c(59.999,100)    # because of needing " ui %*% inital_par - ci > 0 "
ui = c(-3, -1)
ci = -280                # those ui & ci mean " -3*par[1] + -1*par[2] + 280 >= 0 "

constrOptim(theta, Fd, NULL, ui = ui, ci = ci, control=list(fnscale=-1))
  # $par
  # [1] 69.00002 72.99993


[已编辑]

如果你想要的不是不等式而是等式约束,最好使用Rsolnpalabama 包。他们可以使用不等式和/或等式约束(参见Constrained Optimization library for equality and inequality constraints)。

解决方案();奥拉格(); 平等约束为:3 * d1 + d2 = 280
library(Rsolnp); library(alabama); 

Fd2 <- function(betas) {     #  -1 * Fd
   b1 = betas[1]
   b2 = betas[2]
   -1 * (224 * b1 + 84 * b2 + b1 * b2 - 2 * b1^2 - b2^2)
}

eqFd <- function(betas) {  # the equality constraint
    b1 = betas[1]
    b2 = betas[2]
    (3 * b1 + b2 -280)
}

solnp(pars = c(60, 100), fun = Fd2, eqfun = eqFd, eqB = 0)
auglag(par = c(60, 100), fn = Fd2, heq = eqFd)

【讨论】:

  • (-3, -1) 是否是约束上斜率的负数:3 * b1 + b2 = 280?
  • constrOptim() 使用线性不等式约束。在这种情况下,我限制了3 * b1 + b2 &lt;= 280,它相当于-3 * b1 - b2 + 280 &gt;= 0(这能回答你的问题吗?)
  • 我想是的。非常感谢你。这很有帮助。
  • 谢谢。这很有帮助。明天我可能会接受你的回答。我喜欢至少等待 24 小时。我很好奇为什么其他两个 R 包更好。虽然,我意识到我们不应该在 cmets 进行长时间的讨论。
  • 我接受你的回答。这非常很有帮助。但是,我认为您可能拼错了 Rsolnp 包的名称。
【解决方案2】:

在这里,我实施了 G. Grothendieck 的建议,它似乎返回了正确的答案。虽然,理想情况下,我想学习如何使用约束优化获得正确答案。我在这里使用了布伦特方法,因为只有一个变量。请注意,我必须在 optim 语句中提供上限和下限。

# Find maxima using optim and substitution.  First remove b2
#
# 3 * b1 + b2 = 280
#
# b2 = (280 - 3 * b1)

Fd <- function(betas) {

     b1 = betas[1]

     (224 * b1 + 84 * (280 - 3 * b1) + b1 * (280 - 3 * b1) - 2 * b1^2 - (280 - 3 * b1)^2)

}

optim(c(60), Fd, method = "Brent", lower = 0, upper = 93.33333, control=list(fnscale=-1))
# $par
# [1] 69

# Now remove b1
#
# 3 * b1 + b2 = 280
#
# b1 = ((280 - b2) / 3)

Fd <- function(betas) {

     b2 = betas[1]

     (224 * ((280 - b2) / 3) + 84 * b2 + ((280 - b2) / 3) * b2 - 2 * ((280 - b2) / 3)^2 - b2^2)

}

optim(c(100), Fd, method = "Brent", lower = 0, upper = 280, control=list(fnscale=-1))
# $par
# [1] 73

【讨论】:

  • 另请注意,这是一个二次方程,因此可以解析求解。
猜你喜欢
  • 2012-12-08
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-28
相关资源
最近更新 更多