測試數據:
x <- c(2,2,2,1,1,1,1)
rowVals <- c(6,4,3,4)
colVals <- c(3,4,4,6)
函數來構造從(3N-5)參數的相應的測試矩陣:
makeMat <- function(x,n) {
## first and last element of diag are constrained by row/col sums
diagVals <- c(colVals[1],x[1:(n-2)],rowVals[n])
## set up off-diagonals 2,3
sup2Vals <- x[(n-1):(2*n-3)]
sup3Vals <- x[(2*n-2):(3*n-5)]
## set up matrix
m <- diag(diagVals)
m[row(m)==col(m)-1] <- sup2Vals
m[row(m)==col(m)-2] <- sup3Vals
m
}
目標函數(行的平方&柱偏差的總和):
objFun <- function(x,n) {
m <- makeMat(x,n)
## compute SSQ deviation from row/col constraints
sum((rowVals-rowSums(m))^2+(colVals-colSums(m))^2)
}
優化:
opt1 <- optim(fn=objFun,par=x,n=4)
## recovers original values, although it takes a lot of steps
opt2 <- optim(fn=objFun,par=rep(0,length(x)),n=4)
makeMat(opt2$par,n=4)
## [,1] [,2] [,3] [,4]
## [1,] 3 2.658991 0.3410682 0.0000000
## [2,] 0 1.341934 1.1546649 1.5038747
## [3,] 0 0.000000 2.5042858 0.4963472
## [4,] 0 0.000000 0.0000000 4.0000000
##
## conjugate gradients might be better
opt3 <- optim(fn=objFun,par=rep(0,length(x)),n=4,
method="CG")
似乎有這個問題,這 並不奇怪(因爲有上(N-2)+(N-1)+(N-2)= 3N 2N約束多個解-5個參數)。
你沒有說是否需要整數解或不 - 如果 所以你需要更專業的工具...
+1,現在加分,這樣做在VBA :) –
謝謝幫助,我不需要整數,只有非負值。似乎L-BFGS-B方法很好地滿足了這一點。 – ignorantcity