我是R和DM / ML的新手,我写了一个小程序来试用optim函数。
我用SANN方法使用了optim。我定义了自己的gr
函数,并使用control
参数进行了一些配置。
问题在于,当我打印输出时,gr
的计数(表示对gr函数的调用次数)为0,而对fn的调用次数是正确的。
这是我的可运行代码(我认为成本函数是无效的,所以我发布了一个简单的代码):
people = list('Seymour'='BOS',
'Franny'='DAL',
'Zooey'='CAK',
'Walt'='MIA',
'Buddy'='ORD',
'Les'='OMA')
schedulecost <- function(schedule){
return(sum(schedule))
}
annealingOptimize <- function(domains, step=1, T=10000,costf=schedulecost){
solution <- sample(1:9, 2 * length(people), replace=T)
grFunction <- function(sol){
index <- sample(c(1:length(domains$Up)), 1, replace=T)
delta <- as.integer(runif(1,min=-step-1,max=step+1))
newValue <- sol[index] + delta
if (newValue > domains$Up[index]){
newValue <- domains$Up[index]
}
if (newValue < domains$Down[index]){
newValue <- domains$Down[index]
}
sol[index] <- newValue
return(sol)
}
values <- optim(solution,costf,gr=grFunction, method='SANN',
control=list(temp=T, REPORT=1, maxit=200, tmax=10))
print(values)
return(values$par)
}
domains <- list(Down=rep(1,length(people) * 2), Up=rep(9, length(people) * 2))
schedule <-annealingOptimize(domains)
输出是:
$par
[1] 2 2 6 2 3 5 5 1 9 1 1 7
$value
[1] 44
$counts
function gradient
200 NA
$convergence
[1] 0
$message
NULL
根据我的理解,gr
的计数应该等于fn
的计数,因为如果您通过调用{{{{}}有新候选人,则需要调用fn
1}}。
我的理解是否不正确(如果是,他们的关系是什么)或我的代码有问题。
任何人都可以提供帮助吗?
非常感谢!
更新:
正如@Dwin指出的那样,在帮助文档中它说:“方法”SANN“......仅使用函数值,但相对较慢。”但在参数gr
的描述中,它说:“对于“SANN”方法,它指定了一个生成新候选点的函数。“
如果你在我的gr
中添加一些print语句,你会发现它实际上被非常密集地调用了。
此外,如果SANN方法只使用grFunction
并且不使用gr,那么fn
的句子究竟是什么意思?
答案 0 :(得分:1)
研究src/main/optim.c
中的代码表明SANN方法确实调用了渐变函数(当然你通过print语句确认了它),但它并不打算更新渐变计数。这是对内部SANN函数samin
的调用:
samin (npar, dpar, &val, fminfn, maxit, tmax, temp, trace, (void *)OS);
for (i = 0; i < npar; i++)
REAL(par)[i] = dpar[i] * (OS->parscale[i]);
fncount = npar > 0 ? maxit : 1;
grcount = NA_INTEGER;
我可以确认samin
调用genptry
调用渐变函数。
这让我觉得它是一个bug(可以报告给R开发列表,或者是R bug跟踪器),但这是一个无害的bug。正如你所指出的那样,大概是梯度(=候选点生成器)函数总是被称为完全相同的次数(好的,在设置阶段给出或取一两个)作为目标函数...(但我理解当函数没有按照文档中的说法进行操作时的混淆!)