amplpy setup & Quick Start#
Description: amplpy setup and quick start
Tags: amplpy, example
Notebook author: Filipe Brandão <fdabrandao@gmail.com>
Model author: N/A
References: N/A
Setup#
Install from the PiPY repository:
$ 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, 3.8, and 3.9. Please make sure that you are using the latest version of pip
before installing amplpy
(upgrade using “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.
Additional packages#
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
”.
# Install dependencies
%pip install -q amplpy pandas numpy bokeh
# Google Colab & Kaggle integration
from amplpy import AMPL, ampl_notebook
ampl = ampl_notebook(
modules=["gurobi"], # modules to install
license_uuid="default", # license to use
) # instantiate AMPL object and register magics
Quick start#
Step 1: Import some packages that we will use#
Import Pandas and NumPy:
import pandas as pd
import numpy as np
Import Bokeh (do not run if you do not have Bokeh installed):
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):
from bokeh.io import output_notebook
output_notebook()
Step 2: Import the amplpy components that we will use#
from amplpy import AMPL, Environment
Step 3: Create an AMPL object#
ampl = AMPL()
ampl.eval("option version;")
option version 'AMPL Development Version 20230830 (Linux-5.15.0-1042-azure, 64-bit)\
Licensed to AMPL Community Edition License for the AMPL Model Colaboratory (https://colab.ampl.com).\
Temporary license expires 20240331.\
Using license file "/tmp/tmpti35nze0.lic".\
';
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.
Step 4: Select the solver#
ampl.set_option("solver", "gurobi")
Step 5: Define the model#
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)
”.
Step 6: Define the initial data#
foods = ["BEEF", "CHK", "FISH", "HAM", "MCH", "MTL", "SPG", "TUR"]
nutrients = ["A", "C", "B1", "B2", "NA", "CAL"]
Define AMPL sets fom python lists#
ampl.get_set("FOOD").set_values(foods)
ampl.get_set("NUTR").set_values(nutrients)
Define data using an amplpy DataFrame#
ampl.set_data(
pd.DataFrame(
{
"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],
},
index=foods,
)
)
Define data using a Pandas DataFrame#
ampl.set_data(
pd.DataFrame(
{
"n_min": [700, 700, 700, 700, 0, 16000],
"n_max": [20000, 20000, 20000, 20000, 50000, 24000],
},
index=nutrients,
)
)
Define data using a python dictionary#
ampl.get_parameter("amt").set_values(
pd.DataFrame(
np.array(
[
[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],
]
),
columns=foods,
index=nutrients,
)
)
Step 7: Solve the model#
ampl.solve()
Gurobi 10.0.2: Gurobi 10.0.2: optimal solution; objective 119.9897589
5 simplex iterations
Step 8: Create a Pandas DataFrame with the values of the variable ‘Buy’#
ampl.get_variable("Buy").to_pandas()
Buy.val | |
---|---|
BEEF | 5.226933 |
CHK | 2.000000 |
FISH | 2.000000 |
HAM | 10.000000 |
MCH | 10.000000 |
MTL | 10.000000 |
SPG | 9.439734 |
TUR | 2.000000 |
Step 9: Display the objective value#
totalcost = ampl.get_objective("Total_Cost")
print("Objective is:", totalcost.value())
Objective is: 119.98975893599335
Step 10: Increase the costs of beef and ham#
cost = ampl.get_parameter("cost")
cost.set_values({"BEEF": 5.01, "HAM": 4.55})
print("Increased costs of beef and ham.")
Increased costs of beef and ham.
Step 11: Solve the model with the new costs#
ampl.solve()
Gurobi 10.0.2: Gurobi 10.0.2: optimal solution; objective 144.0120033
0 simplex iterations
Step 12: Display the new objective value#
print("New objective value:", totalcost.value())
New objective value: 144.01200332502077
Step 13: Display the value of Buy[‘BEEF’]#
Buy = ampl.get_variable("Buy")
print("Buy['BEEF'].val = {}".format(Buy["BEEF"].value()))
Buy['BEEF'].val = 5.226932668329175
Step 14: Display the dual value of each diet constraint#
diet = ampl.get_constraint("Diet")
for nutr in nutrients:
print("Diet['{}'].dual = {}".format(nutr, diet[nutr].dual()))
Diet['A'].dual = 0.0
Diet['C'].dual = 0.0
Diet['B1'].dual = 0.0
Diet['B2'].dual = 0.7999285120532004
Diet['NA'].dual = -0.007531172069825437
Diet['CAL'].dual = 0.0
Step 15: Display the values of the variable ‘Buy’ using Bokeh#
rows = [tuple(row) for row in Buy.get_values()]
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)