0
obj1<-function(monthly.savings,
               success,
               start.capital,
               target.savings,
               monthly.mean.return,
               monthly.ret.std.dev,
               monthly.inflation,
               monthly.inf.std.dev,
               n.obs,
               n.sim=1000){

  req = matrix(start.capital, n.obs+1, n.sim) #matrix for storing target weight

  monthly.invest.returns = matrix(0, n.obs, n.sim)
  monthly.inflation.returns = matrix(0, n.obs, n.sim)

  monthly.invest.returns[] = rnorm(n.obs * n.sim, mean = monthly.mean.return, sd = monthly.ret.std.dev)
  monthly.inflation.returns[] = rnorm(n.obs * n.sim, mean = monthly.inflation, sd = monthly.inf.std.dev)

  #for loop to be 
  for (a in 1:n.obs){
    req[a + 1, ] = req[a, ] * (1 + monthly.invest.returns[a,] - monthly.inflation.returns[a,]) + monthly.savings
  }

  ending.values=req[nrow(req),]
  suc<-sum(ending.values>target.savings)/n.sim
  value<-success-suc

  return(abs(value))
}

最小化したい上記の目的関数があります。特定の成功確率に必要な毎月の節約を解決しようとします。次の入力仮定が与えられた場合

success<-0.9
start.capital<-1000000
target.savings<-1749665
monthly.savings=10000
monthly.mean.return<-(5/100)/12
monthly.ret.std.dev<-(3/100)/sqrt(12)
monthly.inflation<-(5/100)/12
monthly.inf.std.dev<-(1.5/100)/sqrt(12)
monthly.withdrawals<-10000
n.obs<-10*12  #years * 12 months in a year
n.sim=1000

次の表記法を使用しました。

optimize(f=obj1,
        success=success,
        start.capital=start.capital,
        target.savings=target.savings,
        monthly.mean.return=monthly.mean.return,
        monthly.ret.std.dev=monthly.ret.std.dev,
        monthly.inflation=monthly.inflation,
        monthly.inf.std.dev=monthly.inf.std.dev,
        n.obs = n.obs,
        n.sim = n.sim,
        lower = 0,
        upper = 10000,
        tol = 0.000000001,maximum=F)

私は7875.03を取得します

私は正規分布からサンプリングしているので、出力は毎回異なりますが、ほぼ同じギブまたは数%ポイントになるはずです。私が抱えている問題は、上限を任意に指定できないことです。上記の例の上限 (10000) は、何度も試行錯誤を繰り返した結果です。上限を 100000 に設定したとします (不合理だと思います) と言うと、グローバルな最小節約を見つけるのとは対照的に、その数値が返されます。目的関数を間違って構成しているアイデアはありますか?

ありがとう、

4

1 に答える 1

4

関数が特定の入力に対して常に同じ出力を返すとは限らないという事実は、いくつかの問題を引き起こす可能性があります (多くの誤った極小値が作成されます)。関数 (たとえばset.seed(1)randtoolbox::sobol

これは 1 つの変数の関数であるため、単純にプロットして何が起こるかを確認できます。10,000 を超えるとプラトーになります。最適化アルゴリズムは、プラトーと局所最適を区別できません。

f <- function(x) {
  set.seed(1)
  obj1(x,
      success             = success,
      start.capital       = start.capital,
      target.savings      = target.savings,
      monthly.mean.return = monthly.mean.return,
      monthly.ret.std.dev = monthly.ret.std.dev,
      monthly.inflation   = monthly.inflation,
      monthly.inf.std.dev = monthly.inf.std.dev,
      n.obs               = n.obs,
      n.sim               = n.sim 
  )
}
g <- Vectorize(f)
curve(g(x), xlim=c(0, 20000))

あなたの最初の問題は、実際には最小化の問題ではなく、根を見つける問題であり、はるかに簡単です。

obj2 <- function(monthly.savings) {
  set.seed(1)
  req = matrix(start.capital, n.obs+1, n.sim)
  monthly.invest.returns <- matrix(0, n.obs, n.sim)
  monthly.inflation.returns <- matrix(0, n.obs, n.sim)
  monthly.invest.returns[] <- rnorm(n.obs * n.sim, mean = monthly.mean.return, sd = monthly.ret.std.dev)
  monthly.inflation.returns[] <- rnorm(n.obs * n.sim, mean = monthly.inflation, sd = monthly.inf.std.dev)
  for (a in 1:n.obs)
    req[a + 1, ] <- req[a, ] * (1 + monthly.invest.returns[a,] - monthly.inflation.returns[a,]) + monthly.savings
  ending.values <- req[nrow(req),]
  suc <- sum(ending.values>target.savings)/n.sim
  success - suc
}
uniroot( obj2, c(0, 1e6) )
# [1] 7891.187
于 2013-06-26T22:21:07.693 に答える