Introduction à la Recherche Opérationelle


M1 Statistique Science des Données (SSD)
Anatoli Juditsky
Franck Iutzeler
2017/2018

1. Récupération des données

a. Menu

In [1]:
foods=read.table("data/food.dat", header=T) #  calories, graisses,  vitamines, protéines, ...

n = nrow(foods) # nombre d'aliments

# Printing
foods
n
FoodQuantityCalCalFatFatSatFatCholSodiumCarboProteinVitAVitCCalciumIron
1%_Low_Fat_Milk_Jug 1_carton_(236_ml) 100 20 2 1 10 125 12 8 10 4 30 0
Apple_Slices 1.2_oz_(34_g) 15 0 0 0 0 0 4 0 0 160 2 0
BBQ_Ranch_Burger 4.1_oz_(116_g) 350 140 16 6 45 680 37 16 4 0 20 15
Bacon,_Egg_&_Cheese_Bagel 7_oz_(199_g) 630 290 32 11 275 1490 57 30 20 15 20 20
Bacon,_Egg_&_Cheese_Bagel_with_Egg_Whites 7.2_oz_(203_g) 580 230 26 9 60 1490 55 30 10 15 20 15
Bacon,_Egg_&_Cheese_Biscuit_(Large_Size_Biscuit) 5.8_oz_(164_g) 520 270 30 14 250 1410 43 19 15 8 20 20
Bacon,_Egg_&_Cheese_Biscuit_(Regular_Size_Biscuit) 5.3_oz_(150_g) 460 230 26 13 250 1300 38 19 10 8 15 15
Bacon,_Egg_&_Cheese_Biscuit_with_Egg_Whites_(Large_Biscuit) 5.9_oz_(167_g) 470 220 25 12 35 1420 42 20 6 8 15 15
Bacon,_Egg_&_Cheese_Biscuit_with_Egg_Whites_(RegularBiscuit)5.4_oz_(153_g) 410 180 20 11 35 1300 36 20 2 8 15 10
Bacon,_Egg_&_Cheese_McGriddles 6.1_oz_(174_g) 460 190 21 9 250 1250 48 19 10 10 20 15
Bacon,_Egg_&_Cheese_McGriddles_with_Egg_Whites 6.3_oz_(178_g) 400 140 15 7 35 1250 47 20 2 10 15 10
Bacon_Buffalo_Ranch_McChicken 5.6_oz_(159_g) 420 180 20 4 50 1250 41 20 2 10 15 15
Bacon_Cheddar_McChicken 6_oz_(171_g) 480 220 24 7 65 1260 43 22 4 10 20 15
Bacon_McDouble 5.8_oz_(165_g) 460 210 24 10 85 1120 34 28 6 10 20 20
Baked_Hot_Apple_Pie 2.7_oz_(77_g) 250 110 13 7 0 170 32 2 4 25 2 6
Big_Breakfast_(Large_Size_Biscuit) 10_oz_(283_g) 800 470 52 18 555 1680 56 28 15 2 15 30
Big_Breakfast_(Regular_Size_Biscuit) 9.5_oz_(269_g) 740 430 48 17 555 1560 51 28 15 2 15 25
Big_Breakfast_with_Egg_Whites_(Large_Size_Biscuit) 10.1_oz_(286_g) 690 370 41 14 35 1700 55 26 4 2 10 15
Big_Breakfast_with_Egg_Whites_(Regular_Size_Biscuit) 9.6_oz_(272_g) 640 330 37 14 35 1590 50 26 0 2 10 15
Big_Breakfast_with_Hotcakes_(Large_Size_Biscuit) 15.3_oz_(434_g) 1150 540 60 20 575 2260 116 36 15 2 30 40
Big_Breakfast_with_Hotcakes_(Regular_Size_Biscuit) 14.8_oz_(420_g) 1090 510 56 19 575 2150 111 36 15 2 25 40
Big_Breakfast_with_Hotcakes_and_Egg_Whites_(Large_Biscuit) 15.4_oz_(437_g) 1050 450 50 16 55 2290 115 35 4 2 25 30
Big_Breakfast_with_Hotcakes_and_Egg_Whites_(Regular_Biscuit)14.9_oz_(423_g) 990 410 46 16 55 2170 110 35 0 2 25 30
Big_Mac 7.6_oz_(215_g) 550 260 29 10 75 970 46 25 4 2 25 25
Blueberry_Pomegranate_Smoothie_(Large) 22_fl_oz_cup 340 10 1 0 5 65 79 4 0 4 10 2
Blueberry_Pomegranate_Smoothie_(Medium) 16_fl_oz_cup 260 5 1 0 5 50 62 3 0 4 8 2
Blueberry_Pomegranate_Smoothie_(Small) 12_fl_oz_cup 220 5 0 0 5 40 50 2 0 2 6 2
Buffalo_Ranch_McChicken 5.1_oz_(145_g) 350 130 15 3 35 980 40 14 2 2 15 15
Caramel_Latte_(Large) 20_fl_oz_cup 430 120 14 8 40 180 62 15 15 0 50 2
Caramel_Latte_(Medium) 16_fl_oz_cup 340 90 10 6 30 140 50 11 10 0 35 0
Spicy_Chicken_McBites_Shareable_Size 10_oz_(284_g) 910 500 55 10 120 1990 61 46 15 4 10 10
Spicy_Chicken_McBites_Snack_Size 3_oz_(85_g) 270 150 17 3 35 600 18 14 4 0 2 2
Sprite_(Child) 12_fl_oz_cup 100 0 0 0 0 25 27 0 0 0 0 0
Sprite_(Large) 30_fl_oz_cup 280 0 0 0 0 60 74 0 0 0 0 0
Sprite_(Medium) 21_fl_oz_cup 200 0 0 0 0 45 54 0 0 0 0 0
Sprite_(Small) 16_fl_oz_cup 140 0 0 0 0 30 37 0 0 0 0 0
Steak,_Egg_&_Cheese_Bagel 8.6_oz_(243_g) 680 320 35 13 300 1520 57 33 20 4 25 25
Steak_&_Egg_Biscuit_(Regular_Biscuit) 7.1_oz_(201_g) 540 290 32 16 280 1470 38 25 10 2 20 25
Steak_&_Egg_McMuffin 6.5_oz_(184_g) 420 200 23 9 300 950 31 26 10 2 30 20
Strawberry_Banana_Smoothie_(Large) 22_fl_oz_cup 330 10 1 0 5 80 74 5 0 45 10 4
Strawberry_Banana_Smoothie_(Medium) 16_fl_oz_cup 250 5 1 0 5 60 58 4 0 35 8 4
Strawberry_Banana_Smoothie_(Small) 12_fl_oz_cup 210 5 0 0 5 50 47 3 0 30 8 2
Strawberry_McCafe_Shake_(12_fl_oz_cup)12_fl_oz 550 150 16 10 60 160 90 12 20 0 40 0
Strawberry_McCafe_Shake_(16_fl_oz_cup)16_fl_oz 690 180 20 13 75 210 114 15 25 0 50 0
Strawberry_McCafe_Shake_(22_fl_oz_cup)22_fl_oz 850 210 24 15 90 260 140 18 30 0 70 0
Strawberry_Preserves 0.5_oz_(14_g) 35 0 0 0 0 0 9 0 0 4 0 0
Strawberry_Sundae 6.3_oz_(178_g) 280 60 6 4 25 85 49 6 8 4 20 0
Sugar_Packet 1_pkg_(4.0_g) 15 0 0 0 0 0 4 0 0 0 0 0
Sweet_'N_Sour_Sauce 1_pkg_(28_g) 50 0 0 0 0 150 12 0 2 0 0 0
Sweet_Tea_(Child) 12_fl_oz_cup 110 0 0 0 0 5 27 0 0 0 0 0
Sweet_Tea_(Large) 30_fl_oz_cup 220 0 0 0 0 10 54 1 0 0 0 0
Sweet_Tea_(Medium) 21_fl_oz_cup 180 0 0 0 0 10 45 1 0 0 0 0
Sweet_Tea_(Small) 16_fl_oz_cup 150 0 0 0 0 10 36 1 0 0 0 0
Tangy_Barbeque_Sauce 1_pkg_(28_g) 50 0 0 0 0 260 12 0 2 0 0 0
Tartar_Sauce_Cup 1_oz_(28_g) 140 130 15 2 10 150 0 0 0 0 2 2
Vanilla_McCafe_Shake_(12_fl_oz_cup) 12_fl_oz 530 140 15 10 60 160 86 11 20 0 40 0
Vanilla_McCafe_Shake_(16_fl_oz_cup) 16_fl_oz 660 170 19 12 75 200 109 14 25 0 50 0
Vanilla_McCafe_Shake_(22_fl_oz_cup) 22_fl_oz 820 210 23 15 90 260 135 18 30 0 60 0
Vanilla_Reduced_Fat_Ice_Cream_Cone 3.7_oz_(105_g) 170 40 4 3 15 70 27 5 6 0 15 2
Whipped_Margarine_(1_pat) 1_pkg_(6_g) 40 40 4 1 0 55 0 0 4 0 0 0
305

