R 中的 Excel 求解器是否有替代方案?

Is there any alternative for Excel solver in R?

我们有下面的代码来解决一个优化问题,我们希望通过对利润应用约束来最大化销售额。项目。 我们希望将此利润阈值应用为仅由 200 个项目产生的收入的百分比。 我们通过使用 GRGE 非线性算法在 Excel 求解器中使用变化变量应用利润公式来完成此操作。我们想要 R 的类似替代方案。 有没有办法在 R 中分配变化的变量?

数据集

item sales profit
A 1200 120
B 5600 45
C 450  00
D 990 -90
E 1000 80
F 560  120
G 500  23
H 2000 350

代码

library(lpSolveAPI)
dataset<-read.csv("Dataset.csv",header=T,na.strings='NA',stringsAsFactors =F)
dataset$keep_flag <-1 

**all the func in LPsolve API**
ls("package:lpSolveAPI")
summary(dataset)

**Passing the parameters**
ncol <- nrow(dataset) 

**you have eight rows that can be picked or dropped from the solution set**
lp_rowpicker <- make.lp(ncol=ncol)
set.type(lp_rowpicker, columns=1:ncol, type = c("binary"))

**checking the model**
lp_rowpicker

**setting objective**
obj_vals <- dataset$Revenue_1hr.Projected
#obj_vals<- dataset[, 2]
obj_vals
set.objfn(lp_rowpicker, obj_vals) 
lp.control(lp_rowpicker,sense='max')

**Adding contraints**

Profit constraint
xt<- (dataset$Profit_1hr.Projected)
add.constraint(lp_rowpicker, xt, ">=", 100)
xt

#No.of items to be kept
xt<- (dataset$keep_flag)
add.constraint(lp_rowpicker, xt, "=", 4)
xt

#model check
lp_rowpicker

#solving equation
solve(lp_rowpicker)

#Maximised revenue
get.objective(lp_rowpicker)

#The one with binary as 1 is our item
dataset$keep_flag<- get.variables(lp_rowpicker)
dataset$keep_flag <- as.data.frame(dataset$keep_flag)
sum(dataset$keep_flag)



final_set <- cbind(dataset,final_flag)
final_set <- final_set[which(final_set$final_flag==1),]

final_set$keep_flag <- NULL
final_set$final_flag<- NULL

此代码段将利润阈值应用于总数。的项目,而不是将其应用于选定的项目。

编辑

这是我 运行 @Karsten W. 代码时创建的模型:

           C1    C2    C3    C4    C5    C6    C7    C8         
Maximize  1200  5600   450   990  1000   560   500  2000         
R1         120    45     0   -90    80   120    23   350  >=  100
R2           1     1     1     1     1     1     1     1   =    4
Kind       Std   Std   Std   Std   Std   Std   Std   Std         
Type       Int   Int   Int   Int   Int   Int   Int   Int         
Upper        1     1     1     1     1     1     1     1         
Lower        0     0     0     0     0     0     0     0

得到的输出是:

    item sales profit
1      A  1200    120
1.1    A  1200    120
1.2    A  1200    120
1.3    A  1200    120

同一件商品被退回四次。我想要 4 个独特的物品。另外,我想应用利润约束作为这 4 个项目产生的销售额的百分比。 顺便说一下,我们保留 'keep_flag' 是为了实现与您的 'nitems' 类似的功能。它是一个变化的变量,采用二进制值。

我会看一些然后选择最好的

LPSolve https://cran.r-project.org/web/packages/lpSolve/lpSolve.pdf, 这是一个简单的线性求解器。它与 LPSolve Api 非常相似,但我发现它更容易。

明卡 https://cran.r-project.org/web/packages/minqa/minqa.pdf 这是一个主要用于非线性问题的二次求解器

古罗比http://www.gurobi.com/products/modeling-languages/r 这是 IBM CPLEX 求解器的开源实现。很好很能干。

你的代码对我来说似乎没问题,除了变量名不适合你提供的数据集。特别是我不清楚 keep_flag 代表什么,是某种预选吗?

您代码中的利润约束仅适用于求解器所选变量中的四个。

这是您的代码,稍微整理了一下。

library(lpSolveAPI)

dataset <- data.frame(item=LETTERS[1:8], sales=c(1200, 5600, 450, 990, 1000, 560, 500, 2000), profit=c(120, 45, 0, -90, 80, 120, 23, 350))
nitems <- nrow(dataset)

# make lp   
lprec <- make.lp(0, ncol=nitems)
set.type(lprec, columns=seq.int(nitems), type="binary")

# set objective
lp.control(lprec, sense="max", bb.rule="gap", timeout=30)
set.objfn(lprec, obj=dataset[, "sales"]) 

# constraints
min_rel_profit <- 0.10 # min. 10% profit
add.constraint(lprec, dataset[, "profit"]-min_rel_profit*dataset[,"sales"], ">=", 0) # required profit
add.constraint(lprec, rep(1, nitems), "=", 4)  # four products

print(lprec)
solve(lprec)
dataset[get.variables(lprec)==1,]

利润约束推导如下(p为利润向量,s为销售额向量,x为决策变量0/1,所有lengthnitems,minp为最小相对利润):

  • sum(profit) / sum(sales) >= minprofit 转换为 p'x/s'x >= minp
  • 这相当于(p - minp s)'x >= 0

因此最低利润必须作为 LHS 系数的一部分出现。

如果遇到求解时间长的问题,可以微调参数。有关详细信息,请参阅 ?lp.control.options。使用 timeout 设置测试时的时间限制。对于此类问题 (MIP),bb.rule 参数很有帮助。根据您的示例数据,在不到一秒的时间内找到了 9.5% 的解决方案。