我有一个包含135种食物的数据集,用于解决diet problem:最小化成本和最大化营养价值。我想创建一个包含各种食物的模型,而不是一个例如告诉我每周只吃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))
我使用了闪亮的包,所以这就是为什么它是“输入$ serv”而不是具体的数字。用户可以选择使用滑块小部件的最大服务数,默认值为10.
该模型所依据的食物营养信息位于单独的csv文件中。
一瞥(SNAP)
观察:135
变量:
$ food(fctr)可口可乐,萨克拉门托番茄汁,Tropicana Trop50橙汁,V8蔬菜...... $ 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.00000000,8000000,8000000,2.000000,4.0000000,8000000,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,3.00 ...... $ protPerServ(dbl)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,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 ...
$ grains(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,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,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,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,0,0,0 ,0,0,...
$ fruit(dbl)0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0.00000,0 .... $ sugar(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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,...
$ meatProtein(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,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,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 ...
$ vegs(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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,...
$ dairy(dbl)0.000000,0.000000,0.000000,0.000000,2.5000,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,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,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,...
$ 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 :(得分:0)
好吧,如果没有SNAP数据的源文件,我想出了自己的食物/营养矩阵。应该很容易看出如何适应您的问题。这是一个非常基本的单纯形线性优化问题。我们根据成本,人均最低和最高份量,然后营养成分(目前仅限于维生素A和kCals)来定义每个食品。有2个营养成分,有5列。有42个营养成分,将有45列。
第二个矩阵,最小和最大推荐每日允许量(RDA),每个最小/最大RDA都有一行。
这里有四种食物的R代码,玉米,牛奶,面包和soylent:
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
}
品尝季节......