Advanced Features of AMPL
Advanced Features of AMPL
Cormac Lucas
Table of Contents
1 Notes
Quite often we include redundant columns and rows in the model removing them by explicitly declaring upper bounds of zero. In this section we illustrate the use of the logical expressions to implicitly handle these conditions.
The following model, taking from Williams is used to illustrate these features.
WORKSHOP Multi-Time Period Problem An engineering factory makes seven products (PROD 1 to PROD 7) on the following machines: four grinders, two vertical drills, three horizontal drills, one borer, and one planer. Each product yields a certain contribution to profit (defined as /unit) together with the unit production times (hours) required on each process are given below. A dash indicates that a product does not require a process.
Questions/Notes
2 Notes
PROD 1 Contribution to profit Grinding Vertical drilling Horizontal drilling Boring Planing 10 0.5 0.1 0.2 0.05 -
In the present month (January) and the five subsequent months certain machines will be down for maintenance. These machines will be:
1 grinder 2 horizontal drills 1 borer 1 vertical drill 1 grinder and 1 vertical drill 1 planer and 1 horizontal drill
There are marketing limitations on each product in each month. These are:
Questions/Notes
3 Notes
It is possible to store up to 100 of each product at a time at a cost of 0.5 per unit per month. There are no stocks at present but it is desired to have a stock of 50 of each type of product at the end of June.
The factory works a 6 day week with two shifts of 8 hours each day.
When and what should the factory make in order to maximise the total profit?
Recommend any price increase and the value of acquiring any new machines.
NB It may be assumed that each month consists of only 24 working days. (Williams, 1990, p247f)
Questions/Notes
Notes
Indices
i=1..5 denotes the machine types j=1..6 denotes the time periods k=1..7 denotes the products
Data
Pk unit profit contribution for product p Uk,i hours needed on machine i for a unit of product k D j k, monthly demand for each product Ni available number of machine type i Wi,j number of machine type i in maintenance time j M maximum storage of each product for all time periods S storage cost of holding one product in inventory for 1 month Gk desired closing stock of product k A hours available each month
Variables
xj,k amount of product k produced time j yj,k amount of product k sold time j zj,k amount product k held in inventory at the end of time period j
Questions/Notes
5 Notes
6 7 6 7
maximize
P y Sz
k =1 j =1 k kj k =1 j =1
jk
Subject to
U
k =1
kj
x jk A( N i Wij )
i, j
Production balance
x j ,k y j ,k + z j 1,k = z j ,k
j , k
z j ,k M z6,k = Gk y j ,k D j , k
k , j < 6 k j , k
x j ,k , y j , k , z j , k 0
j , k
set product;
Questions/Notes
Notes
param contrib{i in product}; param time {k in machine,i in product}; param number{k in machine}; param down{j in months,k in machine}; param demand{j in months,i in product}; param storecst := 0.5; param maxstore := 100; param closestck := 50; param maxhours := 6*4*2*8;
var sale{i in product, j in months : demand[j,i]>0 } >=0, <=demand[j,i] ; var prod{i in product, j in months} >=0; var store{i in product, j in months} >=0,<=maxstore;
maximize contr: sum{i in product, j in months : demand[j,i]>0} (contrib[i] * sale[i,j]) sum{i in product, j in months} (storecst*store[i,j]);
subject to cap{j in months, k in machine} : sum{i in product} time[k,i]*prod[i,j] <= maxhours*(number[k]-down[j,k]); bal11{i in product, j in months: j<>"jan" and demand[j,i]>0} : store[i,j] = store[i,prev(j)] +prod[i,j]-sale[i,j]; bal12{i in product, j in months: j<>"jan" and demand[j,i]=0} : store[i,j] = store[i,prev(j)] +prod[i,j]; bal2{i in product, j in months: j="jan"} : store[i,j] = prod[i,j]-sale[i,j]; str2{i in product, j in months: j="jun"} : store[i,j] = closestck; data;
Questions/Notes
set product := 1 2 3 4 5 6 7; set months := jan feb mar apr may jun; set machine := grind vert hori bore plan; param contrib := 1 10 26 38 44 5 11 69 7 3; param time : 1 2 3 0 4 5 6 7 :=
Notes
grind 0.5 0.7 0 vert hori bore plan 0.1 0.2 0 0.2 0
0.3 0 0
0.08 0
param number :=
param down : grind vert hori bore plan := jan 1 feb 0 mar 0 apr 0 may 1 jun 0 param demand :
Questions/Notes
0 2 0 1 1 0 1
0 0 0 0 0 1 2
0 0 1 0 0 0 3
0 0 0 0 0 1; 4 5 6 7 :=
500 1000 300 300 800 200 100 600 500 200 0 300 600 0 0 400 300 150 500 400 100 100
Notes
var store{i in product, j in months} >= (if (j="jun") then closestck else 0) , <= if j="jun" then closestck else maxstore; And we can be more efficient in the specification of the inventory balance equations as in If there is no demand and we are in January then the inventory balance constraint is
If there is demand and we are in January then the inventory balance constraint is
If there is no demand and we are in beyond January then the inventory balance constraint is
If there is demand and we are in beyond January then the inventory balance constraint is bal1{i in product, j in months} : store[i,j] = prod[i,j]+ (if j <> "jan" then store[i,prev(j)] else 0) -(if(demand[j,i] > 0) then sale[i,j] else 0);
Questions/Notes
9 Notes
Running AMPL in command line The ampl model file can be created in an editor such as notepad and saved with a name mymodel.mod. Similarly, the data file can also be edited in notepad and stored in a file called mydata.dat. Then by opening an MSDos window the problem can be solved in the following manner. Microsoft Windows 2000 [Version 5.00.2195] (C) Copyright 1985-2000 Microsoft Corp C:\Program Files\AMPL\Models>ampl License expires on (y)2005:(m)06:(d)08. OptiRisk Systems license manager: valid AMPL license found ampl: model prodplan.mod; ampl: data prodplan.dat; ampl: solve; MINOS 5.5: optimal solution found. 49 iterations, objective 81756.42857 ampl: display store; store [*,*] : jan feb mar apr may jun := 1 100 0 0 0 0 50 2 0 0 0 0 0 50 3 0 0 0 0 100 50 4 0 0 0 0 0 50 5 0 100 0 0 100 50 6 100 0 0 0 0 50 7 0 100 0 0 100 50; ampl: display prod; prod [*,*] : jan feb mar apr may jun := 1 600 0 0 200 0 550 2 788.571 0 0 300 100 550 3 300 200 0 400 600 0 4 300 0 0 500 100 350 5 800 500 0 200 1100 0 6 300 0 400 0 300 550 7 0 250 0 100 100 0; ampl: display sale; sale [*,*]
Questions/Notes
10
: 1 2 3 4 5 6 7
jan feb mar apr may jun := 500 100 0 200 . 500 788.571 0 0 300 100 500 300 200 . 400 500 50 300 . . 500 100 300 800 400 100 200 1000 50 200 100 400 . 300 500 0 150 100 100 . 50;
Notes
Useful Commands ampl: show; parameters: closestck demand maxhours number contrib down maxstore storecst sets: machine months product variables: prod sale store constraints: bal11 bal12 bal2 cap str2 objective: contr ampl: show bal2; s.t. bal2{i in product, j in months: j == 'jan'} : store[i,j] == prod[i,j] sale[i,j]; ampl: expand bal2; s.t. bal2[1,'jan']: sale[1,'jan'] - prod[1,'jan'] + store[1,'jan'] = 0; s.t. bal2[2,'jan']: sale[2,'jan'] - prod[2,'jan'] + store[2,'jan'] = 0; s.t. bal2[3,'jan']: sale[3,'jan'] - prod[3,'jan'] + store[3,'jan'] = 0; s.t. bal2[4,'jan']: sale[4,'jan'] - prod[4,'jan'] + store[4,'jan'] = 0; s.t. bal2[5,'jan']: sale[5,'jan'] - prod[5,'jan'] + store[5,'jan'] = 0;
Questions/Notes
time
11 Notes
s.t. bal2[6,'jan']: sale[6,'jan'] - prod[6,'jan'] + store[6,'jan'] = 0; s.t. bal2[7,'jan']: sale[7,'jan'] - prod[7,'jan'] + store[7,'jan'] = 0; ampl: display store >prodplan.log; ampl: display prod >>prodplan.log; ampl: exit; Estimating the Model Statistics We wish to estimate model statistics such as the number of rows, columns, bounds and non zeros of the problem. By expressing them as parameter expressions we see how easy it is to represent large problems in concise statements. For the above model we compute the statistics as follows Variable Group
sale[product,month] prod[product,month] store[product,month]
Number
Lower
Upper
Row Group
cap[month,machine] bal[product,month]
Number
Variable grp
Number
Tnonz
Now recompute the same information taking into account that there is no sales variable when demand is zero.
Questions/Notes