Как создать верхнюю границу для многих переменных с lpsolve в R?

У меня есть набор данных из 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
Переменные:
$ food (fctr) Coca-Cola, томатный сок Sacramento, апельсиновый сок 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.000000, 8.000000, 8.000000, 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 ....
$ 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 ...
$odiumPerServ (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.0 0, 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, ...
$ oilFats (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, ...
$ fruit (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, ...
$ 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 , ...
$ 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 ...
$ 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, ...
$ молочные продукты (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 (число) 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, ...


person eleh915    schedule 09.06.2015    source источник
comment
Не могли бы вы предоставить для этого образцы данных? Было бы полезно опубликовать что-то вроде публикации dput(head(SNAP)) или ссылки на весь файл.   -  person josliber♦    schedule 11.06.2015
comment
конечно, см. отредактированный вопрос выше. включены только первые 3 пищевые переменные (X1, X2, X3), хотя полный файл идет до X135   -  person eleh915    schedule 11.06.2015


Ответы (1)


Что ж, без исходного файла для данных SNAP я придумал свою собственную матрицу питания / питания. Должно быть легко увидеть, как приспособиться к вашей проблеме. Это очень простая задача симплексной линейной оптимизации. Мы определяем каждый продукт питания с точки зрения стоимости, минимальной и максимальной порций на душу населения, а затем пищевой ценности (в настоящее время ограничивается витамином А и калорийностью). С 2 пищевыми компонентами есть 5 столбцов. С 42 питательными компонентами будет 45 столбцов.

Вторая матрица, минимальная и максимальная рекомендуемые суточные нормы (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
}

Приправить по вкусу ...

person Michael Tiemann    schedule 06.08.2015