2011-09-27 92 views
0

我是R和DM/ML的新手,我寫了一個小程序來嘗試優化函數。爲什麼我的程序輸出中gr計數爲0?

我用SANN方法進行優化。我定義了我自己的gr函數,並使用control參數進行了一些配置。

問題是,當我打印輸出時,gr(代表對gr函數的調用次數)的計數是0,而對fn的調用次數是正確的。

這裏是我運行的代碼(我認爲成本函數是irrevelant所以我貼一個簡單的):

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的計數,因爲如果你有一個新呼叫gr,你需要呼叫fn

我的理解是不正確的(如果是的話,他們的關係是什麼)或者我的代碼有問題。

任何人都可以提供幫助嗎?

非常感謝!

更新

由於@Dwin指出,幫助文檔,它說的:「方法‘SANN’......只使用函數值卻相對緩慢。」但是在參數的描述gr它說:「對於‘SANN’的方式,它指定生成新的候選點的函數」

如果你在我grFunction加一些print語句中,可以看到,它實際上得到了所謂的非常深入。

此外,如果SANN方法只使用fn而不使用gr,那麼gr的句子究竟意味着什麼?

+0

我錯過了什麼?我沒有看到任何會增加名爲「gr」的對象的代碼(更不用說將它返回給調用環境。) –

+0

@DWin,gr在優化函數內部被調用以生成成本函數的新候選,所以你看不到它明確增加。與fn一樣。 –

+0

我確實明白'gr'是一個傳遞給optim的函數,現在我看到你正在談論$ counts [c(「function」,「gradient」]。 –

回答

1

調查src/main/optim.c中的代碼表明SANN方法確實調用了梯度函數(當然,您通過打印語句確認了該函數),但它不會更新梯度計數。下面是調用內部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。正如你所指出的,大概梯度(=候選點生成器)函數總是被調用完全相同的次數(確定,在設置階段給出或採取一個或兩個)作爲目標函數...(但是我理解功能沒有按照文檔中的說明操作時會出現混淆!)

+0

感謝Ben,我在做了更多的測試後明白了混淆,我認爲fn和gr的計數對於SANN以外的其他優化方法可能會不同,所以計數器實際上是一個通用計數器,並非專門針對SANN。你說,這可能只是一個無害的錯誤:) –