Diet Examples#
This section includes source code for all of the Gurobi diet examples.
The same source code can be found in the examples
directory of the
Gurobi distribution.
diet#
/* Copyright 2024, Gurobi Optimization, LLC */
/* Solve the classic diet model, showing how to add constraints
to an existing model. */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "gurobi_c.h"
int printSolution(GRBmodel* model, int nCategories, int nFoods);
int
main(int argc,
char *argv[])
{
GRBenv *env = NULL;
GRBmodel *model = NULL;
int error = 0;
int i, j;
int *cbeg, *cind, idx;
double *cval, *rhs;
char *sense;
/* Nutrition guidelines, based on
USDA Dietary Guidelines for Americans, 2005
http://www.health.gov/DietaryGuidelines/dga2005/ */
const int nCategories = 4;
char *Categories[] =
{ "calories", "protein", "fat", "sodium" };
double minNutrition[] = { 1800, 91, 0, 0 };
double maxNutrition[] = { 2200, GRB_INFINITY, 65, 1779 };
/* Set of foods */
const int nFoods = 9;
char* Foods[] =
{ "hamburger", "chicken", "hot dog", "fries",
"macaroni", "pizza", "salad", "milk", "ice cream" };
double cost[] =
{ 2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89, 1.59 };
/* Nutrition values for the foods */
double nutritionValues[][4] = {
{ 410, 24, 26, 730 },
{ 420, 32, 10, 1190 },
{ 560, 20, 32, 1800 },
{ 380, 4, 19, 270 },
{ 320, 12, 10, 930 },
{ 320, 15, 12, 820 },
{ 320, 31, 12, 1230 },
{ 100, 8, 2.5, 125 },
{ 330, 8, 10, 180 }
};
/* Create environment */
error = GRBloadenv(&env, "diet.log");
if (error) goto QUIT;
/* Create initial model */
error = GRBnewmodel(env, &model, "diet", nFoods + nCategories,
NULL, NULL, NULL, NULL, NULL);
if (error) goto QUIT;
/* Initialize decision variables for the foods to buy */
for (j = 0; j < nFoods; ++j)
{
error = GRBsetdblattrelement(model, "Obj", j, cost[j]);
if (error) goto QUIT;
error = GRBsetstrattrelement(model, "VarName", j, Foods[j]);
if (error) goto QUIT;
}
/* Initialize decision variables for the nutrition information,
which we limit via bounds */
for (j = 0; j < nCategories; ++j)
{
error = GRBsetdblattrelement(model, "LB", j + nFoods, minNutrition[j]);
if (error) goto QUIT;
error = GRBsetdblattrelement(model, "UB", j + nFoods, maxNutrition[j]);
if (error) goto QUIT;
error = GRBsetstrattrelement(model, "VarName", j + nFoods, Categories[j]);
if (error) goto QUIT;
}
/* The objective is to minimize the costs */
error = GRBsetintattr(model, "ModelSense", GRB_MINIMIZE);
if (error) goto QUIT;
/* Nutrition constraints */
cbeg = malloc(sizeof(int) * nCategories);
if (!cbeg) goto QUIT;
cind = malloc(sizeof(int) * nCategories * (nFoods + 1));
if (!cind) goto QUIT;
cval = malloc(sizeof(double) * nCategories * (nFoods + 1));
if (!cval) goto QUIT;
rhs = malloc(sizeof(double) * nCategories);
if (!rhs) goto QUIT;
sense = malloc(sizeof(char) * nCategories);
if (!sense) goto QUIT;
idx = 0;
for (i = 0; i < nCategories; ++i)
{
cbeg[i] = idx;
rhs[i] = 0.0;
sense[i] = GRB_EQUAL;
for (j = 0; j < nFoods; ++j)
{
cind[idx] = j;
cval[idx++] = nutritionValues[j][i];
}
cind[idx] = nFoods + i;
cval[idx++] = -1.0;
}
error = GRBaddconstrs(model, nCategories, idx, cbeg, cind, cval, sense,
rhs, Categories);
if (error) goto QUIT;
/* Solve */
error = GRBoptimize(model);
if (error) goto QUIT;
error = printSolution(model, nCategories, nFoods);
if (error) goto QUIT;
printf("\nAdding constraint: at most 6 servings of dairy\n");
cind[0] = 7;
cval[0] = 1.0;
cind[1] = 8;
cval[1] = 1.0;
error = GRBaddconstr(model, 2, cind, cval, GRB_LESS_EQUAL, 6.0,
"limit_dairy");
if (error) goto QUIT;
/* Solve */
error = GRBoptimize(model);
if (error) goto QUIT;
error = printSolution(model, nCategories, nFoods);
if (error) goto QUIT;
QUIT:
/* Error reporting */
if (error)
{
printf("ERROR: %s\n", GRBgeterrormsg(env));
exit(1);
}
/* Free data */
free(cbeg);
free(cind);
free(cval);
free(rhs);
free(sense);
/* Free model */
GRBfreemodel(model);
/* Free environment */
GRBfreeenv(env);
return 0;
}
int printSolution(GRBmodel* model, int nCategories, int nFoods)
{
int error, status, i, j;
double obj, x;
char* vname;
error = GRBgetintattr(model, "Status", &status);
if (error) return error;
if (status == GRB_OPTIMAL)
{
error = GRBgetdblattr(model, "ObjVal", &obj);
if (error) return error;
printf("\nCost: %f\n\nBuy:\n", obj);
for (j = 0; j < nFoods; ++j)
{
error = GRBgetdblattrelement(model, "X", j, &x);
if (error) return error;
if (x > 0.0001)
{
error = GRBgetstrattrelement(model, "VarName", j, &vname);
if (error) return error;
printf("%s %f\n", vname, x);
}
}
printf("\nNutrition:\n");
for (i = 0; i < nCategories; ++i)
{
error = GRBgetdblattrelement(model, "X", i + nFoods, &x);
if (error) return error;
error = GRBgetstrattrelement(model, "VarName", i + nFoods, &vname);
if (error) return error;
printf("%s %f\n", vname, x);
}
}
else
{
printf("No solution\n");
}
return 0;
}
/* Copyright 2024, Gurobi Optimization, LLC */
/* Solve the classic diet model, showing how to add constraints
to an existing model. */
#include "gurobi_c++.h"
using namespace std;
void printSolution(GRBModel& model, int nCategories, int nFoods,
GRBVar* buy, GRBVar* nutrition);
int
main(int argc,
char *argv[])
{
GRBEnv* env = 0;
GRBVar* nutrition = 0;
GRBVar* buy = 0;
try
{
// Nutrition guidelines, based on
// USDA Dietary Guidelines for Americans, 2005
// http://www.health.gov/DietaryGuidelines/dga2005/
const int nCategories = 4;
string Categories[] =
{ "calories", "protein", "fat", "sodium" };
double minNutrition[] = { 1800, 91, 0, 0 };
double maxNutrition[] = { 2200, GRB_INFINITY, 65, 1779 };
// Set of foods
const int nFoods = 9;
string Foods[] =
{ "hamburger", "chicken", "hot dog", "fries",
"macaroni", "pizza", "salad", "milk", "ice cream" };
double cost[] =
{ 2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89, 1.59 };
// Nutrition values for the foods
double nutritionValues[][nCategories] = {
{ 410, 24, 26, 730 }, // hamburger
{ 420, 32, 10, 1190 }, // chicken
{ 560, 20, 32, 1800 }, // hot dog
{ 380, 4, 19, 270 }, // fries
{ 320, 12, 10, 930 }, // macaroni
{ 320, 15, 12, 820 }, // pizza
{ 320, 31, 12, 1230 }, // salad
{ 100, 8, 2.5, 125 }, // milk
{ 330, 8, 10, 180 } // ice cream
};
// Model
env = new GRBEnv();
GRBModel model = GRBModel(*env);
model.set(GRB_StringAttr_ModelName, "diet");
// Create decision variables for the nutrition information,
// which we limit via bounds
nutrition = model.addVars(minNutrition, maxNutrition, 0, 0,
Categories, nCategories);
// Create decision variables for the foods to buy
//
// Note: For each decision variable we add the objective coefficient
// with the creation of the variable.
buy = model.addVars(0, 0, cost, 0, Foods, nFoods);
// The objective is to minimize the costs
//
// Note: The objective coefficients are set during the creation of
// the decision variables above.
model.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE);
// Nutrition constraints
for (int i = 0; i < nCategories; ++i)
{
GRBLinExpr ntot = 0;
for (int j = 0; j < nFoods; ++j)
{
ntot += nutritionValues[j][i] * buy[j];
}
model.addConstr(ntot == nutrition[i], Categories[i]);
}
// Solve
model.optimize();
printSolution(model, nCategories, nFoods, buy, nutrition);
cout << "\nAdding constraint: at most 6 servings of dairy" << endl;
model.addConstr(buy[7] + buy[8] <= 6.0, "limit_dairy");
// Solve
model.optimize();
printSolution(model, nCategories, nFoods, buy, nutrition);
}
catch (GRBException e)
{
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
}
catch (...)
{
cout << "Exception during optimization" << endl;
}
delete[] nutrition;
delete[] buy;
delete env;
return 0;
}
void printSolution(GRBModel& model, int nCategories, int nFoods,
GRBVar* buy, GRBVar* nutrition)
{
if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL)
{
cout << "\nCost: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
cout << "\nBuy:" << endl;
for (int j = 0; j < nFoods; ++j)
{
if (buy[j].get(GRB_DoubleAttr_X) > 0.0001)
{
cout << buy[j].get(GRB_StringAttr_VarName) << " " <<
buy[j].get(GRB_DoubleAttr_X) << endl;
}
}
cout << "\nNutrition:" << endl;
for (int i = 0; i < nCategories; ++i)
{
cout << nutrition[i].get(GRB_StringAttr_VarName) << " " <<
nutrition[i].get(GRB_DoubleAttr_X) << endl;
}
}
else
{
cout << "No solution" << endl;
}
}
/* Copyright 2024, Gurobi Optimization, LLC */
/* Solve the classic diet model, showing how to add constraints
to an existing model. */
using System;
using Gurobi;
class diet_cs
{
static void Main()
{
try {
// Nutrition guidelines, based on
// USDA Dietary Guidelines for Americans, 2005
// http://www.health.gov/DietaryGuidelines/dga2005/
string[] Categories =
new string[] { "calories", "protein", "fat", "sodium" };
int nCategories = Categories.Length;
double[] minNutrition = new double[] { 1800, 91, 0, 0 };
double[] maxNutrition = new double[] { 2200, GRB.INFINITY, 65, 1779 };
// Set of foods
string[] Foods =
new string[] { "hamburger", "chicken", "hot dog", "fries",
"macaroni", "pizza", "salad", "milk", "ice cream" };
int nFoods = Foods.Length;
double[] cost =
new double[] { 2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89,
1.59 };
// Nutrition values for the foods
double[,] nutritionValues = new double[,] {
{ 410, 24, 26, 730 }, // hamburger
{ 420, 32, 10, 1190 }, // chicken
{ 560, 20, 32, 1800 }, // hot dog
{ 380, 4, 19, 270 }, // fries
{ 320, 12, 10, 930 }, // macaroni
{ 320, 15, 12, 820 }, // pizza
{ 320, 31, 12, 1230 }, // salad
{ 100, 8, 2.5, 125 }, // milk
{ 330, 8, 10, 180 } // ice cream
};
// Model
GRBEnv env = new GRBEnv();
GRBModel model = new GRBModel(env);
model.ModelName = "diet";
// Create decision variables for the nutrition information,
// which we limit via bounds
GRBVar[] nutrition = new GRBVar[nCategories];
for (int i = 0; i < nCategories; ++i) {
nutrition[i] =
model.AddVar(minNutrition[i], maxNutrition[i], 0, GRB.CONTINUOUS,
Categories[i]);
}
// Create decision variables for the foods to buy
//
// Note: For each decision variable we add the objective coefficient
// with the creation of the variable.
GRBVar[] buy = new GRBVar[nFoods];
for (int j = 0; j < nFoods; ++j) {
buy[j] =
model.AddVar(0, GRB.INFINITY, cost[j], GRB.CONTINUOUS, Foods[j]);
}
// The objective is to minimize the costs
//
// Note: The objective coefficients are set during the creation of
// the decision variables above.
model.ModelSense = GRB.MINIMIZE;
// Nutrition constraints
for (int i = 0; i < nCategories; ++i) {
GRBLinExpr ntot = 0.0;
for (int j = 0; j < nFoods; ++j)
ntot.AddTerm(nutritionValues[j,i], buy[j]);
model.AddConstr(ntot == nutrition[i], Categories[i]);
}
// Solve
model.Optimize();
PrintSolution(model, buy, nutrition);
Console.WriteLine("\nAdding constraint: at most 6 servings of dairy");
model.AddConstr(buy[7] + buy[8] <= 6.0, "limit_dairy");
// Solve
model.Optimize();
PrintSolution(model, buy, nutrition);
// Dispose of model and env
model.Dispose();
env.Dispose();
} catch (GRBException e) {
Console.WriteLine("Error code: " + e.ErrorCode + ". " +
e.Message);
}
}
private static void PrintSolution(GRBModel model, GRBVar[] buy,
GRBVar[] nutrition) {
if (model.Status == GRB.Status.OPTIMAL) {
Console.WriteLine("\nCost: " + model.ObjVal);
Console.WriteLine("\nBuy:");
for (int j = 0; j < buy.Length; ++j) {
if (buy[j].X > 0.0001) {
Console.WriteLine(buy[j].VarName + " " + buy[j].X);
}
}
Console.WriteLine("\nNutrition:");
for (int i = 0; i < nutrition.Length; ++i) {
Console.WriteLine(nutrition[i].VarName + " " + nutrition[i].X);
}
} else {
Console.WriteLine("No solution");
}
}
}
/* Copyright 2024, Gurobi Optimization, LLC */
/* Solve the classic diet model, showing how to add constraints
to an existing model. */
import com.gurobi.gurobi.*;
public class Diet {
public static void main(String[] args) {
try {
// Nutrition guidelines, based on
// USDA Dietary Guidelines for Americans, 2005
// http://www.health.gov/DietaryGuidelines/dga2005/
String Categories[] =
new String[] { "calories", "protein", "fat", "sodium" };
int nCategories = Categories.length;
double minNutrition[] = new double[] { 1800, 91, 0, 0 };
double maxNutrition[] = new double[] { 2200, GRB.INFINITY, 65, 1779 };
// Set of foods
String Foods[] =
new String[] { "hamburger", "chicken", "hot dog", "fries",
"macaroni", "pizza", "salad", "milk", "ice cream" };
int nFoods = Foods.length;
double cost[] =
new double[] { 2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89,
1.59 };
// Nutrition values for the foods
double nutritionValues[][] = new double[][] {
{ 410, 24, 26, 730 }, // hamburger
{ 420, 32, 10, 1190 }, // chicken
{ 560, 20, 32, 1800 }, // hot dog
{ 380, 4, 19, 270 }, // fries
{ 320, 12, 10, 930 }, // macaroni
{ 320, 15, 12, 820 }, // pizza
{ 320, 31, 12, 1230 }, // salad
{ 100, 8, 2.5, 125 }, // milk
{ 330, 8, 10, 180 } // ice cream
};
// Model
GRBEnv env = new GRBEnv();
GRBModel model = new GRBModel(env);
model.set(GRB.StringAttr.ModelName, "diet");
// Create decision variables for the nutrition information,
// which we limit via bounds
GRBVar[] nutrition = new GRBVar[nCategories];
for (int i = 0; i < nCategories; ++i) {
nutrition[i] =
model.addVar(minNutrition[i], maxNutrition[i], 0, GRB.CONTINUOUS,
Categories[i]);
}
// Create decision variables for the foods to buy
//
// Note: For each decision variable we add the objective coefficient
// with the creation of the variable.
GRBVar[] buy = new GRBVar[nFoods];
for (int j = 0; j < nFoods; ++j) {
buy[j] =
model.addVar(0, GRB.INFINITY, cost[j], GRB.CONTINUOUS, Foods[j]);
}
// The objective is to minimize the costs
//
// Note: The objective coefficients are set during the creation of
// the decision variables above.
model.set(GRB.IntAttr.ModelSense, GRB.MINIMIZE);
// Nutrition constraints
for (int i = 0; i < nCategories; ++i) {
GRBLinExpr ntot = new GRBLinExpr();
for (int j = 0; j < nFoods; ++j) {
ntot.addTerm(nutritionValues[j][i], buy[j]);
}
model.addConstr(ntot, GRB.EQUAL, nutrition[i], Categories[i]);
}
// Solve
model.optimize();
printSolution(model, buy, nutrition);
System.out.println("JSON solution:" + model.getJSONSolution());
System.out.println("\nAdding constraint: at most 6 servings of dairy");
GRBLinExpr lhs = new GRBLinExpr();
lhs.addTerm(1.0, buy[7]);
lhs.addTerm(1.0, buy[8]);
model.addConstr(lhs, GRB.LESS_EQUAL, 6.0, "limit_dairy");
// Solve
model.optimize();
printSolution(model, buy, nutrition);
System.out.println("JSON solution:" + model.getJSONSolution());
// Dispose of model and environment
model.dispose();
env.dispose();
} catch (GRBException e) {
System.out.println("Error code: " + e.getErrorCode() + ". " +
e.getMessage());
}
}
private static void printSolution(GRBModel model, GRBVar[] buy,
GRBVar[] nutrition) throws GRBException {
if (model.get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) {
System.out.println("\nCost: " + model.get(GRB.DoubleAttr.ObjVal));
System.out.println("\nBuy:");
for (int j = 0; j < buy.length; ++j) {
if (buy[j].get(GRB.DoubleAttr.X) > 0.0001) {
System.out.println(buy[j].get(GRB.StringAttr.VarName) + " " +
buy[j].get(GRB.DoubleAttr.X));
}
}
System.out.println("\nNutrition:");
for (int i = 0; i < nutrition.length; ++i) {
System.out.println(nutrition[i].get(GRB.StringAttr.VarName) + " " +
nutrition[i].get(GRB.DoubleAttr.X));
}
} else {
System.out.println("No solution");
}
}
}
function diet()
% Copyright 2024, Gurobi Optimization, LLC
%
% Solve the classic diet model
% Nutrition guidelines, based on
% USDA Dietary Guidelines for Americans, 2005
% http://www.health.gov/DietaryGuidelines/dga2005/
ncategories = 4;
categories = {'calories'; 'protein'; 'fat'; 'sodium'};
% minNutrition maxNutrition
categorynutrition = [ 1800 2200; % calories
91 inf; % protein
0 65; % fat
0 1779]; % sodium
nfoods = 9;
foods = {'hamburger';
'chicken';
'hot dog';
'fries';
'macaroni';
'pizza';
'salad';
'milk';
'ice cream'};
foodcost = [2.49; % hamburger
2.89; % chicken
1.50; % hot dog
1.89; % fries
2.09; % macaroni
1.99; % pizza
2.49; % salad
0.89; % milk
1.59]; % ice cream
% calories protein fat sodium
nutritionValues = [ 410 24 26 730; % hamburger
420 32 10 1190; % chicken
560 20 32 1800; % hot dog
380 4 19 270; % fries
320 12 10 930; % macaroni
320 15 12 820; % pizza
320 31 12 1230; % salad
100 8 2.5 125; % milk
330 8 10 180]; % ice cream
nutritionValues = sparse(nutritionValues);
model.modelName = 'diet';
% The variables are layed out as [ buy; nutrition]
model.obj = [ foodcost; zeros(ncategories, 1)];
model.lb = [ zeros(nfoods, 1); categorynutrition(:, 1)];
model.ub = [ inf(nfoods, 1); categorynutrition(:, 2)];
model.A = [ nutritionValues' -speye(ncategories)];
model.rhs = zeros(ncategories, 1);
model.sense = repmat('=', ncategories, 1);
function printSolution(result)
if strcmp(result.status, 'OPTIMAL')
buy = result.x(1:nfoods);
nutrition = result.x(nfoods+1:nfoods+ncategories);
fprintf('\nCost: %f\n', result.objval);
fprintf('\nBuy:\n')
for f=1:nfoods
if buy(f) > 0.0001
fprintf('%10s %g\n', foods{f}, buy(f));
end
end
fprintf('\nNutrition:\n')
for c=1:ncategories
fprintf('%10s %g\n', categories{c}, nutrition(c));
end
else
fprintf('No solution\n');
end
end
% Solve
results = gurobi(model);
printSolution(results);
fprintf('\nAdding constraint at most 6 servings of dairy\n')
milk = find(strcmp('milk', foods));
icecream = find(strcmp('ice cream', foods));
model.A(end+1,:) = sparse([1; 1], [milk; icecream], 1, ...
1, nfoods + ncategories);
model.rhs(end+1) = 6;
model.sense(end+1) = '<';
% Solve
results = gurobi(model);
printSolution(results)
end
#!/usr/bin/env python3.11
# Copyright 2024, Gurobi Optimization, LLC
# Solve the classic diet model, showing how to add constraints
# to an existing model.
import gurobipy as gp
from gurobipy import GRB
# Nutrition guidelines, based on
# USDA Dietary Guidelines for Americans, 2005
# http://www.health.gov/DietaryGuidelines/dga2005/
categories, minNutrition, maxNutrition = gp.multidict(
{
"calories": [1800, 2200],
"protein": [91, GRB.INFINITY],
"fat": [0, 65],
"sodium": [0, 1779],
}
)
foods, cost = gp.multidict(
{
"hamburger": 2.49,
"chicken": 2.89,
"hot dog": 1.50,
"fries": 1.89,
"macaroni": 2.09,
"pizza": 1.99,
"salad": 2.49,
"milk": 0.89,
"ice cream": 1.59,
}
)
# Nutrition values for the foods
nutritionValues = {
("hamburger", "calories"): 410,
("hamburger", "protein"): 24,
("hamburger", "fat"): 26,
("hamburger", "sodium"): 730,
("chicken", "calories"): 420,
("chicken", "protein"): 32,
("chicken", "fat"): 10,
("chicken", "sodium"): 1190,
("hot dog", "calories"): 560,
("hot dog", "protein"): 20,
("hot dog", "fat"): 32,
("hot dog", "sodium"): 1800,
("fries", "calories"): 380,
("fries", "protein"): 4,
("fries", "fat"): 19,
("fries", "sodium"): 270,
("macaroni", "calories"): 320,
("macaroni", "protein"): 12,
("macaroni", "fat"): 10,
("macaroni", "sodium"): 930,
("pizza", "calories"): 320,
("pizza", "protein"): 15,
("pizza", "fat"): 12,
("pizza", "sodium"): 820,
("salad", "calories"): 320,
("salad", "protein"): 31,
("salad", "fat"): 12,
("salad", "sodium"): 1230,
("milk", "calories"): 100,
("milk", "protein"): 8,
("milk", "fat"): 2.5,
("milk", "sodium"): 125,
("ice cream", "calories"): 330,
("ice cream", "protein"): 8,
("ice cream", "fat"): 10,
("ice cream", "sodium"): 180,
}
# Model
m = gp.Model("diet")
# Create decision variables for the foods to buy
buy = m.addVars(foods, name="buy")
# You could use Python looping constructs and m.addVar() to create
# these decision variables instead. The following would be equivalent
#
# buy = {}
# for f in foods:
# buy[f] = m.addVar(name=f)
# The objective is to minimize the costs
m.setObjective(buy.prod(cost), GRB.MINIMIZE)
# Using looping constructs, the preceding statement would be:
#
# m.setObjective(sum(buy[f]*cost[f] for f in foods), GRB.MINIMIZE)
# Nutrition constraints
m.addConstrs(
(
gp.quicksum(nutritionValues[f, c] * buy[f] for f in foods)
== [minNutrition[c], maxNutrition[c]]
for c in categories
),
"_",
)
# Using looping constructs, the preceding statement would be:
#
# for c in categories:
# m.addRange(sum(nutritionValues[f, c] * buy[f] for f in foods),
# minNutrition[c], maxNutrition[c], c)
def printSolution():
if m.status == GRB.OPTIMAL:
print(f"\nCost: {m.ObjVal:g}")
print("\nBuy:")
for f in foods:
if buy[f].X > 0.0001:
print(f"{f} {buy[f].X:g}")
else:
print("No solution")
# Solve
m.optimize()
printSolution()
print("\nAdding constraint: at most 6 servings of dairy")
m.addConstr(buy.sum(["milk", "ice cream"]) <= 6, "limit_dairy")
# Solve
m.optimize()
printSolution()
# Copyright 2024, Gurobi Optimization, LLC
#
# Solve the classic diet model, showing how to add constraints
# to an existing model.
library(Matrix)
library(gurobi)
# display results
printSolution <- function(model, res, nCategories, nFoods) {
if (res$status == 'OPTIMAL') {
cat('\nCost: ',res$objval,'\nBuy:\n')
for (j in nCategories + 1:nFoods) {
if (res$x[j] > 1e-4) {
cat(format(model$varnames[j],justify='left',width=10),':',
format(res$x[j],justify='right',width=10,nsmall=2),'\n')
}
}
cat('\nNutrition:\n')
for (j in 1:nCategories) {
cat(format(model$varnames[j],justify='left',width=10),':',
format(res$x[j],justify='right',width=10,nsmall=2),'\n')
}
} else {
cat('No solution\n')
}
}
# define primitive data
Categories <- c('calories', 'protein', 'fat', 'sodium')
nCategories <- length(Categories)
minNutrition <- c( 1800 , 91 , 0 , 0 )
maxNutrition <- c( 2200 , Inf , 65 , 1779 )
Foods <- c('hamburger', 'chicken', 'hot dog', 'fries', 'macaroni',
'pizza', 'salad', 'milk', 'ice cream')
nFoods <- length(Foods)
cost <- c(2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89, 1.59)
nutritionValues <- c( 410, 24, 26 , 730,
420, 32, 10 , 1190,
560, 20, 32 , 1800,
380, 4, 19 , 270,
320, 12, 10 , 930,
320, 15, 12 , 820,
320, 31, 12 , 1230,
100, 8, 2.5, 125,
330, 8, 10 , 180 )
# Build model
model <- list()
model$A <- spMatrix(nCategories, nCategories + nFoods,
i = c(mapply(rep,1:4,1+nFoods)),
j = c(1, (nCategories+1):(nCategories+nFoods),
2, (nCategories+1):(nCategories+nFoods),
3, (nCategories+1):(nCategories+nFoods),
4, (nCategories+1):(nCategories+nFoods) ),
x = c(-1.0, nutritionValues[1 + nCategories*(0:(nFoods-1))],
-1.0, nutritionValues[2 + nCategories*(0:(nFoods-1))],
-1.0, nutritionValues[3 + nCategories*(0:(nFoods-1))],
-1.0, nutritionValues[4 + nCategories*(0:(nFoods-1))] ))
model$obj <- c(rep(0, nCategories), cost)
model$lb <- c(minNutrition, rep(0, nFoods))
model$ub <- c(maxNutrition, rep(Inf, nFoods))
model$varnames <- c(Categories, Foods)
model$rhs <- rep(0,nCategories)
model$sense <- rep('=',nCategories)
model$constrnames <- Categories
model$modelname <- 'diet'
model$modelsense <- 'min'
# Optimize
res <- gurobi(model)
printSolution(model, res, nCategories, nFoods)
# Adding constraint: at most 6 servings of dairy
# this is the matrix part of the constraint
B <- spMatrix(1, nCategories + nFoods,
i = rep(1,2),
j = (nCategories+c(8,9)),
x = rep(1,2))
# append B to A
model$A <- rbind(model$A, B)
# extend row-related vectors
model$constrnames <- c(model$constrnames, 'limit_dairy')
model$rhs <- c(model$rhs, 6)
model$sense <- c(model$sense, '<')
# Optimize
res <- gurobi(model)
printSolution(model, res, nCategories, nFoods)
# Clear space
rm(res, model)
' Copyright 2024, Gurobi Optimization, LLC
' Solve the classic diet model, showing how to add constraints
' to an existing model.
Imports System
Imports Gurobi
Class diet_vb
Shared Sub Main()
Try
' Nutrition guidelines, based on
' USDA Dietary Guidelines for Americans, 2005
' http://www.health.gov/DietaryGuidelines/dga2005/
Dim Categories As String() = New String() {"calories", "protein", "fat", _
"sodium"}
Dim nCategories As Integer = Categories.Length
Dim minNutrition As Double() = New Double() {1800, 91, 0, 0}
Dim maxNutrition As Double() = New Double() {2200, GRB.INFINITY, 65, 1779}
' Set of foods
Dim Foods As String() = New String() {"hamburger", "chicken", "hot dog", _
"fries", "macaroni", "pizza", _
"salad", "milk", "ice cream"}
Dim nFoods As Integer = Foods.Length
Dim cost As Double() = New Double() {2.49, 2.89, 1.5R, 1.89, 2.09, 1.99, _
2.49, 0.89, 1.59}
' Nutrition values for the foods
' hamburger
' chicken
' hot dog
' fries
' macaroni
' pizza
' salad
' milk
' ice cream
Dim nutritionValues As Double(,) = New Double(,) {{410, 24, 26, 730}, _
{420, 32, 10, 1190}, _
{560, 20, 32, 1800}, _
{380, 4, 19, 270}, _
{320, 12, 10, 930}, _
{320, 15, 12, 820}, _
{320, 31, 12, 1230}, _
{100, 8, 2.5, 125}, _
{330, 8, 10, 180}}
' Model
Dim env As New GRBEnv()
Dim model As New GRBModel(env)
model.ModelName = "diet"
' Create decision variables for the nutrition information,
' which we limit via bounds
Dim nutrition As GRBVar() = New GRBVar(nCategories - 1) {}
For i As Integer = 0 To nCategories - 1
nutrition(i) = model.AddVar(minNutrition(i), maxNutrition(i), 0, _
GRB.CONTINUOUS, Categories(i))
Next
' Create decision variables for the foods to buy
'
' Note: For each decision variable we add the objective coefficient
' with the creation of the variable.
Dim buy As GRBVar() = New GRBVar(nFoods - 1) {}
For j As Integer = 0 To nFoods - 1
buy(j) = model.AddVar(0, GRB.INFINITY, cost(j), GRB.CONTINUOUS, _
Foods(j))
Next
' The objective is to minimize the costs
'
' Note: The objective coefficients are set during the creation of
' the decision variables above.
model.ModelSense = GRB.MINIMIZE
' Nutrition constraints
For i As Integer = 0 To nCategories - 1
Dim ntot As GRBLinExpr = 0
For j As Integer = 0 To nFoods - 1
ntot.AddTerm(nutritionValues(j, i), buy(j))
Next
model.AddConstr(ntot = nutrition(i), Categories(i))
Next
' Solve
model.Optimize()
PrintSolution(model, buy, nutrition)
Console.WriteLine(vbLf & "Adding constraint: at most 6 servings of dairy")
model.AddConstr(buy(7) + buy(8) <= 6, "limit_dairy")
' Solve
model.Optimize()
PrintSolution(model, buy, nutrition)
' Dispose of model and env
model.Dispose()
env.Dispose()
Catch e As GRBException
Console.WriteLine("Error code: " & e.ErrorCode & ". " & e.Message)
End Try
End Sub
Private Shared Sub PrintSolution(ByVal model As GRBModel, ByVal buy As GRBVar(), _
ByVal nutrition As GRBVar())
If model.Status = GRB.Status.OPTIMAL Then
Console.WriteLine(vbLf & "Cost: " & model.ObjVal)
Console.WriteLine(vbLf & "Buy:")
For j As Integer = 0 To buy.Length - 1
If buy(j).X > 0.0001 Then
Console.WriteLine(buy(j).VarName & " " & buy(j).X)
End If
Next
Console.WriteLine(vbLf & "Nutrition:")
For i As Integer = 0 To nutrition.Length - 1
Console.WriteLine(nutrition(i).VarName & " " & nutrition(i).X)
Next
Else
Console.WriteLine("No solution")
End If
End Sub
End Class
diet2#
#!/usr/bin/env python3.11
# Copyright 2024, Gurobi Optimization, LLC
# Separate the model (dietmodel.py) from the data file (diet2.py), so
# that the model can be solved with different data files.
#
# Nutrition guidelines, based on
# USDA Dietary Guidelines for Americans, 2005
# http://www.health.gov/DietaryGuidelines/dga2005/
import dietmodel
import gurobipy as gp
from gurobipy import GRB
categories, minNutrition, maxNutrition = gp.multidict(
{
"calories": [1800, 2200],
"protein": [91, GRB.INFINITY],
"fat": [0, 65],
"sodium": [0, 1779],
}
)
foods, cost = gp.multidict(
{
"hamburger": 2.49,
"chicken": 2.89,
"hot dog": 1.50,
"fries": 1.89,
"macaroni": 2.09,
"pizza": 1.99,
"salad": 2.49,
"milk": 0.89,
"ice cream": 1.59,
}
)
# Nutrition values for the foods
nutritionValues = {
("hamburger", "calories"): 410,
("hamburger", "protein"): 24,
("hamburger", "fat"): 26,
("hamburger", "sodium"): 730,
("chicken", "calories"): 420,
("chicken", "protein"): 32,
("chicken", "fat"): 10,
("chicken", "sodium"): 1190,
("hot dog", "calories"): 560,
("hot dog", "protein"): 20,
("hot dog", "fat"): 32,
("hot dog", "sodium"): 1800,
("fries", "calories"): 380,
("fries", "protein"): 4,
("fries", "fat"): 19,
("fries", "sodium"): 270,
("macaroni", "calories"): 320,
("macaroni", "protein"): 12,
("macaroni", "fat"): 10,
("macaroni", "sodium"): 930,
("pizza", "calories"): 320,
("pizza", "protein"): 15,
("pizza", "fat"): 12,
("pizza", "sodium"): 820,
("salad", "calories"): 320,
("salad", "protein"): 31,
("salad", "fat"): 12,
("salad", "sodium"): 1230,
("milk", "calories"): 100,
("milk", "protein"): 8,
("milk", "fat"): 2.5,
("milk", "sodium"): 125,
("ice cream", "calories"): 330,
("ice cream", "protein"): 8,
("ice cream", "fat"): 10,
("ice cream", "sodium"): 180,
}
dietmodel.solve(categories, minNutrition, maxNutrition, foods, cost, nutritionValues)
diet3#
#!/usr/bin/env python3.11
# Copyright 2024, Gurobi Optimization, LLC
# Use a SQLite database with the diet model (dietmodel.py). The database
# (diet.db) can be recreated using the included SQL script (diet.sql).
#
# Note that this example reads an external data file (..\data\diet.db).
# As a result, it must be run from the Gurobi examples/python directory.
import os
import sqlite3
import dietmodel
import gurobipy as gp
con = sqlite3.connect(os.path.join("..", "data", "diet.db"))
cur = con.cursor()
cur.execute("select category,minnutrition,maxnutrition from categories")
result = cur.fetchall()
categories, minNutrition, maxNutrition = gp.multidict(
(cat, [minv, maxv]) for cat, minv, maxv in result
)
cur.execute("select food,cost from foods")
result = cur.fetchall()
foods, cost = gp.multidict(result)
cur.execute("select food,category,value from nutrition")
result = cur.fetchall()
nutritionValues = dict(((f, c), v) for f, c, v in result)
con.close()
dietmodel.solve(categories, minNutrition, maxNutrition, foods, cost, nutritionValues)
diet4#
#!/usr/bin/env python3.11
# Copyright 2024, Gurobi Optimization, LLC
# Read diet model data from an Excel spreadsheet (diet.xlsx).
# Pass the imported data into the diet model (dietmodel.py).
#
# Note that this example reads an external data file (..\data\diet.xlsx).
# As a result, it must be run from the Gurobi examples/python directory.
#
# This example uses Python package 'openpyxl', which isn't included
# in most Python distributions. You can install it with
# 'pip install openpyxl'.
import os
import openpyxl
import dietmodel
# Open 'diet.xlsx'
book = openpyxl.load_workbook(os.path.join("..", "data", "diet.xlsx"))
# Read min/max nutrition info from 'Categories' sheet
sheet = book["Categories"]
categories = []
minNutrition = {}
maxNutrition = {}
for row in sheet.iter_rows():
category = row[0].value
if category != "Categories":
categories.append(category)
minNutrition[category] = row[1].value
maxNutrition[category] = row[2].value
# Read food costs from 'Foods' sheet
sheet = book["Foods"]
foods = []
cost = {}
for row in sheet.iter_rows():
food = row[0].value
if food != "Foods":
foods.append(food)
cost[food] = row[1].value
# Read food nutrition info from 'Nutrition' sheet
sheet = book["Nutrition"]
nutritionValues = {}
for row in sheet.iter_rows():
if row[0].value == None: # column labels - categories
cats = [v.value for v in row]
else: # nutrition values
food = row[0].value
for col in range(1, len(row)):
nutritionValues[food, cats[col]] = row[col].value
dietmodel.solve(categories, minNutrition, maxNutrition, foods, cost, nutritionValues)