向 R 中的简单优化添加约束

问题描述

我已经在 SO 上查看了几个类似的问题,但仍然无法解决。但我希望添加一个约束,其中音量的变化(新音量/旧音量 - 1 >= -10%)不能小于 -10%。

示例

客户 Old_volume 弹性 价格
X 100 -0.68 15.00
#example dataset
df <- data.frame(customer = c("X"),old_volume = c(100),elasticity = c(-0.68),price = c(15.00))

#function
f3 <- function(x) {
         new_vol = 100 * (1+(-0.68 * x))
         new_rev = new_vol * (15.00 * (1+x))
         new_cost = new_vol * 11.25
     
         return(new_rev - new_cost)  }

n_vol <- function(x) {
         new_vol = 100 * (1+(-0.68 * x))
         return(new_vol)  }

#example run function
f3(0.25)
>>>[1] 622.5

#running the optimization
res <- optimize(f3,lower=0,upper=10,maximum = TRUE)
res$maximum
>>>0.6102941

res$objective
>>>[1] 754.9081

n_vol(0.6102941)
>>> 58.5

因此 vol 变化 % = 58.5/100-1 = -0.415,但我想将其限制为 -0.1。

现在我想添加一个约束,其中 new_vol/old_vol-1 >= -0.1。但是,我不确定如何使用 Optimize()optim()lpsolve() 添加它。我正在阅读 lpsolve() 文档,这似乎是要走的路,但我对 objective.in 中的系数向量感到困惑。还查看了其他包,例如 constrOptim,对于一维的东西来说似乎太复杂了。

谢谢

举个例子,通常在 Excel 上,我会有一堆带有这些计算的列,并在体积变化 >= -0.1 的约束下运行求解器。但是,当行数 > 1,000

时,运行宏花费的时间太长

编辑:添加输入示例

解决方法

您可以代数计算新边界。

change_inv <- function(frac,oldvol = 100) {  oldvol * (1 + frac) }
n_vol_inv <- function(vol) { (vol / 100 - 1) / -0.68 }
n_vol_inv(vol = change_inv(frac = -0.1))
# [1] 0.1470588
max_x <- optimize(f3,lower = 0,upper = n_vol_inv(vol = change_inv(-0.1)),maximum = TRUE)
max_x
# $maximum
# [1] 0.1469922
# 
# $objective
# [1] 535.9664
n_vol(max_x$maximum) / 100 - 1
# [1] -0.09995469

不幸的是,这意味着最大值只是边界。