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% 的解决方案。
我们有下面的代码来解决一个优化问题,我们希望通过对利润应用约束来最大化销售额。项目。 我们希望将此利润阈值应用为仅由 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% 的解决方案。