Going Through Sample MPL Model File | ||
|
On this page we go through a sample MPL model file and explain it step by step. You can also see how MPL model files are structured.
{ Planning.mpl }
{ Aggregate production planning for 12 months }
Any text that appears within curly braces is a comment. Comments may be
anywhere, even inside a statement. The exclamation mark '!' is an alternative style
for comments that extend only from that point to the end of the line.
TITLE
Production_Planning;
The title is optional, but a convenient place to name the problem. After optimizing,
the title is used in the solution file to identify the problem.
INDEX
product = 1..3;
month = (January,February,March,April,May,June,July,
August,September,October,November,December) ;
In the index section the dimensions of the problem are declared. Here, we have
products number 1, 2 and 3, and the period from January to December. The vector
variables and the constraints can be conveniently specified when these dimensions
have been given, encapsulating the sizes of the dimensions to this single place of
declaration.
Notice there are two ways of defining indexes: 1) Subrange of integers as in the case of product, meaning all the integers in the given range, inclusive. Both numbers can be any non-negative integer. 2) Enumeration of items or simply a list of names like month. This is a convenient way of assigning meaning to indexes and the vectors that use them. The data section defines data vectors and single value scalars.
DATA
price[product] := (105.09, 234.00, 800.00);
In this case, price is a data vector over one dimension, the index product that has
three elements. The number of elements in the list that follows need to be at least
three to satisfy the dimension of the vector. Additional numbers are allowed and just
ignored.
Demand[month,product] := 1000 DATAFILE(demand.dat) ;
The demand vector has 36 values, 12 months times 3 products, which are stored in a
separate file, demand.dat. A datafile is a free-format textfile, where alphabetic text
is ignored and numbers are read in the order they appear. The numbers are separated
with commas or spaces and comments are allowed too.
ProductionCapacity[product] := 1000 (105, 42, 14) ;
ProductionCost[product] := (64.30,188.10,653.20) ;
InventoryCost := 8.8? ;
The number 1000 on the first line, means a constant with which all items in the list
are multiplied. Thus the actual values for the vector are (105000, 42000, 14000).
A question mark denotes an interactive value. The user is prompted at runtime to
type in a value for the InventoryCost.
DECISION
Inventory[product,month] -> Invt;
Production[product,month] -> Prod;
Sales[product,month] -> Sale;
The decision section contains declaration of the subscripted variables of the problem.
Inventory, Production and Sales all range over products and months, for a total of 36
normal decision variables for each vector variable.
The name that appears after the æ->Æ (read becomes) sign is an optional abbreviation of the vector name to combat the variable name size limitations of most LP solvers. This allows you to use long and descriptive names in your MPL model, while maintaining sufficient conciseness of terms needed in your LP package. Same abbreviations can also be given for constraint names and enumeration items. Macros are a convenient and a powerful way of naming and reusing complex expressions and parts of expressions.
MACRO
Revenues := SUM(product,month: price * Sales);
TotalCost := SUM(product,month: InventoryCost * Inventory
+ ProductionCost * Production) ;
In the example above, we have set up two macros: Revenues is the expression for the
sum of the revenues of all three products over the whole period. TotalCost is the cost
of the inventory plus cost of production over all months and all products. We can
then, in the model, refer to these sums using the macro names. This makes the model
more readable and sometimes even smaller, by eliminating unnecessary variables.
Now we come to the actual model. The keyword MODEL is optional, denoting the
end of declarations and the start of the model part.
MODEL
MAX Profit = Revenues - TotalCost ;
The first section in the model is the definition of the objective function. Which is
either to maximize MAX or minimized MIN. This function may have a name, in this
case it is Profit. Finally, we come to the formula for the objective function. In this
case, the objective is simple because of the macros used: maximize profit equal to
the difference between revenues and total cost.
SUBJECT TO
InventoryBalance[product,month] -> InvB :
Inventory = Inventory[month-1] + Production - Sales ;
The constraints of this problem are shown above. This single equation is expanded
to 36 normal constraints, one for each product and month. The intuitive meaning of
the constraint is simple: the inventory of a given month (for any product) has to
equal the previous monthÆs inventory, plus what we have produced, minus what we
have sold. For the special case of January the constraint is: inventory is equal to
production minus sales.
A constraint is specified by: constraint_declaration : formula comparison formula ;A constraint declaration consists of a name, a list of the indexes that it ranges over (unless it is a simple single constraint), and an optional abbreviation for input generation purposes. Here we have the constraint InventoryBalance which shortens to InvB, for each product and each month. The formulas of the constraint can be a combination of constants, single variables, data vectors, variable vectors and sums, with the restriction that all the indexes of a vector must be accounted for, either as a part of the constraint declaration or as part of sum indexes, or by fixing it to a given value. Note that dimensions of vectors need not be specified, but are implicit. And even if they are listed, they can be placed in any order, unless it has dimensions with a fixed value, in which case it is important to correctly recognize order. In the term Inventory[month-1], the month index has an offset value, which select the variable for the previous month. For example, the last generated constraint would look like: InvB1Dec : Invt1Dec = Invt1Nov + Prod1Dec - Sale1Dec;In the above constraint for product 1, month of December, November is used for the second inventory term. This method works for any integer offset value. Entries that fall out of bounds are ignored, thus for the January constraint the Inventory variable will be omitted. Simple upper and lower bounds on variables are specified separately, in a manner similar to constraints. They are preceded with the keyword BOUNDS.
BOUNDS
Sales <= Demand ; Production <="ProductionCapacity" ; Inventory[product,month="January..November]" <="90000" ; Inventory[product,December]="20000" ;
One side of a bound must be only a normal variable or variable vector, and the other
side a scalar constant or data vector. It is possible to specify both lower and upper
bound for variable in one single statement in the usual manner (1 These bounds illustrate a special feature; the use of subindexes. Sometimes a constraint/bound should only be given for a subrange of the originally specified index. Here, the subrange month=January..November constrains the month index within the range specified, therefore, the MaxInventory bound is not generated for December. The CloseInventory bound is similar and complementary, even if it looks different. Here we have an example of a fixed dimension, Inventory, that has the month dimension fixed to December. Alternatively, this bound could also have been entered as:
Inventory[product,month=December] = 20000;
The last sections of the model specification involve labeling some variables with
special attributes. Decision variables can be marked FREE, INTEGER or BINARY,
as a status classification for the LP solver. Here we want the production variables to
be integer variables.
INTEGER
Production
END
|
||