R 中的优化:最大化和最小化多个变量
Optimization in R: Maximizing and Minimizing Many Variables
我有一个数据集,其中包含 70 种食物和有关每种食物的营养价值的信息(protein/oz.、fat/oz.、cals/oz. 等),以及食物的营养价值cost/oz。我想弄清楚——给定一个以美元为单位的固定预算——最好的食物组合(以及每种食物的量)是什么来最大化蛋白质、最小化脂肪、最小化卡路里等。我的目标是这样做跨一系列价格点,并绘制每个价格点。
我在这里找到了一大堆不同的包可以帮助解决这个问题:http://cran.r-project.org/web/views/Optimization.html。但是,我是一名初学者,不确定最 helpful/where 应该从什么开始 - 希望熟悉解决此类优化问题的任何人提供一些建议。
这称为饮食问题,它是对线性规划的流行介绍(例如,参见 the first Google hit I found for the diet problem)。通过 lpSolve
等包的线性规划求解器可用于解决饮食问题的许多变体。
例如,考虑上面 link 中的问题版本,您有以下食物可供选择:
(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
假设您想找到使总成本最小化的每种食物的份数,但前提是总卡路里必须在 2000 到 2500 之间,维生素 A 的量必须在 5000 到 50000 之间。如果您定义了变量 X1、X2 和 X2,那么您的 objective 是 .18*X1 + .23*X2 + .05*X3,即变量的线性函数。同样,您的每个约束都在变量的线性函数中;例如,卡路里数量的下限是 72*X1 + 121*X2 + 65*X3 >= 2000.
形式的约束
lpSolve
包中的 lp
函数将指示 objective 值中的系数的向量作为输入,以及有关约束的信息(约束矩阵,每个向量的方向约束,以及每个约束的右侧)。对于所述问题,这将是:
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))
模型求解后,可以查看objective函数和值:
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
满足约束条件的最低成本是 2.91 美元,您可以通过使用 0 份玉米、10 份 2% 牛奶和 12.15 份小麦面包来实现。这会产生恰好 5000 单位的维生素 A 和恰好 2000 卡路里。
我有一个数据集,其中包含 70 种食物和有关每种食物的营养价值的信息(protein/oz.、fat/oz.、cals/oz. 等),以及食物的营养价值cost/oz。我想弄清楚——给定一个以美元为单位的固定预算——最好的食物组合(以及每种食物的量)是什么来最大化蛋白质、最小化脂肪、最小化卡路里等。我的目标是这样做跨一系列价格点,并绘制每个价格点。
我在这里找到了一大堆不同的包可以帮助解决这个问题:http://cran.r-project.org/web/views/Optimization.html。但是,我是一名初学者,不确定最 helpful/where 应该从什么开始 - 希望熟悉解决此类优化问题的任何人提供一些建议。
这称为饮食问题,它是对线性规划的流行介绍(例如,参见 the first Google hit I found for the diet problem)。通过 lpSolve
等包的线性规划求解器可用于解决饮食问题的许多变体。
例如,考虑上面 link 中的问题版本,您有以下食物可供选择:
(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
假设您想找到使总成本最小化的每种食物的份数,但前提是总卡路里必须在 2000 到 2500 之间,维生素 A 的量必须在 5000 到 50000 之间。如果您定义了变量 X1、X2 和 X2,那么您的 objective 是 .18*X1 + .23*X2 + .05*X3,即变量的线性函数。同样,您的每个约束都在变量的线性函数中;例如,卡路里数量的下限是 72*X1 + 121*X2 + 65*X3 >= 2000.
形式的约束lpSolve
包中的 lp
函数将指示 objective 值中的系数的向量作为输入,以及有关约束的信息(约束矩阵,每个向量的方向约束,以及每个约束的右侧)。对于所述问题,这将是:
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))
模型求解后,可以查看objective函数和值:
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
满足约束条件的最低成本是 2.91 美元,您可以通过使用 0 份玉米、10 份 2% 牛奶和 12.15 份小麦面包来实现。这会产生恰好 5000 单位的维生素 A 和恰好 2000 卡路里。