R中有Excel解算器的替代方法吗?

时间:2016-08-17 11:49:50

标签: r optimization mathematical-optimization linear-programming

我们有以下代码来解决优化问题,我们希望通过对利润和不应用约束来最大化销售。的项目。 我们希望将此利润阈值应用为仅由200个项目生成的收入的百分比。 我们通过使用GRGE非线性算法在Excel Solver中使用变化变量应用利润公式来完成它。我们想要一个类似的替代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'正在做的类似的功能。它是一个采用二进制值的变化变量。

2 个答案:

答案 0 :(得分:2)

您的代码似乎没问题,但变量名称不适合您提供的数据集。特别是我不清楚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,所有长度{ {1}},nitems是最低相对利润):

  • 总和(利润)/总和(销售额)&gt; = minprofit转换为minp
  • 这相当于p'x/s'x >= minp

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

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

答案 1 :(得分:1)

我会看几个并选择最好的

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

Minqa https://cran.r-project.org/web/packages/minqa/minqa.pdf 这是一个四边形解算器,主要用于非线性问题

Gurobi http://www.gurobi.com/products/modeling-languages/r 这是IBM的CPLEX解算器的开源实现。非常好,能干。