R用于解决线性规划营销问题

R for solving linear programming marketing problem

我有这个问题,我知道答案,但我需要能够通过 R

解决它

有 5 个广告系列,分别称为 A、B、C、D、E,每个广告系列都有可能花费的最大预算,每个广告系列花费的每一美元都有一个投资回报率。

看起来像这样

Campaign   Max Budget    ROI
  A         156.09       0.77
  B         73.92        1.46
  C         65.8         2.14
  D         43.68        0.77
  E         41.01        1.81

有两个限制,你只能在所有活动中花费总共 100,并且你不能在每个活动上花费超过你的最大预算,你正在努力最大化你的利润,那就是你的投资回报率时间您在广告系列上花费的预算。

我知道答案是在活动 C 上花费 65.8,因为它具有更高的投资回报率,然后在活动 E 上花费 34.2,因为你有第二高的投资回报率,并且你将达到最大支出 100 的限制。

如果有人可以帮助我使用 lpSolveAPI 或 lpsolve 进行设置,在此先感谢

这是我目前尝试过的方法

 library("lpSolveAPI")

 model<-make.lp(ncol=5)
 m1<-lp.control(model, sense="max", verbose="neutral")

 m2<-set.objfn(model, obj=c(120.1893,107.9232,140.812,33.6336,74.2462))

 m3<-set.bounds(model, upper =c(156.09,73.92,65.8,43.68,41.02))

 m4<-add.constraint(model, c(1,1,1,1,1), "<=",100)

 solve(model)


 get.variables(model)
 34.2  0.0 65.8  0.0  0.0

为什么我在 C 上得到 65.8 而在 A 上得到 34.2,它应该在 E 上吗?我假设我的 objective 函数不正确,对于 objective 函数,我将 ROI 乘以最大预算并使用这些系数。

我认为在这里使用整个方程式求解模型有点矫枉过正,因为广告系列之间没有什么可以平衡的。

如果我没理解错的话,你想把尽可能多的钱花在投资回报率最高的广告系列上,第二高的还剩下什么,然后剩下的......等等。直到所有的钱都花完了花了。

我的方法是根据 ROI 进行排序,并计算累计总和以了解您得到的结果。如果您的数据位于 data.frame 中,名为 df:

df <- df[order(df$ROI, decreasing=TRUE), ]
df$spend <- pmin(df$MaxBudget,
                 pmax(TotalMoney-cumsum(c(0, df$MaxBudget[-nrow(df)]),
                      0)

并行化,您可以在每个活动上花费尽可能多的钱,或者在所有 "more worthwhile" 个活动筹到资金后剩余的金额,以较少者为准。并且 "what is left" 被定义为什么都没有,或者 TotalMoney 减去所有较高活动的总和。

在下面的注释中使用 dat 试试这个:

library(lpSolveAPI)

n <- nrow(dat)
model <- make.lp(0, n)
control <- lp.control(model, sense = "max")

set.objfn(model, dat$ROI)

set.bounds(model, upper = dat$Max_Budget)
add.constraint(model, rep(1, n), "<=", 100)

solve(model)
## [1] 0

get.variables(model)
## [1]  0.0  0.0 65.8  0.0 34.2

备注

可重现形式的输入:

Lines <- "
Campaign   Max_Budget    ROI
  A         156.09       0.77
  B         73.92        1.46
  C         65.8         2.14
  D         43.68        0.77
  E         41.01        1.81"
dat <- read.table(text = Lines, header = TRUE)