R:如何向 DEoptim 添加额外的约束

R: How to add additional constraints to DEoptim

我正在尝试使用 DEoptim 最小化 objective 函数,但要服从一个简单的约束。我不清楚如何将简单约束添加到对 DEoptim 的调用中。这是 objective 函数:

obj_min <- function(n,in_data) {
    gamma <- in_data$Gamma
    delta <- in_data$Delta
    theta <- in_data$Theta
    gammaSum <- sum(n * gamma)
    deltaSum <- sum(n * delta)
    thetaSum <- sum(n * theta)
    abs((EPC * gammaSum - 2 * abs(deltaSum)) / thetaSum )
}

我的映射函数(施加整数约束)如下:

 mappingFun <- function(x) {
    x[1:length(x)] <- round(x[1:length(x)], 0)
 }

我对 DEoptim 的调用是:

 out <- DEoptim(DTRRR_min, lower = c(rep(-5, length(in_data[, 1]))),
        upper = c(rep(5, length(in_data[, 1]))),
        fnMap = mappingFun, DEoptim.control(trace = F),in_data)

我的 in_data 对象(数据框)是:

   Underlying.Price  Delta  Gamma   Theta   Vega    Rho Implied.Volatility
 1            40.69 0.9237 3.2188 -0.7111 2.0493 0.0033             0.3119
 2            40.69 0.7713 6.2267 -1.6352 4.3240 0.0032             0.3402
 3            40.69 0.5822 8.4631 -2.0019 5.5782 0.0338             0.3229
 4            40.69 0.3642 8.5186 -1.8403 5.3661 0.0210             0.3086
 5            40.69 0.1802 6.1968 -1.2366 3.7517 0.0093             0.2966

我想添加一个简单的约束:

 sum(n * delta) = target

换句话说,优化参数 n 的总和乘以我的 in_data 数据帧中的增量总和为某种目标。为简单起见,我们只说 0.5。我该如何施加

 sum(n * delta) = 0.5

作为约束?感谢您的帮助!

DEOptim 包说明说

Implements the differential evolution algorithm for global optimization of a realvalued function of a real-valued parameter vector.

全局优化的概念没有约束的地方,它也被称为无约束优化。很抱歉,但它不可能直接。话虽如此,如果必须这样做,您总是可以使用 "Lagrange's multiplier" hack。为此,您需要执行以下操作:

abs((EPC * gammaSum - 2 * abs(deltaSum))/thetaSum) - lambda* (sum(n * delta) - 0.5)

你在哪里惩罚你的约束松弛。

好的,感谢您的所有建议。我从多个角度研究和解决了我的问题,我想与大家分享我的想法,以防对你们中的一些人有所帮助。

最明显的是,在我的特定 objective 函数中,deltaSum 是一个变量,我试图将其限制为特定值。将这个约束值简单地替换到 objective 函数中就是解决这个问题的方法(微不足道)。但是,假设我要在 objective 函数中还不是变量的变量上引入约束,我可以简单地 运行 一个 for 循环,其中 returns Inf 对于任何约束 I希望强加,即:

obj_func_sum_RRRs <- function(n, in_data) {
#Declare deltaSum, gammaSum, thetaSum, vegaSum, and rhoSum from in_data

#Impose constraints
#No dividing by 0:
        if (thetaSum == 0) {
            return(Inf)
        }

#Specify that regardless of the length of vector of variables to 
#be optimized, we only want our final results to include either 4 or 6
#nonzero n's in our final optimized solution  

        if (!sum(n[1:length(n)] != 0) == 4 &
            !sum(n[1:length(n)] != 0) == 6) {
            return(Inf)
         }

    (deltaSum + gammaSum)/thetaSum
}

第一个 for 循环 (thetaSum == 0, return Inf) 有效,因为虽然 Inf 是优化器理解的解决方案(并且永远不会 select 作为最优),除以 0 in R returns NaN,即"breaks"优化过程。这有点 "hacky",因为它可能不是解决问题的计算效率最高的方法,但老实说,我正在与一位密友和软件架构师专家(利用微服务)开发基础设施通过 Microsoft Service Fabric 部署),我们的远程回测仍然非常快速。这种方法实际上允许您对问题施加任意数量的约束,尽管需要进行进一步测试以了解使用这种技术计算复杂性会变得多么繁重...

上面的拉格朗日技术是可行的,但前提是您在纸上推导出 lambda 的解析形式,然后在代码中实现。它在应用中并不总是实用,虽然您可以编写算法来优化参数,但将自己逼到必须优化参数的角落听起来是个坏主意,而这反过来又是必要的对原始 objective 功能的优化。按照上面的建议设置一个 for 循环似乎是更好的方法。

深思......

我正在使用一个包装器,它根据外部约束自定义 DEoptim 的调用。我承认不是很优雅,但它在某种程度上有效。 我的 objective 函数 - Monte Carlo 模拟 - 非常耗时 所以约束真的很有帮助...... 克里斯

由于我正在做的事情非常特殊(Monte Carlo 优化中子束光学的光线追踪)我没有看到任何添加代码的理由。我认为这里真正重要的是概念。我很乐意与任何感兴趣的人分享我所拥有的。请告诉我....克里斯