我目前正在尝试使用模拟退火包GenSA以最小化以下功能:
efficientFunction <- function(v) {
t(v) %*% Cov_Mat %*% v
}
其中Cov_Mat是从4个资产获得的协方差矩阵,v是维度4的权重向量。
我试图以这种方式解决Markowitz资产分配方法,我想知道如何引入数学约束,例如所有系数的总和必须等于1:
sum(v) = 1
此外,由于我打算依赖GenSA功能,我想使用约束这样的东西:
v <- c(0.25, 0.25, 0.25, 0.25)
dimension <- 4
lower <- rep(0, dimension)
upper <- rep(1, dimension)
out <- GenSA(v, lower = lower, upper = upper, fn = efficientFunction)
我在本文中发现:http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.97.6091&rep=rep1&type=pdf 如何在模拟退火算法中处理这种约束,但我不知道如何在R中实现它。
我非常感谢任何建议。这是我第一次使用SO,所以不要犹豫告诉我,问我的问题方法是否错误。
答案 0 :(得分:4)
一种可能的方法是利用所谓的拉格朗日乘数(参见http://en.wikipedia.org/wiki/Lagrange_multiplier)。例如,设置
efficientFunction <- function(v) {
lambda <- 100
t(v) %*% Cov_Mat %*% v + lambda * abs( sum(v) - 1 )
}
,以便最小化目标函数efficientFunction
,结果参数也最小化惩罚项lambda * abs( sum(v) - 1 )
。拉格朗日乘数lambda
设置为任意但足够高的水平。
答案 1 :(得分:1)
因此,函数本身似乎没有任何可以设置的约束。但是,您可以重新参数化函数以强制约束。 <怎么样
efficientFunction <- function(v) {
v <- v/sum(v)
t(v) %*% Cov_Mat %*% v
}
这里我们规范化v
的值,使它们总和为1.然后,当我们得到输出参数时,我们需要执行相同的转换
out <- GenSA(v, lower = lower, upper = upper, fn = efficientFunction)
out$par/sum(out$par)
答案 2 :(得分:0)
我花了一些时间试图找到答案。我甚至想向GenSA开发人员写一个问题,为什么他们还没有实现约束处理。但后来我意识到这没有必要。
如果您有等式约束。这是作者的案例。使用该等式通过所有其他变量输出(解释)一个变量。然后在您尝试最小化的函数中替换它。之后,函数看起来更复杂,但是等式约束消失了。此外,搜索空间的大小也减小了。
对所有其他相等约束做同样的事情。如果你有比变量更多的等式约束,那就意味着问题没有解决方案。
如果您有不平等约束。在目标函数中,只需添加类似
的内容if (conctraints not fulfilled)
{result <- 999999;}
else
{result <- [evaluate function]}
return (result)
据我所知,没有实际需要打扰选择动态参数,正如优化文章中所建议的那样。