Reproducing an amplpy ticdat issue without ticdat

This might be something you need to do to demo a specific amplpy issue, so here is a demo notebook about how to do that.

NB you will might need some sort of %env PATH = statement here to get insure the AMPL engine can be found


In [2]:
from amplpy import AMPL
import amplpy
from pandas import DataFrame


/Users/petercacioppi/anaconda/lib/python2.7/site-packages/numexpr/cpuinfo.py:53: UserWarning: [Errno 2] No such file or directory
  stacklevel=stacklevel + 1)
/Users/petercacioppi/anaconda/lib/python2.7/site-packages/numexpr/cpuinfo.py:76: UserWarning: [Errno 2] No such file or directory
  stacklevel=stacklevel + 1):

FYI - ticdat.testing.testampl.convert_to_dicts_that_can_be_turned_into_DataFrames makes it easy to create the hardcoded dict objects that are then used to create the DataFrame objects below.


In [3]:
categories = DataFrame({'Name': {0: u'calories',
   1: u'fat',
   2: u'protein',
   3: u'sodium'},
  'n_max': {0: 2200.0, 1: 65.0, 2: float('inf'), 3: 1779.0},
  'n_min': {0: 1800, 1: 0, 2: 91, 3: 0}})

In [4]:
foods = DataFrame({'Name': {0: u'chicken',
   1: u'fries',
   2: u'hamburger',
   3: u'hot dog',
   4: u'ice cream',
   5: u'macaroni',
   6: u'milk',
   7: u'pizza',
   8: u'salad'},
  'cost': {0: 2.8900000000000001,
   1: 1.8899999999999999,
   2: 2.4900000000000002,
   3: 1.5,
   4: 1.5900000000000001,
   5: 2.0899999999999999,
   6: 0.89000000000000001,
   7: 1.99,
   8: 2.4900000000000002}})

In [5]:
nutrition_quantities = DataFrame({'Category': {0: u'calories', 1: u'fat', 2: u'protein', 3: u'sodium',
   4: u'calories', 5: u'fat', 6: u'protein', 7: u'sodium', 8: u'calories', 9: u'fat', 10: u'protein',
   11: u'sodium', 12: u'calories', 13: u'fat', 14: u'protein', 15: u'sodium', 16: u'calories', 17: u'fat',
   18: u'protein', 19: u'sodium', 20: u'calories', 21: u'fat', 22: u'protein', 23: u'sodium', 24: u'calories',
   25: u'fat', 26: u'protein', 27: u'sodium', 28: u'calories', 29: u'fat', 30: u'protein', 31: u'sodium',
   32: u'calories', 33: u'fat', 34: u'protein', 35: u'sodium'},
  'Food': {0: u'chicken', 1: u'chicken', 2: u'chicken', 3: u'chicken', 4: u'fries', 5: u'fries', 6: u'fries',
   7: u'fries', 8: u'hamburger', 9: u'hamburger', 10: u'hamburger', 11: u'hamburger', 12: u'hot dog',
   13: u'hot dog', 14: u'hot dog', 15: u'hot dog', 16: u'ice cream', 17: u'ice cream', 18: u'ice cream',
   19: u'ice cream', 20: u'macaroni', 21: u'macaroni', 22: u'macaroni', 23: u'macaroni', 24: u'milk', 25: u'milk',
   26: u'milk', 27: u'milk', 28: u'pizza', 29: u'pizza', 30: u'pizza', 31: u'pizza', 32: u'salad', 33: u'salad',
   34: u'salad', 35: u'salad'},
  'amt': {0: 420.0, 1: 10.0, 2: 32.0, 3: 1190.0, 4: 380.0, 5: 19.0, 6: 4.0, 7: 270.0, 8: 410.0, 9: 26.0,
   10: 24.0, 11: 730.0, 12: 560.0, 13: 32.0, 14: 20.0, 15: 1800.0, 16: 330.0, 17: 10.0, 18: 8.0, 19: 180.0,
   20: 320.0, 21: 10.0, 22: 12.0, 23: 930.0, 24: 100.0, 25: 2.5, 26: 8.0, 27: 125.0, 28: 320.0, 29: 12.0,
   30: 15.0, 31: 820.0, 32: 320.0, 33: 12.0, 34: 31.0, 35: 1230.0}})

In [6]:
mod_str = """
    set CAT;
    set FOOD;
    param cost {FOOD} > 0;
    param n_min {CAT} >= 0;
    param n_max {i in CAT} >= n_min[i];
    param amt {FOOD, CAT} >= 0;
    var Buy {j in FOOD} >= 0;
    var Consume {i in CAT } >= n_min [i], <= n_max [i];
    minimize Total_Cost:  sum {j in FOOD} cost[j] * Buy[j];
    subject to Diet {i in CAT}:
       Consume[i] =  sum {j in FOOD} amt[j,i] * Buy[j];
    """

In [7]:
ampl = AMPL()
ampl.setOption('solver', 'gurobi')
ampl.eval(mod_str)

In [8]:
def df_to_ampl_df(df, pkfields):
    assert set(df.columns).issuperset(pkfields)
    rtn = amplpy.DataFrame(index=pkfields)
    for f in pkfields:
        rtn.setColumn(f, list(df[f]))
    for f in df.columns:
        if f not in pkfields:
            rtn.addColumn(f, list(df[f]))
    return rtn

In [9]:
ampl.setData(df_to_ampl_df(categories, ("Name",)), "CAT")
ampl.setData(df_to_ampl_df(foods, ("Name",)), "FOOD")
ampl.setData(df_to_ampl_df(nutrition_quantities, ('Food', 'Category')))

In [10]:
# should find objective 11.82886111
ampl.solve()


Gurobi 7.5.0: optimal solution; objective 11.82886111
4 simplex iterations