Documentation: http://amplpy.readthedocs.io
GitHub Repository: https://github.com/ampl/amplpy
PyPI Repository: https://pypi.python.org/pypi/amplpy
Install from the PiPY repository:
$ pip install amplpy
Or:
$ python -m pip install amplpy
Note: For Windows, Linux, and macOS, the amplpy package comes with 33 binary wheels for Python 2.7, 3.5, 3.6, 3.7, and 3.8. Please make sure that you are using the latest version of pip before installing amplpy (upgrade using "pip install pip --upgrade" or "python -m pip install pip --upgrade"). If a binary wheel for your platform is not available, a C++ compiler and python development libraries will be required.
In this tutorial, we will also use Pandas and Bokeh. You can install these packages using "pip install pandas bokeh" or "python -m pip install pandas bokeh". Note that Bokeh is not mandatory for this tutorial.
We also recommend the use of Jupyter Notebook, which was used to create this tutorial. You can install Jupyter using "pip install jupyter" or "python -m pip install jupyter".
In [1]:
from __future__ import print_function
Import Pandas:
In [2]:
import pandas as pd
Import Bokeh (do not run if you do not have Bokeh installed):
In [3]:
from bokeh.layouts import row
from bokeh.plotting import figure, show
For Jupyter Notebooks only (do not run if you are not using Bokeh and Jupyter):
In [4]:
from bokeh.io import output_notebook
output_notebook()
In [5]:
from amplpy import AMPL, Environment, DataFrame
In [6]:
ampl = AMPL()
If the AMPL installation directory is not in the system search path, you should create the AMPL object as follows instead:
ampl = AMPL(Environment('full path to the AMPL installation directory'))
Note that you may need to use raw strings (e.g., r'C:\ampl\ampl.mswin64') or escape the slashes (e.g., 'C:\\ampl\\ampl.mswin64') if the path includes backslashes.
In [7]:
ampl.setOption('solver', 'gurobi')
In [8]:
ampl.eval('''
set NUTR;
set FOOD;
param cost {FOOD} > 0;
param f_min {FOOD} >= 0;
param f_max {j in FOOD} >= f_min[j];
param n_min {NUTR} >= 0;
param n_max {i in NUTR} >= n_min[i];
param amt {NUTR,FOOD} >= 0;
var Buy {j in FOOD} >= f_min[j], <= f_max[j];
minimize Total_Cost: sum {j in FOOD} cost[j] * Buy[j];
subject to Diet {i in NUTR}:
n_min[i] <= sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i];
''')
Note: Alternatively you can read the model from a file using "ampl.read(filename)".
In [9]:
foods = ['BEEF', 'CHK', 'FISH', 'HAM', 'MCH', 'MTL', 'SPG', 'TUR']
nutrients = ['A', 'C', 'B1', 'B2', 'NA', 'CAL']
In [10]:
ampl.getSet('FOOD').setValues(foods)
ampl.getSet('NUTR').setValues(nutrients)
In [11]:
ampl.setData(DataFrame(
index=[('FOOD', foods)],
columns=[
('cost', [3.59, 2.59, 2.29, 2.89, 1.89, 1.99, 1.99, 2.49]),
('f_min', [2, 2, 2, 2, 2, 2, 2, 2]),
('f_max', [10, 10, 10, 10, 10, 10, 10, 10])
]
))
In [12]:
df = pd.DataFrame({
'n_min': [700, 700, 700, 700, 0, 16000],
'n_max': [20000, 20000, 20000, 20000, 50000, 24000]
},
index=nutrients
)
ampl.setData(DataFrame.fromPandas(df))
In [13]:
amounts = [
[ 60, 8, 8, 40, 15, 70, 25, 60],
[ 20, 0, 10, 40, 35, 30, 50, 20],
[ 10, 20, 15, 35, 15, 15, 25, 15],
[ 15, 20, 10, 10, 15, 15, 15, 10],
[928, 2180, 945, 278, 1182, 896, 1329, 1397],
[295, 770, 440, 430, 315, 400, 379, 450]
]
df = DataFrame(('NUTR', 'FOOD'), 'amt')
df.setValues({
(nutrient, food): amounts[i][j]
for i, nutrient in enumerate(nutrients)
for j, food in enumerate(foods)
})
ampl.setData(df)
In [14]:
ampl.solve()
In [15]:
ampl.getVariable('Buy').getValues().toPandas()
Out[15]:
In [16]:
totalcost = ampl.getObjective('Total_Cost')
print("Objective is:", totalcost.value())
In [17]:
cost = ampl.getParameter('cost')
cost.setValues({'BEEF': 5.01, 'HAM': 4.55})
print("Increased costs of beef and ham.")
In [18]:
ampl.solve()
In [19]:
print("New objective value:", totalcost.value())
In [20]:
Buy = ampl.getVariable('Buy')
print("Buy['BEEF'].val = {}".format(Buy['BEEF'].value()))
In [21]:
diet = ampl.getConstraint('Diet')
for nutr in nutrients:
print("Diet['{}'].dual = {}".format(nutr, diet[nutr].dual()))
In [22]:
rows = [tuple(row) for row in Buy.getValues()]
factors = [index for index, value in rows]
x = [value for index, value in rows]
dot = figure(
title="Categorical Dot Plot", tools='', toolbar_location=None,
y_range=factors, x_range=[0,12]
)
dot.segment(0, factors, x, factors, line_width=2, line_color='green')
dot.circle(x, factors, size=15, fill_color='orange', line_color='green', line_width=3)
show(dot)