2. Alimentation idéale

In [2]:
nutr=read.table("data/nutr_ideal.dat", header=T)
nutr
CalCalFatFatSatFatCholSodiumCarboProteinVitAVitCCalciumIron
2500600 65 20 300 2400300 50 100 100 100 100

a. Combinaisons pour une alimentation pauvre en calories

Pour commencer, nous allons essayer de trouver une stratégie $x$ en résolvant un problème diet1 de minimisation des calories, sous contrainte de rester idéal vis à vis des autres nutriments (CalFat, Fat, VitA, etc.)

In [3]:
library(CVXR)
Attaching package: ‘CVXR’

The following object is masked from ‘package:stats’:

    power

Question: Implementer les fonctions et contraintes suivantes, puis résoudre le problème.

  • Fonction objective linéaire à minimiser: $c^\mathrm{T}x$ où $c$ contient les calories par aliment
In [4]:
x <- Variable(n) 

c = foods[3] # calories

diet1 <-  Minimize( t(c) %*% x)
  • Contrainte à vérifier: $x$ est positif (par de quantités négatives d'aliments) et $Ax=b$ où $A$ contient les valeurs des nutriments par aliment et $b$ contient les valeurs idéales
In [5]:
# Constraints matrix
A = t(foods[4:14])
b = t(nutr[2:12])

A
b
CalFat 20 0 140 290 230 270 230 220 180 190 0 0 0 0 130 140 170 210 40 40
Fat 2 0 16 32 26 30 26 25 20 21 0 0 0 0 15 15 19 23 4 4
SatFat 1 0 6 11 9 14 13 12 11 9 0 0 0 0 2 10 12 15 3 1
Chol 10 0 45 275 60 250 250 35 35 250 0 0 0 0 10 60 75 90 15 0
Sodium125 0 680 149014901410130014201300125010 10 10 260 150 160 200 260 70 55
Carbo 12 4 37 57 55 43 38 42 36 4854 45 36 12 0 86 109 135 27 0
Protein 8 0 16 30 30 19 19 20 20 19 1 1 1 0 0 11 14 18 5 0
VitA 10 0 4 20 10 15 10 6 2 10 0 0 0 2 0 20 25 30 6 4
VitC 4 160 0 15 15 8 8 8 8 10 0 0 0 0 0 0 0 0 0 0
Calcium 30 2 20 20 20 20 15 15 15 20 0 0 0 0 2 40 50 60 15 0
Iron 0 0 15 20 15 20 15 15 10 15 0 0 0 0 2 0 0 0 2 0
CalFat 600
Fat 65
SatFat 20
Chol 300
Sodium2400
Carbo 300
Protein 50
VitA 100
VitC 100
Calcium 100
Iron 100
In [6]:
contrainte1 <- x>=0
contrainte2 <- A%*%x - b ==0
  • Resolution par CVXR
In [7]:
problem <- Problem(diet1 , constraints = list(contrainte1, contrainte2))
result <- solve(problem)
In [8]:
result$status
'infeasible'

b. Relaxation des contraintes

Le problème précedent n'avait pas de point faisable avec les contraintes imposées. Afin d'obtenir des points faisable, nous allons remplacer la contrainte $$ Ax = b$$ par les deux contraintes de type boite $$ Ax \geq 0.8 b ~~ \text{ et } ~~ Ax \leq b $$ ainsi les contraintes de nutriments sont satisfaites entre 80 et 100% et le problème devient faisable.

Question: Définir les deux contraintes de boite et resoudre le problème. Vérifier qu'il est faisable.

In [9]:
contrainte2a <- A%*%x <= 1.0*b 
contrainte2b <- A%*%x >= 0.8*b
In [10]:
problem <- Problem(diet1 , constraints = list(contrainte1, contrainte2a,contrainte2b))
result <- solve(problem)
In [11]:
result$status
'optimal'

Question: Affichez les valeur des nutriments pour la solution obtenue et la comparer à 80% et 100% des valeurs prescrites.

In [12]:
cbind(0.8*b,result$getValue(A%*%x),1.0*b)
CalFat 480 480.00000 600
Fat 52 54.08105 65
SatFat 16 20.00000 20
Chol 240 240.00000 300
Sodium1920 2200.662412400
Carbo 240 244.66541 300
Protein 40 50.00000 50
VitA 80 100.00000 100
VitC 80 80.00000 100
Calcium 80 80.00000 100
Iron 80 80.00000 100

Question: Donner le nombre de calories totales et les aliments pour lesquelles la quantité est supérieure à 0.3.

In [13]:
xopt = result$getValue(x)
In [14]:
t(foods[3])%*%xopt
Cal1397.049
In [15]:
for (j in 1:n){
if (xopt[j]>0.3){
print( paste(j,foods[j,1],foods[j,2],": ",xopt[j]))
}
}
[1] "44 Chocolate_Chip_Cookie 1_cookie_(33_g) :  3.69308367977886"
[1] "53 Coffee_(Large) 16_fl_oz_cup :  3.20976009673567"
[1] "54 Coffee_(Medium) 16_fl_oz_cup :  3.20976009673567"
[1] "55 Coffee_(Small) 12_fl_oz_cup :  3.20976009673567"
[1] "59 Dasani_Water 16.9_fl_oz :  3.20976009673567"
[1] "60 Diet_Coke_(Child) 12_fl_oz_cup :  1.58348533696689"
[1] "61 Diet_Coke_(Large) 30_fl_oz_cup :  1.24456182541714"
[1] "62 Diet_Coke_(Medium) 21_fl_oz_cup :  1.46213426584622"
[1] "63 Diet_Coke_(Small) 16_fl_oz_cup :  1.76702208552523"
[1] "74 EQUAL_0_Calorie_Sweetener 1_pkg_(1.0_g) :  30.9360336697206"
[1] "75 Egg_McMuffin 4.8_oz_(135_g) :  0.499223166840716"
[1] "79 Fat_Free_Chocolate_Milk_Jug 1_carton_(236_ml) :  1.24818967029558"
[1] "99 Hamburger 3.5_oz_(100_g) :  1.53428972296434"
[1] "151 Iced_Tea_(Child) 12_fl_oz_cup :  2.12050661174218"
[1] "152 Iced_Tea_(Large) 30_fl_oz_cup :  1.58348533696689"
[1] "153 Iced_Tea_(Medium) 21_fl_oz :  1.76702208552523"
[1] "154 Iced_Tea_(Small) 16_fl_oz_cup :  1.76702208552523"
[1] "249 SPLENDA_No_Calorie_Sweetener 1_pkg_(1.0_g) :  30.9360336697206"
[1] "251 Salt_Packet 1_pkg_(0.7_g) :  0.715052311639653"
[1] "265 Side_Salad 3.1_oz_(87_g) :  1.5472357496715"

On remarque que la solution n'est pas pratique!

c. D'autres contraintes

On va imposer:

  • pas de EQUAL_0_Calorie_Sweetener 1_pkg_(1.0_g) (item $74$) ni de SPLENDA_No_Calorie_Sweetener 1_pkg_(1.0_g) : 30.9360336697206 (item $249$) car c'est pas très bon
  • pas plus de 10 unités dans le menu, pas plus de 2 unités par item
  • au moins un petit déjeuner (items 4 à 23)

Relacher au besoin les contraintes de nutrition...

Question : Implémenter ces contraintes une par une et regarder la valeur optimale de la fonction (le nombre de calories). Cette valeur augmente-t-elle ou diminue-t-elle ? Pourquoi ?

In [16]:
contrainte3a <- x[74] == 0
contrainte3b <- x[249] == 0

contrainte4a <- t(rep(1,n))%*%x <= 10
contrainte4b <- x <= 2.0
In [17]:
dej <- c(rep(0,3),rep(1,20),rep(0,n-23))

contrainte5 <- t(dej)%*%x >=1.0
In [18]:
problem <- Problem(diet1 , constraints = list(contrainte1, contrainte2a,contrainte2b,contrainte3a,contrainte3b,contrainte4a,contrainte4b,contrainte5))
result <- solve(problem)
In [19]:
result$status
'optimal'
In [20]:
xopt = result$getValue(x)
In [21]:
t(foods[3])%*%xopt
Cal1651.642
In [22]:
for (j in 1:n){
if (xopt[j]>0.3){
print( paste(j,foods[j,1],foods[j,2],": ",xopt[j]))
}
}
[1] "15 Baked_Hot_Apple_Pie 2.7_oz_(77_g) :  0.999999999668443"
[1] "44 Chocolate_Chip_Cookie 1_cookie_(33_g) :  1.00438937975382"
[1] "53 Coffee_(Large) 16_fl_oz_cup :  0.369027481671354"
[1] "54 Coffee_(Medium) 16_fl_oz_cup :  0.369027481671354"
[1] "55 Coffee_(Small) 12_fl_oz_cup :  0.369027481671354"
[1] "59 Dasani_Water 16.9_fl_oz :  0.369027481671354"
[1] "75 Egg_McMuffin 4.8_oz_(135_g) :  0.6330076555099"
[1] "79 Fat_Free_Chocolate_Milk_Jug 1_carton_(236_ml) :  0.663488473411496"
[1] "99 Hamburger 3.5_oz_(100_g) :  1.00654879227808"
[1] "122 Hotcakes 5.3_oz_(151_g) :  1.78822174662897"
[1] "265 Side_Salad 3.1_oz_(87_g) :  1.74581677648645"

3. D'autres problèmes

Beaucoup d'autres problèmes de ce genre existent. Ci-dessous vous trouverez un nouveau problème mais vous êtes également invités à inventer vos propres problèmes et chercher si ils sont solvables par CVXR !

Question : Quels sont les aliments à choisir pour obtenir au moins les nutriments recommendés en un minimum d'unités ?

In [23]:
x <- Variable(n) 

un = rep(1,n) 

efficace <-  Minimize( t(un) %*% x)
In [24]:
# Constraints matrix
Aeff = t(foods[3:14])
beff = t(nutr[1:12])

contrainte <- Aeff%*%x >= beff
In [25]:
problemEff <- Problem(efficace , constraints = list(contrainte, x>=0 ))
resultEff <- solve(problemEff)
In [26]:
xeff = resultEff$getValue(x)
In [27]:
for (j in 1:n){
if (xeff[j]>0.1){
print( paste(j,foods[j,1],foods[j,2],": ",xeff[j]))
}
}
[1] "20 Big_Breakfast_with_Hotcakes_(Large_Size_Biscuit) 15.3_oz_(434_g) :  2.27302416718625"
[1] "105 Hi-C_Orange_Lavaburst_(Large) 30_fl_oz_cup :  0.202705070811545"
[1] "175 McFlurry_with_M&M'S_Candies_(16_fl_oz_cup) 16.2_oz_(460_g) :  0.37883736117585"
[1] "242 Premium_Southwest_Salad_with_Grilled_Chicken 11.8_oz_(335_g) :  0.352710646581702"

Question : Quels nutriments sont les plus dur à obtenir (on pourra regarder la valeur de la variable duale) ?

In [28]:
cbind(Aeff%*%xeff,beff)
Cal3131.421202500
CalFat1361.98563 600
Fat 151.70477 65
SatFat 53.74265 20
Chol1360.09144 300
Sodium5464.794252400
Carbo 343.23232 300
Protein 98.92880 50
VitA 100.00000 100
VitC 100.00000 100
Calcium 100.00000 100
Iron 100.00000 100
In [29]:
resultEff$getDualValue(contrainte)
7.141224e-16
8.764722e-16
6.020363e-15
9.417959e-15
3.692402e-16
1.096652e-16
2.910060e-14
6.708524e-15
3.242262e-03
2.439024e-03
1.091714e-02
1.547434e-02

4. Programmation entière avec RMosek

Les solutions obtenues précédemment sont des solutions continues, alors que l'on commande généralement un nombre entier d'items. Les problèmes d'optimisation avec variables entières appellés (Mixed) Integer Programs, se résolvent avec des méthodes et des solveurs différents, comme RMosek.

 a. Installation

Pour l'installation sous Linux:

  • téléchargez et décrompressez Mosek (https://www.mosek.com/) dans votre home
  • demandez une license académique avec votre email universitaire https://license.mosek.com/academic/ et copier le fichier recu dans le répertoire mosek de votre home
  • executez export PATH=$PATH:/home/[USER]/mosek/8/tools/platform/linux64x86/bin où [USER] est votre nom d'utilisateur.
  • Sous R, exécutez install.packages("Rmosek", type="source", repos="http://download.mosek.com/R/8", configure.vars="PKG_MOSEKHOME=/home/[USER]/mosek/8/tools/platform/linux64x86 PKG_MOSEKLIB=mosek64")

b. Retour sur le problème 2b

En RMosek, celui se code de la manière suivante

In [30]:
require(Rmosek)
require(Matrix)
Loading required package: Rmosek
Loading required package: Matrix
In [31]:
dietM = list()
dietM$sense = "min" # we want to minimize ...
dietM$c = as.numeric(unlist(foods[3])) # ... a linear objective: the calories of selected items
In [32]:
# Constraints matrix
A = t(as.matrix(foods[4:14]))
dietM$A = Matrix(A,sparse=TRUE)

# Lower and upper constraints limits
blc = 0.8*as.matrix(nutr[2:12])
buc = 1.0*as.matrix(nutr[2:12])
dietM$bc = rbind(blc, buc);

# Box constraints limits
blx = rep(0,n); bux = rep(Inf,n); 
dietM$bx = rbind(blx, bux);
In [33]:
res = mosek(dietM, list(verbose=0))

res$sol$itr$prosta
xM = res$sol$itr$xx
'PRIMAL_AND_DUAL_FEASIBLE'
In [34]:
for (j in 1:n){
if (xM[j]>0.1){
print( paste(j,foods[j,1],foods[j,2],": ",xM[j]))
}
}
[1] "2 Apple_Slices 1.2_oz_(34_g) :  0.236008829423503"
[1] "44 Chocolate_Chip_Cookie 1_cookie_(33_g) :  3.69309226644752"
[1] "61 Diet_Coke_(Large) 30_fl_oz_cup :  15.7620988922317"
[1] "74 EQUAL_0_Calorie_Sweetener 1_pkg_(1.0_g) :  62.1365500388856"
[1] "75 Egg_McMuffin 4.8_oz_(135_g) :  0.499224588360876"
[1] "79 Fat_Free_Chocolate_Milk_Jug 1_carton_(236_ml) :  1.24818937672678"
[1] "99 Hamburger 3.5_oz_(100_g) :  1.53427764933197"
[1] "260 Sausage_Burrito 3.9_oz_(111_g) :  0.244543125363525"
[1] "265 Side_Salad 3.1_oz_(87_g) :  1.54723638775475"

c. Integer programming

Voici comment ajouter la contrainte d'optimisation en nombres entiers.

In [35]:
dietM$intsub=c(1:n)
In [36]:
res = mosek(dietM, list(verbose=0))

res$sol$int$prosta
xM = res$sol$int$xx
'PRIMAL_INFEASIBLE'

Question : Resoudre le problème de faisabilité puis observer la solution.

In [37]:
# Lower and upper constraints limits
blc = 0.6*as.matrix(nutr[2:12])
buc = 1.0*as.matrix(nutr[2:12])
dietM$bc = rbind(blc, buc);
In [38]:
res = mosek(dietM, list(verbose=0))

res$sol$int$prosta
xM = res$sol$int$xx
'PRIMAL_FEASIBLE'
In [39]:
for (j in 1:n){
if (xM[j]>0.1){
print( paste(j,foods[j,1],foods[j,2],": ",xM[j]))
}
}
[1] "63 Diet_Coke_(Small) 16_fl_oz_cup :  27"
[1] "74 EQUAL_0_Calorie_Sweetener 1_pkg_(1.0_g) :  22"
[1] "79 Fat_Free_Chocolate_Milk_Jug 1_carton_(236_ml) :  1"
[1] "99 Hamburger 3.5_oz_(100_g) :  2"
[1] "120 Hot_Habanero_Sauce 22_oz_(0.8_g) :  1"
[1] "260 Sausage_Burrito 3.9_oz_(111_g) :  1"
[1] "265 Side_Salad 3.1_oz_(87_g) :  1"
[1] "287 Strawberry_Banana_Smoothie_(Small) 12_fl_oz_cup :  1"
In [ ]: