ボックス制約は、以下のように目的関数自体にペナルティ制約として設定できます。
の値は、目的関数と制約の間の相対的重要性を決定します。 lambda
の値が高いほど、ソルバーは目的関数よりも制約を優先します。
ここでは、c(4,3)
library("DEoptim")
#run DEoptim and set a seed first for replicability
#note the results are sensitive to seed values and parameters (lambda,NP,itermax,F,CR)
set.seed(1234)
#create a vector/grid of lambda values
lambdaVec = sapply(0:12,function(x) 10^x)
lambdaVec
#[1] 1e+00 1e+01 1e+02 1e+03 1e+04 1e+05 1e+06 1e+07 1e+08 1e+09 1e+10
#For each value of lambda compute the output of optimization function and combine the results
optimSummary = do.call(rbind,lapply(lambdaVec, function(lambdaParam) {
fnCustom = function(x,lambda=lambdaParam) {
x1 <- x[1]
x2 <- x[2]
#integer param constraints
firstIntPenalty <- (x1-round(x1))^2
secondIntPenalty <- (x2-round(x2))^2
# x2 < x1, note the sign is opposite of desired constraint
inEqualityConstraint <- sum(x2>x1)
100 * (x1^2 + x2^2 - 25)^2 + lambda * (firstIntPenalty + secondIntPenalty + inEqualityConstraint)
}
lower <- c(0,0)
upper <- c(5,5)
#you will have to tinker with values of NP,F and CR and monitor convergence, see ?DEoptim last paragraph
outDEoptim <- DEoptim(fnCustom, lower, upper, DEoptim.control(NP = 80, itermax = 1000, F = 1.2, CR = 0.7,trace=TRUE))
#output data.frame of optimization result
optimRes <- data.frame(lambda = lambdaParam ,param1 = outDEoptim$optim$bestmem[1],param2 = outDEoptim$optim$bestmem[2])
rownames(optimRes) <- NULL
return(optimRes)
}))
浮動小数点表現の予想出力と制約、 としてX2 < X1とX1^2 +×2^2 = 25の整数解のための単純な方程式解く:
を
浮動小数点表現のため、ほとんどの場合、結果は期待される整数出力と正確に等しくはありません。 あなたのドメインに応じて、それ以下で許容されるしきい値を定義しなければなりません。ソルバは、より多くの重量を割り当てソルバ制約を無視ラムダの低いレベルおよび増加ラムダと
threshold = 1e-6
expectedOut = c(4,3)
#optimization summary
optimSummary
# lambda param1 param2
#1 1e+00 4.999996 0.0002930537
#2 1e+01 4.000000 3.0000000000
#3 1e+02 4.000000 3.0000000000
#4 1e+03 4.000000 3.0000000000
#5 1e+04 4.000000 3.0000000000
#6 1e+05 4.000000 3.0000000000
#7 1e+06 4.000000 3.0000000000
#8 1e+07 4.000000 3.0000000000
#9 1e+08 4.000000 2.9999999962
#10 1e+09 3.999999 2.9999998843
#11 1e+10 4.000000 2.9999999569
#12 1e+11 4.000000 3.0000000140
#13 1e+12 4.000000 3.0000000194
#Verify output
#1)With constraintBreach1 and constraintBreach2 we check if difference between output and expected result
#has breached threshold
#2)With constraintBreach3 we check if x1 > x2 condition is violated
#3)Columns with TRUE observations indicate breach of respective constraints at particular lambda values
verifyDF = data.frame(lambdaVec,constraintBreach1 = abs(optimSummary$param1-expectedOut[1]) > threshold
, constraintBreach2 = abs(optimSummary$param2-expectedOut[2]) > threshold
, constraintBreach3 = optimSummary$param1 < optimSummary$param1)
verifyDF
# lambdaVec constraintBreach1 constraintBreach2 constraintBreach3
#1 1e+00 TRUE TRUE FALSE
#2 1e+01 FALSE FALSE FALSE
#3 1e+02 FALSE FALSE FALSE
#4 1e+03 FALSE FALSE FALSE
#5 1e+04 FALSE FALSE FALSE
#6 1e+05 FALSE FALSE FALSE
#7 1e+06 FALSE FALSE FALSE
#8 1e+07 FALSE FALSE FALSE
#9 1e+08 FALSE FALSE FALSE
#10 1e+09 FALSE FALSE FALSE
#11 1e+10 FALSE FALSE FALSE
#12 1e+11 FALSE FALSE FALSE
#13 1e+12 FALSE FALSE FALSE
:詳細について
は?.Machine
と このR floating point precision
出力収束及び検証を参照します〜 の制約を満たすことができ、したがって制約が満たされる。
特定の問題については、lambda,NP,itermax,F,CR
の値を変更する必要があります。
これは完全に機能しました。 – Patty