AMPL An Introduction
Outline AMPL - What is it (good for)? Basics Starting a Problem Running the Problem Example
Outline (Continued) Two File Format Why Use a Data File? All About Sets Example (single file) Example with data file Logical Operators
Outline (A little More) Set Operations Set Indexing Syntax Where to get AMPL
AMPL What is it (good for)?
AMPL is: A Mathematical Programming Language Supports over 30 solvers Only need to know syntax for AMPL to use many different solvers
AMPL does: Solves LP’s Solves IP’s Solves MIP’s, and non-linear programs
Basics Files you will need How to write them How to save them
Writing the.mod file Open up a non-contextual text editor (e.g. GNU Emacs, OxEdit, or textedit), type the model, save with file extension “.mod”
Syntax of File AMPL is a computer language, so it doesn’t understand what you mean Because of this, there is a particular format that AMPL files must have to run properly The format is fairly straightforward Here’s how it goes:
Order of entry Enter the variables first, e.g.: var x1 >=0; var Sally >=4.5; var smileyface <=-1; var happy integer >=0; Everything has to be identified before you use it, so AMPL knows it is there to use
Order of Entry- Cont. Next enter the objective: maximize OBJ: 3*x1 - happy + 2*Sally; minimize COST: 3*x3 + 2*x1 - Sally; maximize WHOCARES: 0;
A Quick Note: AMPL is case sensitive, so “SALLY”, “Sally”, and “sally” are three different names for variables. If something isn’t working correctly, a case error is an easy thing to identify and fix.
Order of Entry - Cont. Next enter the constraints: subject to WOOD: 2*x1 - 40*happy<=27; subject to WORK: x *Sally<=34; subject to MACHINE: happy - Sally<=14;
Put it all together: var x1 >=0; var Sally >=4.5; var smileyface <=-1; var happy integer >=0; maximize OBJ: 3*x1 - happy + 2*Sally + 4.5*smileyface; subject to WOOD: 2*x1 - 40*happy<=27; subject to WORK: x *Sally<=34; subject to MACHINE: happy - 3*smileyface<=14;
Running the File Once you have the file written and saved, we need to run it to get our solution.
How to Run AMPL Open up AMPL Tell AMPL what you want solved by: “model \project1.mod;” If the file is in AMPL’s search path, you may be able to just enter “model FILENAME.mod;” If you want to use a different solver: “option solver ;” Tell AMPL to solve it: “solve;”
Subject to Semicolons You may have noticed all the semicolons running around the file we put together, and in the commands to run the model. These tell AMPL where to separate lines, and things will not work properly without them. For instance, if you typed “solve” rather than “solve;”, AMPL would return a prompt that looks like this “ampl?”
Getting the variables This will only give you the optimal value, if it exists. How do you know the variable values that give this objective? Tell AMPL to give them to you: “display x1,x3,Sally,happy,smileyface;” This will display the variable values Remember, AMPL is case sensitive.
Put it all together ampl: model data\ampl1.mod; ampl: option solver cplex; ampl: solve; CPLEX 8.0.0, optimal integral solution found, objective value 712.2, 0 MIP iterations, 0 branch and bound nodes display x1,x3,Sally,smileyface,happy; x1 = 0 x3 = -1 Sally = happy = 11 smileyface = 0
The.dat File AMPL supports using a separate file for the particular data The.dat file holds the values for the parameters, and the names of the variables
Why Use 2 Files? You may want to do similar problems You may need to modify the data, but not the model It makes finding and changing parameters easy It makes adding or removing variables easy
All About Sets AMPL lets you define sets in the model by declaring them: set SETNAME Once a set is declared, you can index parameters over it: param PARAMETER {i in SETNAME} Alternatively: param PARAMETER {SETNAME} You can even index variables over sets: var VARIABLE {i in SETNAME} Also, you can use summation notation: sum {i in SETNAME} VARIABLE[i]*PARAMETER[i]
A (Relatively) Simple Example Suppose there is a steel mill that can process raw steel into two products, bands and coils. The manager of the mill wants to maximize his profit, given the restrictions on processing time available, and the limitations on how much he can realistically sell of each Bands can be processed at 200 tons per hour, at a profit of $25 per ton, and at most 6000 tons can be sold Coils are processed at 140 tons per hour, at a profit of $30 per ton, with a market cap of 4000 tons There are 40 hours available per week to process the steel
The old way Without using sets or a.dat file, the model would look something like this: var Bands; var Coils; maximize Profit: 25 * Bands + 30 * Coils; subject to Time: (1/200)*Bands + (1/140)*Coils <= 40; subject to B_Limit: 0 <= Bands <= 6000; subject to C_Limit: 0 <= Coils <= 4000;
The New Way Alternatively, we could split this into a.mod file and a.dat file:
steel.mod set Products; param rate {i in Products}; param profit {i in Products}; param market {i in Products}; param hours; var X {i in Products}; maximize Total_Profit: sum {i in Products} X[i] * profit[i]; subject to Time: sum {i in Products} X[i]/rate[i]<=hours; subject to Market {i in Products}: 0<= X[i] <= market[i];
steel.dat set Products := bands coils; param: ratemarketprofit := bands coils ; param hours := 40;
WHY???? Right now, it looks like the old way is easier, right? What if we want to add a new product, rods? In the old way, we would need to find every place that something might change and alter it individually In the new way, we just have to change the.dat file
The Old Way, Updated var Bands; var Coils; var Rods; maximize Profit: 25 * Bands + 30 * Coils + 28 * Rods; subject to Time: (1/200)*Bands + (1/140)*Coils + (1/160)*Rods <= 40; subject to B_Limit: 0 <= Bands <= 6000; subject to C_Limit: 0 <= Coils <= 4000; subject to R_Limit: 0<= Rods <= 5000;
Or, just change steel.dat set Products := bands coils rods; param: ratemarketprofit := bands coils rods ; param hours := 40;
Also… If you are dealing with large models, the.mod file can get REALLY big without a.dat file Changing the problem becomes very easy with a.dat file
Logical Operators AMPL supports some logical operators Boolean variables (true/false) If-then If-then-else
How to Use if-then-else Suppose all variables, except one, have the same upper bound, and the other has an upper bound that is twice that of the rest A constraint like this will take care of all the the upper bounds: subject to UB {i in SETNAME }: variable[i] <= 10*(if i=1 then 2 else 1);
Set Operations Basic set operations: –Union: U = A union B –Intersection: U = A inter B –Cartesian Product: U = {A,B}
Advantage of Set Operations Suppose we have 3 sets of products, –CANDY –TOYS –GAMES In our model we may need to declare the following parameters for each: –Price –Supply –Demand
Naïve Setup –Param Price_C {CANDY}; –Param Price_T {TOYS}; –Param Price_G {GAMES}; –Param Supply_C {CANDY}; –Param Supply_T {TOYS}; –Param Supply_G {GAMES}; –Param Demand_C {CANDY}; –Param Demand_T {TOYS}; –Param Demand_G {GAMES};
Using Set Operation Union Param Price {CANDY union TOYS union GAMES}; Param Supply {CANDY union TOYS union GAMES}; Param Demand {CANDY union TOYS union GAMES};
Even Better… Set PRODUCTS = CANDY union TOYS union GAMES; Param Price {PRODUCTS}; Param Supply {PRODUCTS}; Param Demand {PRODUCTS};
Compound Sets Suppose you have a set called PRODUCTS of products to sell at a store Consider that instead of one store you have three stores in different parts of the country Each store has a different level of each paramater
One Solution Instead of using the set PRODUCTS, make three different sets: –PRODUCTS_1 –PRODUCTS_2 –PRODUCTS_3 Let each of the three numbers represent one of your store locations
One Solution (cont…) Next, define each parameter for each set of products: –Param Price {PRODUCTS_1}; –Param Supply {PRODUCTS_1}; –Param Demand {PRODUCTS_1}; –Param Price {PRODUCTS_2}; –Param Supply {PRODUCTS_2}; –…
Easier Solution For a better solution use compound sets: –Param Price {PRODUCTS, STORES}; –Param Supply {PRODUCTS, STORES}; –Param Demand {PRODUCTS, STORES};
Structure of {PRODUCTS, STORES} Suppose –PRODUCTS := oreos jenga lazertag ; –STORES:= ; Then {PRODUCTS, STORES} is the set of all combinations of products with stores: (oreos,1)(oreos,2)(oreos,3) (jenga,1) (jenga,2) (jenga,3) (lazertag,1) (lazertag,2) (lazertag,3)
Specifying Data In your.dat file, your declaration of Demand could look like this: param Demand:123:= oreos jenga lazertag403022;
Set Indexing
Indexing of Sets Indexing of a one dimensional set sum {i in PRODUCTS} cost[i]*make[i]; Indexing is similar in compound sets One can say sum { (i,j) in {PRODUCTS, STORES}} cost[i]*make[i,j]; or sum { i in PRODUCTS, j in STORES} cost[i]*make[i,j];
When do we need indexing? We may declare a parameter with or without giving index values: param Demand { PRODUCTS, STORES }; or param Demand { i in PRODUCTS, j in STORES };
With PRODUCTS and STORES: “The sales at each store will not exceed the demand for any given product at that store.” Could be expressed as the following constraint: subject to DEMAND {(i,j) in {PRODUCTS, STORES}}: Demand [i,j] >= Sell [i,j];
With PRODUCTS and STORES: Suppose we have another parameter: Param Capacity {STORES}; Let the capacity of a store be the total number of items it can sell all together
With PRODUCTS and STORES: “The total sales at any given store can not exceed the sales capacity of that store.” Could be expressed as follows Subject to CAPACITY {j in STORES}: Sum {i in PRODUCTS} Sell [i, j] <= Capacity [j];
Advanced Syntax Tips and Shortcuts
Transposition
How to Transpose Recall an earlier example: Param Demand:123:= oreos jenga lazertag403022;
How to Transpose Data in Transposed form Param Demand (tr): oreos jenga lazertag:= ;
Why Transpose Not Necessary, but can help with data management What if we had 30 stores? Param Demand (tr): oreos jenga lazertag:= ;
Omitted Data
Omitted Data Entry Example: Consider the following data Param:Cost Supply Demand := oreos jenga lazertag403022;
Omitted Data Entry Suppose in addition to the data specified in the previous table, you have an additional parameter such as: Param Calories {FOOD}; This parameter would apply to oreos, but not to jenga or lazertag.
Example Param:Cost Supply Demand := oreos jenga lazertag403022; Param: Calories := oreos 100 ;
Example Param:Cost Supply Demand Calories:= oreos jenga lazertag ; We can use “.” to represent omitted data
Where to get AMPL –Link to the web interface –Download the student edition For Windows, it is an easy installation For Mac OS, use unix install. You may need to install additional components Walkthrough available at: – b3/amplInstallingUsing.pdf