R 中的优化:最大化和最小化许多变量

ele*_*915 3 r mathematical-optimization minimize maximize ggplot2

我有一个包含 70 种食物的数据集,以及有关每种食物的营养价值(蛋白质/盎司、脂肪/盎司、卡路里/盎司等)以及食物/盎司的成本的信息。我试图弄清楚——给定美元预算——食物的最佳组合(以及每种食物的含量)将是最大限度地提高蛋白质、最大限度地减少脂肪、最大限度地减少卡路里等。我的目标是做到这一点跨越一系列价格点,并绘制每个价格点。

我在这里找到了一大堆不同的软件包可以帮助解决这个问题: http: //cran.r-project.org/web/views/Optimization.html。然而,我是一个初学者,不确定什么最有帮助/从哪里开始 - 希望熟悉解决此类优化问题的任何人提供一些建议。

jos*_*ber 5

这称为饮食问题,它是线性规划的流行介绍(例如,参见我发现的有关饮食问题的第一个 Google 搜索结果)。线性规划求解器通过诸如此类的包lpSolve可用于解决饮食问题的许多变体。

例如,考虑上面链接中的问题版本,其中有以下食物可供选择:

(food <- data.frame(Food=c("Corn", "2% Milk", "Wheat Bread"), CostPerServing=c(.18, .23, .05), VitaminA=c(107, 500, 0), Calories=c(72, 121, 65)))
#          Food CostPerServing VitaminA Calories
# 1        Corn           0.18      107       72
# 2     2% Milk           0.23      500      121
# 3 Wheat Bread           0.05        0       65
Run Code Online (Sandbox Code Playgroud)

假设您想要找到使总成本最小化的每种食物的份数,但总热量必须在 2000 到 2500 之间,维生素 A 的含量必须在 5000 到 50000 之间。如果您定义了变量 X1 、X2 和 X2,那么您的目标是 0.18*X1 + 0.23*X2 + 0.05*X3,变量的线性函数。同样,变量的线性函数中的每个约束;例如,卡路里数量的下限是 72*X1 + 121*X2 + 65*X3 >= 2000 形式的约束。

lp包中的函数将lpSolve指示目标值中的系数的向量以及有关约束的信息(约束矩阵、每个约束的方向以及每个约束的右侧)作为输入。对于所述问题,这将是:

library(lpSolve)
mod <- lp("min",  # min/max
          food$CostPerServing,  # Objective
          rbind(food$VitaminA, food$VitaminA, food$Calories, food$Calories),  # Constraint matrix
          c(">=", "<=", ">=", "<="),  # Constraint directions
          c(5000, 50000, 2000, 2500))
Run Code Online (Sandbox Code Playgroud)

模型求解后,您可以查看目标函数和值:

mod$objval
# [1] 2.907692
mod$solution
# [1]  0.00000 10.00000 12.15385
sum(food$VitaminA * mod$solution)
# [1] 5000
sum(food$Calories * mod$solution)
# [1] 2000
Run Code Online (Sandbox Code Playgroud)

满足限制的最便宜成本为 2.91 美元,您可以通过使用 0 份玉米、10 份 2% 牛奶和 12.15 份小麦面包来实现这一目标。这样可以产生 5000 单位的维生素 A 和 2000 卡路里的热量。