2016-09-12 44 views
1

私はこれらの記事を見ていると、他のカップル:上記制約付き最適化R:もう一つの例私はR.で制約付き最適化を実行しようとしています

constrained optimization in R

function constrained optimization in R

最初の投稿はあり非常に便利ですが、私はまだ私の問題に正解を得ていません。

My機能は次のとおりです。

Fd <- 224 * d1 + 84 * d2 + d1 * d2 - 2 * d1^2 - d2^2 

と私の制約がある:3 * d1 + d2 = 280

まず私が制約を網羅的な探索が続く制約のない徹底的な検索を使用して正しい答えを見つける:

my.data <- expand.grid(x1 = seq(0, 200, 1), x2 = seq(0, 200, 1)) 
head(my.data) 
dim(my.data) 

d1  <- my.data[,1] 
d2  <- my.data[,2] 

Fd <- 224 * d1 + 84 * d2 + d1 * d2 - 2 * d1^2 - d2^2 

new.data <- data.frame(Fd = Fd, d1 = d1, d2 = d2) 
head(new.data) 

# identify values of d1 and d2 that maximize Fd without the constraint 
new.data[new.data$Fd == max(new.data$Fd),] 
# **This is the correct answer** 
#   Fd d1 d2 
# 6157 11872 76 80 


# Impose constraint 
new.data <- new.data[(3 * new.data$d1 + new.data$d2) == 280, ] 

# identify values of d1 and d2 that maximize Fd with the constraint 
new.data[new.data$Fd == max(new.data$Fd),] 
# **This is the correct answer** 
#   Fd d1 d2 
# 14743 11774 69 73 

optimを使用して、制約のない最大値を見つけてください。これは機能します。

Fd <- function(betas) { 

     b1 = betas[1] 
     b2 = betas[2] 

     (224 * b1 + 84 * b2 + b1 * b2 - 2 * b1^2 - b2^2) 

    } 

    # unconstrained 
    optim(c(60, 100), Fd, control=list(fnscale=-1), method = "BFGS", hessian = TRUE) 
    # $par 
    # [1] 75.99999 79.99995 

ここで、制限付き最大値はconstrOptimです。これは動作しません。

b1.lower.bound <- c(0, 280) 
b1.upper.bound <- c(93.33333, 0) 
b2.lower.bound <- c(93.33333, 0) 
b2.upper.bound <- c(0, 280) 

theta = c(60,100)       # starting values 
ui = rbind(c(280,0), c(0,93.33333))  # range of allowable values 
theta %*% ui        # obtain ci as -1 * theta %*% ui 
#  [,1]  [,2] 
# [1,] 16800 9333.333 

constrOptim(c(60,100), Fd, NULL, ui = rbind(c(280,0), c(0,93.33333)), ci = c(-16800, -9333.333), control=list(fnscale=-1)) 
# $par 
# [1] 75.99951 80.00798 

私はuiciで遊んで試してみましたが、それは関係なく、私は常に制約のないoptimと同じ答えを得る私は彼らのために使用する値のように思えます。

ありがとうございました。

+1

注意1つの変数で –

+0

ありがとうございます。それはきちんとした考えです。しかし、完全性のために、私は制約付き最適化を使用してそれを解決する方法を学びたいと考えています。 –

答えて

1

constrOptim()線形不等式制約を使用しui %*% param - ci >= 0により実行可能領域を画定します。制約が3 * d1 + d2 <= 280の場合、uic(-3, -1)であり、ci-280です。 constrOptim();

constrOptim(); 不平等制約がある: 3 * D1 + D2 = 280 <
Fd <- function(betas) { 
    b1 = betas[1] 
    b2 = betas[2] 
    (224 * b1 + 84 * b2 + b1 * b2 - 2 * b1^2 - b2^2) 
} 

theta = c(59.999,100) # because of needing " ui %*% inital_par - ci > 0 " 
ui = c(-3, -1) 
ci = -280    # those ui & ci mean " -3*par[1] + -1*par[2] + 280 >= 0 " 

constrOptim(theta, Fd, NULL, ui = ui, ci = ci, control=list(fnscale=-1)) 
    # $par 
    # [1] 69.00002 72.99993 


[編集]

あなたは不平等が、等式制約でない場合、Rsolnpかを使用する方が良いだろうalabamaパッケージ。それらは、不等式および/または等価性制約(Constrained Optimization library for equality and inequality constraintsを参照)を使用できます。

solnp(); auglag(); 平等制約がある。この場合には、あなたがD1のための制約(またはD2)と目的関数の中に拘束されない問題への問題を軽減することを代わりに解決できることを 3 * D1 + D2 = 280
library(Rsolnp); library(alabama); 

Fd2 <- function(betas) {  # -1 * Fd 
    b1 = betas[1] 
    b2 = betas[2] 
    -1 * (224 * b1 + 84 * b2 + b1 * b2 - 2 * b1^2 - b2^2) 
} 

eqFd <- function(betas) { # the equality constraint 
    b1 = betas[1] 
    b2 = betas[2] 
    (3 * b1 + b2 -280) 
} 

solnp(pars = c(60, 100), fun = Fd2, eqfun = eqFd, eqB = 0) 
auglag(par = c(60, 100), fn = Fd2, heq = eqFd) 
+0

制約上の勾配の(-3、-1)が負であるかどうか:3 * b1 + b2 = 280? –

+1

'constrOptim()'は線形の不等式制約を使います。この場合、私は '3 * b1 + b2 <= 280'を制約し、' -3 * b1 - b2 + 280> = 0'と等価です(これはあなたの質問に答えますか?) – cuttlefish44

+0

そうだと思います。どうもありがとうございました。これは非常に役に立ちます。 –

1

ここで私はG. Grothendieckの提案を実装しており、正解を返すようです。理想的には、制約付き最適化を使用して正しい答えを得る方法を学びたいと思います。ここでは、変数が1つしかないので、ブレントメソッドを使用しました。私はoptimステートメントで上限と下限を指定しなければならなかったことに注意してください。

# Find maxima using optim and substitution. First remove b2 
# 
# 3 * b1 + b2 = 280 
# 
# b2 = (280 - 3 * b1) 

Fd <- function(betas) { 

    b1 = betas[1] 

    (224 * b1 + 84 * (280 - 3 * b1) + b1 * (280 - 3 * b1) - 2 * b1^2 - (280 - 3 * b1)^2) 

} 

optim(c(60), Fd, method = "Brent", lower = 0, upper = 93.33333, control=list(fnscale=-1)) 
# $par 
# [1] 69 

# Now remove b1 
# 
# 3 * b1 + b2 = 280 
# 
# b1 = ((280 - b2)/3) 

Fd <- function(betas) { 

    b2 = betas[1] 

    (224 * ((280 - b2)/3) + 84 * b2 + ((280 - b2)/3) * b2 - 2 * ((280 - b2)/3)^2 - b2^2) 

} 

optim(c(100), Fd, method = "Brent", lower = 0, upper = 280, control=list(fnscale=-1)) 
# $par 
# [1] 73 
+1

これは二次的なので、解析は解析的に解くことに注意してください。 –

関連する問題