【问题标题】:R: How to add additional constraints to DEoptimR:如何向 DEoptim 添加额外的约束
【发布时间】:2019-07-10 04:25:17
【问题描述】:

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

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

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

【问题讨论】:

    标签: r optimization differential-evolution


    【解决方案1】:

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

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

    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 是优化器理解的解决方案(并且永远不会选择为最优),但在 R 中除以 0 返回 NaN,这会“破坏”优化过程。这有点“hacky”,因为它可能不是解决问题的最有效的计算方法,但老实说,我正在与一位密友和软件架构师大师一起开发的基础设施(它利用通过部署的微服务Microsoft Service Fabric),我们的长期回测仍然在快速减轻。这种方法实际上允许您对问题施加任意数量的约束,尽管需要进行进一步的测试以了解使用这种技术计算复杂性可能变得多么繁重......

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

    深思……

    【讨论】:

    • 仅供参考,我已经实现了这个,实际上我得到了 Inf 作为优化的解决方案,所以 thetaSum == 1, return Inf, 不像我想象的那样工作。回到我的绘图板上....
    【解决方案2】:

    DEOptim 包描述说

    实现全局的差分进化算法 实值参数的实值函数的优化 向量。

    全局优化的概念没有约束的地方,它也被称为无约束优化。很抱歉,但它不可能直接。话虽如此,如果必须这样做,您始终可以使用“拉格朗日乘数”技巧。为此,您需要执行以下操作:

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

    你惩罚你的约束松弛的地方。

    【讨论】:

    • 谢谢,这很有意义。您对我可以采取哪些方法来解决 R 中这种特殊的约束优化有其他建议吗?
    • 另外,我将如何以编程方式使用您的 Legrange 乘数版本?换句话说,在这种情况下,lambda 只是 Legrange 乘数(达到目的的手段),但对于 R,它只是另一个未定义的变量。如何让 R 继续最小化,求解 lambda,然后将其替换回最终优化解决方案?换句话说,我可以在纸上做拉格朗日乘数,我如何让 R 在这个优化问题的上下文中做呢?
    • 第一个问题你可以看看stackoverflow.com/questions/38404309/…Lambda参数需要通过反复试验来选择,这就是为什么我称之为hack而不是解决方案。
    • 我做优化和 R 两者..R 与 Gurobi 两全其美......但 Gurobi 不是开源求解器..
    【解决方案3】:

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

    由于我正在做的事情的特殊性(用于优化中子束光学的蒙特卡洛射线追踪),我没有看到任何添加代码的理由。我认为这里真正重要的是概念。我很乐意与任何感兴趣的人分享我所拥有的。让我知道.... 克里斯

    【讨论】:

    • 虽然这可能是解决问题的宝贵提示,但一个好的答案也可以证明解决方案。请edit 提供示例代码来说明您的意思。或者,考虑将其写为评论。
    猜你喜欢
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多