【问题标题】:Optimization in R: Maximizing and Minimizing Many VariablesR 中的优化:最大化和最小化许多变量
【发布时间】:2015-05-29 20:46:42
【问题描述】:

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

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

【问题讨论】:

  • 您需要一个目标函数来描述达到某个目标的“好”程度。例如,如果您想控制成本 ($)、卡路里 (kCal) 和蛋白质 (g),您可以使用 f(cost,cals,prot) = cost^2 + (1000-protein)^ 这样的函数2/3 + (14,000 - 卡路里)^2/4 这个函数的作用是试图让你接近 1,000 克蛋白质和 14,000 卡路里,同时减少食物成本。目标是最小化这个函数。
  • 由于您对 SO 很陌生,您可能想阅读有关 how to ask a good question 以及如何生成 minimal reproducible example 的信息。这将使其他人更容易帮助您。

标签: r ggplot2 mathematical-optimization minimize maximize


【解决方案1】:

这被称为饮食问题,它是线性规划的流行介绍(参见,例如,the first Google hit I found for the diet problem)。通过 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

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

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

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))

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

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 卡路里。

【讨论】:

  • 有没有办法为 mod$solution 指定最小变量数?在您的示例中,您需要牛奶和小麦面包来满足最便宜的成本,而不是玉米。如果我想要全部 3 种(或者,使用更大的数据集、至少 10 种食物、20 种、100 种等)来扩大规模怎么办?
猜你喜欢
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 2016-09-15
  • 2018-08-10
  • 2021-06-18
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
相关资源
最近更新 更多