0

我有一个包含 135 种食物的数据集,用于解决饮食问题:最小化成本和最大化营养价值。我想创建一个包含多种食物的模型,而不是告诉我每周只吃 80 份土豆和 50 份菠菜的模型。我想:

1) 设置食物份数的上限(即每种食物最多 10 份),而不改变我对其他变量(例如食物组)的上限和下限

2)能够在我的模型中指定我想要的食物(/变量)的最小数量

现在,我正在写出模型中的所有变量,以及指定纤维、卡路里、盎司的最小值和最大值。水果,盎司 蔬菜等:

minCost <- lp("min", SNAP$costPerServ,
           rbind(SNAP$protPerServ, SNAP$protPerServ, SNAP$fatPerServ,
 SNAP$fatPerServ, SNAP$costPerServ, SNAP$costPerServ, SNAP$sodiumPerServ,
 SNAP$sodiumPerServ, SNAP$fiberPerServ, SNAP$fiberPerServ, SNAP$sugarPerServ,
 SNAP$sugarPerServ, SNAP$calsPerServ, SNAP$calsPerServ, SNAP$fruit,     SNAP$vegs,
 SNAP$grains, SNAP$grains, SNAP$meatProtein, SNAP$dairy, SNAP$X1, SNAP$X2,
 SNAP$X3, SNAP$X4, SNAP$X5, SNAP$X6, SNAP$X7, SNAP$X8, SNAP$X9, ... [more foods
 here] ..., SNAP$X135),
           c(">=", "<=", ">=", "<=", ">=", "<=", ">=", "<=", ">=", "<=", ">=",
 "<=", ">=", "<=", ">=", ">=", ">=", "<=", ">=", ">=",
 "<=", "<=", "<=", "<=", "<=", "<=", "<=", "<=", "<=",
 "<=", ...[more "<="s here]..., "<="),
           c(input$prot[1]*7, input$prot[2]*7, input$fat[1]*7, input$fat[2]*7,
 input$budget[1], input$budget[2], input$sodium[1]*7, input$sodium[2]*7,
 input$fiber[1]*7, input$fiber[2]*7, input$sugar[1]*7, input$sugar[2]*7,
 input$cals[1]*7, input$cals[2]*7, 16, 28, 9, 25, 6.4, 24, input$serv,
 input$serv, input$serv, input$serv, input$serv, input$serv, input$serv,
 input$serv, input$serv, input$serv, ...[more input$servs here]...,
 input$serv))

我为此使用了闪亮的包,所以这就是为什么它是“input$serv”而不是一个具体的数字。用户可以使用滑块小部件选择最大份数,默认值为 10。

模型所基于的食物营养信息位于单独的 csv 文件中。

一瞥(SNAP)
观察:135个
变量:
$食品(fctr)可口可乐,萨克拉门托番茄汁,Tropicana Trop50橙汁,V8 Veg ...
$ foodGroup(fctr)饮料,饮料,饮料,饮料,乳制品,乳制品,乳制品, 乳制品, 乳制品...
$ calsPerServ (dbl) 140.0, 35.0, 50.0, 50.0, 90.0, 90.0, 102.4, 150.0, 90.0, 90.0, 113.0, 50.0...
$ ozPerServ (dbl) 12.000000, 6.0000008.00000000000000 , 2.500000, 4.070000, 8.000000, 8.0... $ fatPerServ ( dbl
) 0.00, 0.00, 0.00, 0.00, 5.00, 1.00, 0.24, 8.00, 0.00, 0.00, 9.00, 3.00, 7...
0.0, 1.0, 1.0, 2.0, 8.0, 16.0, 7.2, 8.0, 6.0, 3.0, 7.0, 4.0, 2.0, 2.0, 6.0...
$ sodiumPerServ (dbl) 45.00, 560.00, 10.00, 590.00, 80.00, 360.00, 120.80, 120.00, 100.00, 60.00...
$ fiberPerServ (dbl) 0.0, 1.0, 0.0, 2.0, 0.0, 0.0, 0,0,0, 0.0, 0.0, 0.0 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,...
$sugarPerServ (dbl) 39.00, 4.90, 10.00, 8.00, 0.00, 3.00, 11.20, 11.00, 12.00, 14.00, 0.00, 1....
$ costPerServ ( dbl) 0.4800000, 0.2400000, 0.5600000, 0.4737500, 0.1750000, 0.4884000, 0.240000...
$ 谷物 (dbl) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
$ oilsFats (dbl) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
$ 水果 (dbl) 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000 , 0.00000, 0.00000, 0....
$ 糖 (dbl) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0,...
$ 肉蛋白质 (dbl) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0,...
$ bev (int) 12, 6, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
$ 蔬菜 (dbl) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
$ 乳制品 (dbl) 0.000000, 0.000000, 0.000000, 0.000000, 2.500000, 4.070000, 8.000000, 8.00...
$ X1 (int) 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0,...
$ X2 (int) 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0,...
$ X3 (int) 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0,...

4

1 回答 1

0

好吧,没有 SNAP 数据的源文件,我想出了自己的食物/营养矩阵。应该很容易看出如何适应您的问题。这是一个非常基本的单纯形线性优化问题。我们根据成本、人均最小和最大份量以及营养含量(目前仅限于维生素 A 和千卡)来定义每种食品。有 2 种营养成分有 5 列。有 42 种营养成分,就有 45 列。

第二个矩阵 min 和 max Recommended Daily Allowances (RDA),每个最小/最大 RDA 都有一行。

这是四种食物的 R 代码,玉米、牛奶、面包和大豆:

library(lpSolveAPI)

# Diet options (index, cost, min servings, max servings, vitA, calories)
food.corn <- c(0.18, 0, 10, 107, 72)
food.milk <- c(0.23, 0, 10, 500, 121)
food.bread <- c(0.05, 0, 10, 0, 65)
food.soylent <- c(0.50, 0, 10, 625, 250)

foods <- matrix(c(food.corn, food.milk, food.bread, food.soylent), 4, 5, byrow=TRUE)

# Recommended Daily Allowance (min, max)
rda.vitA <- c(5000, 50000)
rda.cal <- c(2000, 2250)

rdas <- matrix(c(rda.vitA, rda.cal), 2, 2, byrow=TRUE)

nr <- length(foods[,1])
varcount <- nr
const.count <- 0
lp <- make.lp (0, varcount, verbose="normal")
lp.control (lp, sense="min")
set.objfn (lp, foods[,1])

for (i in length(rdas[,1])) {
    add.constraint (lp, foods[,(3+i)], ">=", as.double(rdas[i,1]))
    add.constraint (lp, foods[,(3+i)], "<=", as.double(rdas[i,2]))
    const.count <- const.count + 1
}

for (i in nr) {
    add.constraint (lp, c(rep(0,i-1), 1, rep(0,nr-i)), ">=", as.double(foods[i,2]))
    add.constraint (lp, c(rep(0,i-1), 1, rep(0,nr-i)), "<=", as.double(foods[i,3]))
    const.count <- const.count + 1
}

set.bounds (lp, lower=foods[,2], upper=foods[,3])
set.type (lp, 1:varcount, type="integer")
resize.lp (lp, const.count, varcount)

if (solve (lp) == 0) {
    lps.out <- list(solution=get.variables(lp), objective=get.objective(lp))
} else {
    print ("No feasible solution")
    lps.out <- NA
}

调味...

于 2015-08-06T10:52:09.977 回答