如何调试模拟的退火代码?

时间:2019-05-16 09:57:45

标签: r

我的问题陈述说:

  

编写一个函数以对输入函数执行模拟退火,在下面的函数规范中我们描述了输入。它应该输出niter + 1行的历史记录(记录x0,并记录下一个x_k是否移动)以及最终向量。

我所做的是:

 SA <- function(func,x0,S,M, niter) {

  # f0 -- function of x to be minimized
  # x0 -- initial guess for x
  # s  -- vector of standard deviations giving step sizes
  #       to take, should be of the same dimension as x. 
  # M  -- Cooling temperature schedule constant. 
  # niter - number of steps to take
  x_b <- x_c <- x_n <- x0
  f_b <- f_c <- f_n <- func(x_n)
  message("It\tBest\tCurrent\tNeigh\tTemp")
  message(sprintf("%i\t%.4f\t%.4f\t%.4f\t%.4f", 0L, f_b, f_c, f_n, 1))

  for (k in 1:niter) {     
    M <- (1 - S)^k
    # consider a random neighbor
    x_n <- rnorm(2, x_c, 1)
    f_n <- func(x_n)
    # update current state
    if (f_n < f_c || runif(1, 0, 1) < exp(-(f_n - f_c) / M)) {
      x_c <- x_n
      f_c <- f_n
    }
    # update best state
    if (f_n < f_b) {
      x_b <- x_n
      f_b <- f_n         
    }
    message(sprintf("4f\niter%.4f\f_b%", f_b, niter))
  }
  return(list(Sol = f_b, iterhist = niter))
}

现在这应该适用于以下情况:

testfunc = function(x){ return( -cos( x[1] + x[2] + x[3] ) + sum(abs(x)) ) }

set.seed(1)
    all.equal(SA(testfunc,rep(0.5,3),c(0.3,0.5,1),0.8,1)$sol,c(0.3120639,0.5918217,-0.3356286),tol=1e-7)

set.seed(2)
all( SA(testfunc,rep(0.5,3),c(0.3,0.5,1),0.8,1)$sol == 0.5 )

set.seed(2)
all.equal( SA(testfunc,rep(0.5,3),c(0.3,0.5,1),0.08,1)$sol,c(0.2309256 ,0.5924246 ,2.0878453),tol=1e-7)

Bu给出错误:

 Error in if (f_n < f_c || runif(1, 0, 1) < exp(-(f_n - f_c)/M)) { : 
  missing value where TRUE/FALSE needed

代码有什么问题?

1 个答案:

答案 0 :(得分:0)

您的问题是

testfunc = function(x){ return( -cos( x[1] + x[2] + x[3] ) + sum(abs(x)) ) }
NA_real_不(至少)没有三个元素时,

将返回x,并且在SA()中您可以看到这些行

x_n <- rnorm(2, x_c, 1)
f_n <- func(x_n)

x_n创建为长度为2的向量,并将其提供给func()

请考虑以下内容:

set.seed(1)
testfunc = function(x){ return( -cos( x[1] + x[2] + x[3] ) + sum(abs(x)) ) }
x_c <- rep(0.5,3)
x_n <- rnorm(2, x_c, 1)
x_n
# [1] -0.1264538  0.6836433
testfunc(x_n)
# [1] NA
sum(abs(x_n))
# [1] 0.8100971
-cos( x_n[1] + x_n[2] + x_n[3] )
# [1] NA
-cos(sum(x_n))
# [1] -0.8487447