diet.py


#!/usr/bin/python

# Copyright 2009, Gurobi Optimization, Inc.

# Solve the classic diet model, showing how to add constraints
# to an existing model.

import sys
from gurobipy import *

# Nutrition guidelines, based on
# USDA Dietary Guidelines for Americans, 2005
# http://www.health.gov/DietaryGuidelines/dga2005/

Categories = ['calories', 'protein', 'fat', 'sodium']
nCategories = len(Categories)
minNutrition = [1800, 91, 0, 0 ]
maxNutrition = [2200, GRB.INFINITY, 65, 1779]

# Set of foods
Foods = ['hamburger', 'chicken', 'hot dog', 'fries', 'macaroni',
         'pizza', 'salad', 'milk', 'ice cream']
nFoods = len(Foods)
cost = [2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89, 1.59]

# Nutrition values for the foods
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
]

# Model
m = Model("diet")

# Create decision variables for the nutrition information,
# which we limit via bounds
nutrition = []
for i in range(nCategories):
  newvar = m.addVar(minNutrition[i], maxNutrition[i], 0, \
                    GRB.CONTINUOUS, Categories[i])
  nutrition += [newvar]

# Create decision variables for the foods to buy
buy = []
for j in range(nFoods):
  newvar = m.addVar(0, GRB.INFINITY, cost[j], GRB.CONTINUOUS, Foods[j])
  buy += [newvar]

# The objective is to minimize the costs
m.ModelSense = 1;

# Update model to integrate new variables
m.update()

# Nutrition constraints
for i in range(nCategories):
  ntot = LinExpr()
  for j in range(nFoods):
    ntot.addTerms(nutritionValues[j][i], buy[j])
  m.addConstr(ntot, GRB.EQUAL, nutrition[i], Categories[i])

def printSolution():
  if m.Status == GRB.OPTIMAL:
    print '\nCost:', m.ObjVal
    print '\nBuy:'
    for j in range(nFoods):
      if buy[j].X > 0.0001  :
        print Foods[j], buy[j].X
    print '\nNutrition:'
    for i in range(nCategories):
      print Categories[i], nutrition[i].X
  else:
    print 'No solution'

# Solve
m.optimize()
printSolution()

print '\nAdding constraint: at most 6 servings of dairy'
lhs = LinExpr([1, 1], [buy[7], buy[8]])
m.addConstr(lhs, GRB.LESS_EQUAL, 6, "limit_dairy")

# Solve
m.optimize()
printSolution()