我们有以下代码来解决优化问题,我们希望通过对利润和不应用约束来最大化销售。的项目。 我们希望将此利润阈值应用为仅由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'正在做的类似的功能。它是一个采用二进制值的变化变量。
答案 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
是最低相对利润):
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解算器的开源实现。非常好,能干。