繁体   English   中英

R中的非线性离散优化

[英]Nonlinear discrete optimization in R

我有一个简单的(确实是经济学标准)非线性约束离散最大化问题,在R中解决并且遇到了麻烦。 我找到了部分问题的解决方案(非线性最大化;离散最大化),但没有找到所有问题的联合。

这是问题所在。 消费者想要购买三种产品(凤梨,香蕉,饼干),知道价格并且预算为20欧元。 他喜欢多样性(即,如果可能的话,他希望拥有所有三种产品)并且他的满意度在消耗量上减少(他喜欢他的第一个饼干方式超过他的第100个)。

他希望最大化的功能是

功能最大化

当然,由于每个人都有一个价格,并且他的预算有限,他在这个约束条件下最大化了这个功能

在此输入图像描述

我想要做的是找到满足约束条件的最佳购买清单(N ananas,M香蕉,K饼干)。

如果问题是线性的,我会简单地使用linprog :: solveLP()。 但目标函数是非线性的。 如果问题具有连续性,那么它将是一个简单的分析解决方案。

问题是离散和非线性的,我不知道如何继续。

这是一些玩具数据。

df <- data.frame(rbind(c("ananas",2.17),c("banana",0.75),c("cookie",1.34)))
names(df) <- c("product","price")

我想要一个优化程序,给我一个(N,M,K)的最佳购买清单。

任何提示?

如果您不介意使用“手动”解决方案:

uf=function(x)prod(x)^.5
bf=function(x,pr){
  if(!is.null(dim(x)))apply(x,1,bf,pr) else x%*%pr
}
budget=20
df <- data.frame(product=c("ananas","banana","cookie"),
                 price=c(2.17,0.75,1.34),stringsAsFactors = F)
an=0:(budget/df$price[1]) #include 0 for all possibilities
bn=0:(budget/df$price[2])
co=0:(budget/df$price[3])
X=expand.grid(an,bn,co)
colnames(X)=df$product
EX=apply(X,1,bf,pr=df$price)
psX=X[which(EX<=budget),] #1st restrict
psX=psX[apply(psX,1,function(z)sum(z==0))==0,] #2nd restrict
Ux=apply(psX,1,uf)
cbind(psX,Ux)
(sol=psX[which.max(Ux),])
uf(sol) # utility
bf(sol,df$price)  #budget
 > (sol=psX[which.max(Ux),]) ananas banana cookie 1444 3 9 5 > uf(sol) # utility [1] 11.61895 > bf(sol,df$price) #budget 1444 19.96 

1)没有包这可以通过蛮力来完成。 使用问题中的df作为输入确保price是数字(它是问题的df中的一个因子)并计算每个变量的最大数量mx 然后创建可变计数的网格g并计算每个的total价格以及给出gg的相关objective 现在按照目标的降序对gg进行排序,并使这些解决方案满足约束条件。 head将展示前几个解决方案。

price <- as.numeric(as.character(df$price))
mx <- ceiling(20/price)
g <- expand.grid(ana = 0:mx[1], ban = 0:mx[2], cook = 0:mx[3]) 
gg <- transform(g, total = as.matrix(g) %*% price, objective = sqrt(ana * ban * cook))
best <- subset(gg[order(-gg$objective), ], total <= 20)

赠送:

> head(best) # 1st row is best soln, 2nd row is next best, etc.
     ana ban cook total objective
1643   3   9    5 19.96  11.61895
1929   3   7    6 19.80  11.22497
1346   3  10    4 19.37  10.95445
1611   4   6    5 19.88  10.95445
1632   3   8    5 19.21  10.95445
1961   2  10    6 19.88  10.95445

2)dplyr这也可以使用dplyr包很好地表达。 使用上面的gprice

library(dplyr)
g %>% 
  mutate(total = c(as.matrix(g) %*% price), objective = sqrt(ana * ban * cook)) %>%
  filter(total <= 20) %>%
  arrange(desc(objective)) %>%
  top_n(6)

赠送:

Selecting by objective
  ana ban cook total objective
1   3   9    5 19.96  11.61895
2   3   7    6 19.80  11.22497
3   3  10    4 19.37  10.95445
4   4   6    5 19.88  10.95445
5   3   8    5 19.21  10.95445
6   2  10    6 19.88  10.95445

我认为这个问题在本质上与这个问题非常相似( 在R中求解不确定方程系统 )。 Richie Cotton的答案是这种可能解决方案的基础:

df <- data.frame(product=c("ananas","banana","cookie"),
                 price=c(2.17,0.75,1.34),stringsAsFactors = F)

FUN <- function(w, price=df$price){
  total <- sum(price * w) 
  errs <- c((total-20)^2, -(sqrt(w[1]) * sqrt(w[2]) * sqrt(w[3])))
  sum(errs)
}

init_w <- rep(10,3)
res <- optim(init_w, FUN, lower=rep(0,3), method="L-BFGS-B")
res
res$par # 3.140093 9.085182 5.085095
sum(res$par*df$price) # 20.44192

请注意,解决方案的总成本(即价格)为20.44美元。 为了解决这个问题,我们可以对误差项进行加权,以便更加强调第一项,即与总成本相关:

### weighting of error terms
FUN2 <- function(w, price=df$price){
  total <- sum(price * w) 
  errs <- c(100*(total-20)^2, -(sqrt(w[1]) * sqrt(w[2]) * sqrt(w[3]))) # 1st term weighted by 100
  sum(errs)
}

init_w <- rep(10,3)
res <- optim(init_w, FUN2, lower=rep(0,3), method="L-BFGS-B")
res
res$par # 3.072868 8.890832 4.976212
sum(res$par*df$price) # 20.00437

正如LyzandeR所说,R中没有非线性整数规划求解器。相反,您可以使用R包rneos将数据发送到NEOS求解器之一并将结果返回到R过程。

NEOS Solvers页面上选择“Mixed Integer Nonlinearly Constrained Optimization”的解算器之一 ,例如Bonmin或Couenne。 对于上面的示例,请将AMPL建模语言中的以下文件发送给以下解算器之一:

[请注意,最大化乘积x1 * x2 * x3与最大化乘积sqrt(x1) * sort(x2) * sqrt(x3)

型号文件:

param p{i in 1..3};
var x{i in 1..3} integer >= 1;
maximize profit: x[1] * x[2] * x[3];
subject to restr: sum{i in 1..3} p[i] * x[i] <= 20;

数据文件:

param p:= 1 2.17  2 0.75  3 1.34 ;

命令文件:

solve;
display x;

您将收到以下解决方案:

x [*] :=
1  3
2  9
3  5
;

这种方法适用于更多扩展示例,“手动”解决方案不合理,而且舍入optim解决方案不正确。

为了看一个更苛刻的例子,让我提出以下问题:

求整数向量x =(x_i),i = 1,...,10,最大化x1 * ... * x10,使得p1 * x1 + ... + p10 * x10 <= 10,其中p = (p_i),i = 1,...,10,是以下价格向量

p <- c(0.85, 0.22, 0.65, 0.73, 0.91, 0.11, 0.31, 0.47, 0.93, 0.71)

使用constrOptim来解决这个带有线性不等式约束的非线性优化问题,我得到了900不同起点的解,但从来没有960的最优解!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM