Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R中预算分配的优化(原名Excel Solver)_R_Optimization_Solver - Fatal编程技术网

R中预算分配的优化(原名Excel Solver)

R中预算分配的优化(原名Excel Solver),r,optimization,solver,R,Optimization,Solver,我将Excel中的一个问题转化为R。我希望以“Gesamt”(由函数返回)最大化的形式分配固定预算 NrwGes <- function(Budget, Speed, maxnrw, cpcrp) { BudgetA <- Budget[1] BudgetB <- Budget[2] BudgetC <- Budget[3] BudgetD <- Budget[4] BudgetE <- Budget[5] M

我将Excel中的一个问题转化为R。我希望以“Gesamt”(由函数返回)最大化的形式分配固定预算

NrwGes <- function(Budget, Speed, maxnrw, cpcrp) {
    BudgetA <- Budget[1]
    BudgetB <- Budget[2]
    BudgetC <- Budget[3]
    BudgetD <- Budget[4]
    BudgetE <- Budget[5]

    MaxNRW <- c(90, 40, 40, 25, 15)
    Speed <- c(0.9, 0.9, 0.9, 0.9, 0.9)
    cpcrp <- c(6564, 4494, 3962, 4525, 4900)

    TV <- BudgetA*1000/cpcrp[1]
    Catchup <- BudgetB*1000/cpcrp[2]
    YT <- BudgetC*1000/cpcrp[3]
    FB <- BudgetD*1000/cpcrp[4]
    Display <- BudgetE*1000/cpcrp[5] 

    a <- TV^Speed[1]/(1+abs((TV)^Speed[1]-1)/(MaxNRW[1]*0.98))
    b <- Catchup^Speed[2]/(1+abs((Catchup)^Speed[2]-1)/(MaxNRW[2]*0.98))
    c <- YT^Speed[3]/(1+abs((YT)^Speed[3] -1)/(MaxNRW[3]*0.98))
    d <- FB^Speed[4]/(1+abs((FB)^Speed[4]-1)/(MaxNRW[4]*0.98))
    e <- Display^Speed[5]/(1+abs((Display)^Speed[5]-1)/(MaxNRW[5]*0.93))

    Gesamt <- a+(100-a)/100*b+((100-a)/100*(100-b)/100*c)+((100-a)/100*(100-b)/100*(100-c)/100*d)+((100-a)/100*(100-b)/100*(100-c)/100*(100-d)/100*e)
    return(Gesamt)
}

暴力强制或网格搜索不是一个选项,因为这将进行15-20次,并且算法将应用于R-Shining应用程序。

尝试使用L-BFGS-U方法(允许边界)和下限0进行优化。然后将输入分量投影到一个向量上,该向量的总和为5000,并将其传递给
NrwGes
fscale=-1
表示最大化而不是最小化。最终分配将是
proj(res$par)
,如底部所示。没有使用任何软件包

proj <- function(x) 5000 * x / sum(x)
st <- proj(rep(1, 5))
f <- function(x) NrwGes(proj(x))
res <- optim(st, f, lower = 0 * st, method = "L-BFGS-B", control = list(fnscale = -1))

projTry
optim
使用L-BFGS-U方法(允许边界)和下限0。然后将输入分量投影到一个向量上,该向量的总和为5000,并将其传递给
NrwGes
fscale=-1
表示最大化而不是最小化。最终分配将是
proj(res$par)
,如底部所示。没有使用任何软件包

proj <- function(x) 5000 * x / sum(x)
st <- proj(rep(1, 5))
f <- function(x) NrwGes(proj(x))
res <- optim(st, f, lower = 0 * st, method = "L-BFGS-B", control = list(fnscale = -1))

proj一个选项是
nloptr
包:

library(nloptr)

# we use NLOPT_LN_COBYLA algorithm because it doesn't need gradient functions
opts <- list(algorithm="NLOPT_LN_COBYLA",
             xtol_rel=1.0e-8,
             maxeval=10000)
# objective function (negative because nloptr always minimize)
objFun <- function(x){ -NrwGes(x) }

# sum of budget <= 5000 (in the form g(x) <= 0)
g <- function(x){ sum(x) - 5000 }


res <- nloptr(x0=rep.int(0,5), # initial solution (all zeros)
              eval_f=objFun, 
              lb=rep.int(0,5), # lowerbounds = 0
              ub=rep.int(5000,5), # upperbounds = 5000
              eval_g_ineq=g,
              opts=opts)

注意:您可以使用
res$solution
res$objective
等访问res的解决方案、目标。

一个选项是
nloptr
包:

library(nloptr)

# we use NLOPT_LN_COBYLA algorithm because it doesn't need gradient functions
opts <- list(algorithm="NLOPT_LN_COBYLA",
             xtol_rel=1.0e-8,
             maxeval=10000)
# objective function (negative because nloptr always minimize)
objFun <- function(x){ -NrwGes(x) }

# sum of budget <= 5000 (in the form g(x) <= 0)
g <- function(x){ sum(x) - 5000 }


res <- nloptr(x0=rep.int(0,5), # initial solution (all zeros)
              eval_f=objFun, 
              lb=rep.int(0,5), # lowerbounds = 0
              ub=rep.int(5000,5), # upperbounds = 5000
              eval_g_ineq=g,
              opts=opts)

注意:您可以使用
res$solution
res$objective
等访问res的解决方案、目标。

问题是什么?问题是什么?传递一个总加起来为5000的投影向量是一个非常酷的技巧。我本想建议运行optim时对目标函数进行惩罚(等于初始总预算和预算最大化之间的绝对差值,时间是一个很大的数字),但你的答案要聪明得多。你只是个天才!!非常感谢你!抱歉,还有一个问题:当我使用结果作为输入(NrwGes(res$par)时,我得到82.53,但$value更大,为86.64,看起来接近我用Excel收到的值。我是否犯了错误?需要使用
NrwGes(proj(res$par))
f(res$par)
proj(res$par)
是分配向量,而不是
res$par
。传递一个总加起来为5000的投影向量是一个非常酷的技巧。我建议运行optim时对目标函数进行惩罚(等于初始总预算和随着时间的推移最大化的预算之间的绝对差值,这是一个很大的数字),但你的答案要聪明得多。你只是个天才!!非常感谢!抱歉,还有一个问题:当我使用结果作为输入时(NrwGes(res$par),我得到82.53,但是$value更大,为86.64,看起来更接近我用Excel得到的值。我是不是犯了错误?需要使用
NrwGes(proj(res$par))
f(res$par)
项目(资源$par)
是分配向量,而不是
res$par
。谢谢你……有趣的是,这种分配比G的解决方案具有更好的结果。Grothdieck@MarkusLnGa。不是这样。两种解决方案都给出了86.64285到小数点后的五位数。谢谢你……有趣的是,这种分配比G的解决方案的结果要好得多。Grothdieck@MarkusLnGa。不是这样。两种解决方案都给出了86.64285到小数点后的五位数。
> res
Call:
nloptr(x0 = rep.int(0, 5), eval_f = objFun, lb = rep.int(0, 5), 
    ub = rep.int(5000, 5), eval_g_ineq = g, opts = opts)


Minimization using NLopt version 2.4.2 

NLopt solver status: 4 ( NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel 
or xtol_abs (above) was reached. )

Number of Iterations....: 261 
Termination conditions:  xtol_rel: 1e-08    maxeval: 10000 
Number of inequality constraints:  1 
Number of equality constraints:    0 
Optimal value of objective function:  -86.6428477187536 
Optimal value of controls: 3037.382 695.3725 675.7232 386.2929 205.2291