MPL ProgrammingLanguage MathematicalOptimizationModeling
MPL ProgrammingLanguage MathematicalOptimizationModeling
PART I - INTRODUCTION
CHAPTER 1 INTRODUCTION
APPENDICES
APPENDIX A: CHARACTER SET
Chapter 1. Introduction
Optimization is today one of the most important tools in implementing and planning efficient operations
and increasing competitive advantage. Organizations need to make intelligent decisions to obtain optimal
use of their available resources, such as manpower, equipment, raw materials and capital. The discipline
of optimization, through the use of advanced mathematics and computer science techniques, can be used
to assist organizations with solving their complex business problems in areas such as manufacturing,
distribution, finance, and scheduling. Typically, these optimization problems contain hundreds,
thousands, or even millions of interconnected variables and require an advanced set of software tools to
solve.
Today, the field of optimization entails highly advanced software applications that integrate sophisticated
mathematical algorithms and modeling techniques with intelligent software programming and data
processing capabilities.
Optimization projects begin with the development of a mathematical model that defines the business
problem. Individual business decisions are represented as "variables," and the connections between them
are represented by a series of mathematical equations termed "constraints". The "objective" represents
the goal of the business problem, for example, to maximize profitability or lower costs. Identifying the
variables, the constraints and the objective is known as the "modeling" process and is an essential task
for every optimization project. After the model has been formulated, it is then solved, using an
optimization solver, which, at its core, has highly sophisticated algorithms adept at intelligently sorting
through huge amounts of data and analyzing possible approaches to come up with an optimal solution.
clear, concise, and efficient way. Models developed in MPL can then be solved with any of the multiple
commercial optimizers available on the market today.
MPL includes an algebraic modeling language that allows the model developer to create optimization
models using algebraic equations. The model is used as a basis to generate a mathematical matrix that
can be relayed directly into the optimization solver. This is all done in the background so that the model
developer only needs to focus on formulating the model. Algebraic modeling languages, such as MPL,
have proven themselves over the years to be the most efficient method of developing and maintaining
optimization models because they are easier to learn, quicker to formulate and require less programming.
MPL offers a feature-rich model development environment that takes full advantage of the graphical
user interface in Microsoft Windows, making MPL a valuable tool for developing optimization models.
MPL can import data directly from databases or spreadsheets. Once the model has been solved, MPL
also has the ability to export the solution back into the database. MPL models can be embedded into
other Windows applications, including databases and spreadsheets, which makes MPL ideal for creating
end-user applications.
The main purpose of a modeling language is to retrieve data from a structured data source, such as a
database, and generate a matrix that the optimization solver can handle. For large optimization models,
this matrix generation requires a modeling language with highly advanced capabilities, such as sparse
indexing and database management, as well as high scalability and speed. Many details need to be taken
into account when choosing a modeling language for optimization projects:
● Database Connections
● Connection to Solvers
MPL was designed to support multiple platforms. MPL for Windows is the most popular platform but
an OSF Motif version is also available for various UNIX flavors including HP 9000, IBM RS-6000, Sun
Sparc, Silicon Graphics and Linux. MPL models are portable so a model created for one platform can
always be read on any other supported platform.
This new release, offers the highest performance of modeling languages on the market today. Since we
are constantly working on new releases of MPL, please contact Maximal Software for updated
information.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
MPL includes an algebraic modeling language that allows the model developer to create optimization
models using algebraic equations. The model is used as a basis to generate a mathematical matrix that
can be relayed directly into the optimization solver. This is all done in the background so that the model
developer only needs to focus on formulating the model. Algebraic modeling languages, such as MPL,
have proven themselves over the years to be the most efficient method of developing and maintaining
optimization models because they are easier to learn, quicker to formulate and require less programming.
MPL offers a feature-rich model development environment that takes full advantage of the graphical
user interface in Microsoft Windows, making MPL a valuable tool for developing optimization models.
MPL can import data directly from databases or spreadsheets. Once the model has been solved, MPL
also has the ability to export the solution back into the database. MPL models can be embedded into
other Windows applications, including databases and spreadsheets, which makes MPL ideal for creating
end-user applications.
The main purpose of a modeling language is to retrieve data from a structured data source, such as a
database, and generate a matrix that the optimization solver can handle. For large optimization models,
this matrix generation requires a modeling language with highly advanced capabilities, such as sparse
indexing and database management, as well as high scalability and speed. Many details need to be taken
into account when choosing a modeling language for optimization projects:
● Database Connections
● Connection to Solvers
MPL was designed to support multiple platforms. MPL for Windows is the most popular platform but
an OSF Motif version is also available for various UNIX flavors including HP 9000, IBM RS-6000, Sun
Sparc, Silicon Graphics and Linux. MPL models are portable so a model created for one platform can
always be read on any other supported platform.
Release 4.2 is the newest version of MPL. This new release, offers the highest performance of modeling
languages on the market today. Since we are constantly working on new releases of MPL, please contact
Maximal Software for updated information.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
● Direct link to Windows DLL solvers. MPL can set up the matrix and then send it to the solver
directly through memory. Solvers that are supported in MPL as Windows DLL include, CPLEX,
XPRESS, OSL, XA, CONOPT, LSGRG2, and FrontMP. MPL can also handle legacy DOS
solvers through a DOS window.
● Database Connection. MPL can import both indexes and data directly from a database. After the
model has been solved, MPL can also export the solution back to the database. Furthermore,
MPL can easily be called directly from other Windows applications, including databases.
Supported databases include Access, Paradox, FoxPro, and Dbase and any ODBC compatible
database.
● Manage models through projects. If you are using MPL to work on multiple models, that use
different files and option settings, you can use projects to manage the models. Projects are used to
store information about items such as, open model files and windows, the default working
directory, and current option settings.
● Model Definitions window. MPL allows you to view defined items from the model formulation
in an easy to browse tree window. You can expand and collapse each branch to show only the
elements you are interested in. You can display the contents for each item, such as elements for an
index or solution values for a variable, simply by selecting it in the tree.
● Message window. While MPL is running it can send various progress information to a message
window. What is displayed is selected by the user and can include status window messages, MPL
input lines, performance statistics, warning messages, SQL statements, and iteration log
information from the solver.
● Context sensitive help. MPL supports Windows context sensitive help for dialog boxes. To
display the help, simply select the question mark button in the upper right corner of the dialog box
and then click on the item you want help for. A small window will popup with a short explanation
of the item you selected.
● Multiple input formats. In addition to the modeling language, MPL can read multiple other input
formats, including MPS. MPS files and native input formats for solvers such as CPLEX. MPL
will automatically detect the format, when reading the input file, and switch to the correct
language. MPL can also be used to generate several different solver input formats. This ensures
that models created in MPL can be solved with nearly all industrial strength optimization
packages available on the market today.
● Helpful error messages. MPL makes it easy to correct mistakes in your formulation. An error
window pops up containing the erroneous line in the model file where the error is described in
plain English. After you have read the message, the program automatically locates the line in the
model file and moves the cursor to it.
● Meaningful names. You can use meaningful names of any length for variables and constraints,
so the formulation is easy to read and understand. You can also, for additional clarity, use
explanations and general comments throughout the model file.
● Free format constraints. With MPL you can write variables and constants on both sides of the
constraints. This means that you do not have to convert the constraints to a standard format before
entering them.
● Arithmetic in the input. You can use fractions, products, percentages, and mathematical
functions in the model file. This flexibility not only allows clearer formulation, but also
automatically results in the highest possible accuracy. Full use of parentheses is also allowed.
● Separation of data from the model. With MPL you can read in data from external data files in
both sparse and dense data formats. The data files can be created either using the text editor in
MPL or be exported from other programs such as spreadsheets and databases. For example, to
read in data file containing a price list you would simply enter:
price[product] := datafile(price.dat);
● Data entered at run-time. Named data constants can be given a value interactively at run-time.
You are prompted for the value when the model file is read. This feature can be very useful when
you want to run the same model several times with different data values.
● Summation over vector variables. In MPL you can work with vector variables of up to eight
dimensions concisely and effectively. For example, to add the produc-tion cost for all months and
products, you simply type:
InventoryBalance[month=Jan..Dec] :
Inventory = Inventory[month-1] + Production - Sales;
● Macro definitions. Macro definitions in MPL allow you to define a part of a constraint or
formula that is frequently used as a macro. You can then refer to it in the model by entering just
the macro name. In some cases macros can be used to eliminate unnecessary equality constraints
and thereby reduce the size of the problem for the solver.
● Include files. MPL allows you to include external files to the model formulation, using a simple
include command. Include files can also be a great advantage when you want to solve a number of
closely related models containing common data or model statements.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Email: [email protected]
Web: www.maximalsoftware.com
Email: [email protected]
Web: www.maximalsoftware.co.uk
MPL is continually evolving in order to bring you the most current and advanced techniques available.
Your input is a helpful component in shaping our focus and direction and is greatly appreciated.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
● System Requirements shows you the hardware and operating system requirements for using the
MPL software.
● Installing MPL for Windows gives information about installing MPL and what files are contained
on your MPL distribution diskette.
● Setting Up Solvers gives information about changing which solvers are available in the Run menu
in MPL and all solvers that are supported by the current version of MPL.
● Using the MPL Environment gives you a short overview on how to run the program.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
To install MPL for Windows place the first MPL installation disk in drive A:. From Start menu choose the Run
command. Type a:\setup and click OK. The installation program will ask a number of simple questions such as
where to install the software and then copy the files to the hard disk on your machine. It will create entries for MPL
in the Start menu.
The files on the distribution diskette for MPL are copied to the hard disk as follows:
Mplwin4 directory:
Windows directory:
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
After you have installed the solver, you can change which solvers are available in the Run menu by
choosing Solver Menu from the Options menu. This will display the Solver Menu Setup dialog box. The
list box shows the solvers that are supported by the current version of MPL.
To let MPL search your hard disk for supported solvers, press the Scan button. This option can be
especially useful when you are not sure where on the hard disk solvers have been installed and you want
MPL to locate them automatically and set them up.
You can select manually which solvers should be in the Run menu. Double-click on a solver name to
either add or remove it from the menu. Those solvers that are currently in the menu have the word
‘Menu’ listed in the second column.
If you need to change some of the setup options for a solver, such as the filename or the location, select
the solver in the list box and then press the Edit button. This will display the Solver Setup Options dialog
box. For further information on how to setup solvers for MPL refer to the sections on Setup Solvers for
the Run Menu and Change Setup Options for Solvers in Chapter 4.9 The Options Menu.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
To start working on your model choose from the File menu either New to create new model or Open to edit an existing model. To save your model use either Save
or Save As from the File menu.
After you have worked on your model in the editor choose Solve <solvername> from the Run menu to solve the model.
While optimizing, MPL displays a status window that gives you information on the solution progress. When the model has been solved, the solution is written to a
solution file. You can use options from the View menu to display various parts of the solution. You can also use the Graph menu to display a graph of the matrix or
the objective function.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
To start working on your model choose from the File menu either New to create new model or Open to
edit an existing model. To save your model use either Save or Save As from the File menu.
After you have worked on your model in the editor choose Solve <solvername> from the Run menu to
solve the model.
While optimizing, MPL displays a status window that gives you information on the solution progress.
When the model has been solved, the solution is written to a solution file. You can use options from the
View menu to display various parts of the solution. You can also use the Graph menu to display a graph
of the matrix and of the objective function.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The model developer uses the built-in model editor to formulate the model in MPL and then select the
optimizer directly from the menus to solve the model. The solution results are automatically retrieved
from the solver and the displayed, providing the usesr with instant feedback. Each item defined in the
model is also displayed in a tree window allowing the model developer to browse through them easily.
The MPL Modeling System connects to solvers dynamically through memory at run-time. This gives
MPL the capablity to integrate the solver completely into the modeling environment, resulting in the
matrix being transferred between the modeling system and the solver directtly through memory. As no
files are involved, this seamless connection is both considerably faster and more robust than the
traditional use of files in other modeling systems. In the event that it is necessary to change any
algorithmic options, MPL provides easy-to-use option dialog boxes for each solver.
This chapter describes the process of running MPL in detail. It contains these sections:
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The installation program for MPL created an entry in the Start menu under Programs | MPL for Windows. To
access it click the Start button from the task bar that appears along the bottom of the Windows screen. The MPL
for Windows start menu entry is shown here in Figure 3.1:
You can create a shortcut for MPL by clicking on the right mouse button anywhere on the desktop. You will be
presented with a pop-up menu where you choose New and then Shortcut. This will start the Create Shortcut
Wizard. In the input box enter the full path for the MPL program. If you do not know the path you can press the
Browse button to locate MPL in your system. After entering the path, press Next to continue. In the next window
enter the name of the shortcut and then press Finish. The new shortcut will now be created on the desktop.
You can also set MPL up so it will automatically open a specific model file when starting. There is an example
of this in Figure 3.1 where you can see the MPL icon with the caption 'Planning.mpl'. To see how this is set up,
create a shortcut for MPL on the desktop and then use the right mouse button to choose properties for it. This
will bring up the Properties dialog box. Select the Shortcut tab and in the Target input box enter the following:
c:\mplwin4\mplwin42.exe planning.mpl
By giving the name of the model file 'planning.mpl' as an argument after the program name on the command line,
MPL will automatically open the file when it is started. To create another icon that opens a different file, first
duplicate the icon by dragging it with the right mouse button and select Copy Here. Then you can change the
name of the model file in the command line by going again into the Properties dialog box.
MPL was not only designed to help the model developer to create optimization models, but also to make it easy
to delpoy the model by embedding it into business applications. With the introduction of the Optimax 200
Component Library, MPL models can now be easily embedded into end-user applications such as Excel and
Access from Microsoft Office, using programming languages such as Visual Basic and C++. This allows model
developers whose expertise lies in developing models, to effectively work with and deliver models to the IT
professionals who can then focus on working in databases and building graphical user interfaces and end-user
applications. Please contact Maximal for more details on the OptiMax 2000 Component Library.
MPL can be run directly from other windows applications in run-time mode. This will let MPL solve a model
from the other application without entering the integrated modeling system. MPL is run in run-time mode by
entering the command SOLVE to the command line before the name of the model.
This will direct MPL to read the model file that follows and solve the model directly. You can also ask MPL to
generate an input file, such as MPS, in run-time mode, by entering the command GENERATE to the command
line followed by the MPS filename.
This will direct MPL to read the model file, with the filename that follows, using the extension ‘.mpl’ and then
generate the input file you requested. MPL will determine which type of input file to generate from the file
extension used.
Many end-user applications for Windows, such as databases and spreadsheets, have a macro language that lets
you execute other programs from a command line. This allows you to use the application as a front-end that
handles the data entry and management tasks for your project and then call MPL directly from the application to
solve the model. Then, using the database features of MPL, you can create an application around your model
where the end-user never has to know how to use MPL.
The way you can call MPL from other applications depends on which software you are using. The most common
applications that are used include Visual Basic, C/C++, and databases such as MS Access. In most cases this is
accomplished by making a Win32 call to CreateProcess. Other programs will possibly have functions like
WinExec or Shell. In many cases, you will want your calling application to wait until MPL and the solver are
finished before continuing. Here is an example of a WinExecWait function that will first call CreateProcess and
then use the Win32 function WaitForSingleObject.
StartupInfo.cb = sizeof(STARTUPINFO);
Result = CreateProcess(NULL,CommandLine,NULL,NULL,FALSE,0,NULL,NULL,
&StartupInfo,&ProcessInfo);
if (!Result)
return WE_SOMEERROR;
else {
CloseHandle(ProcessInfo.hThread);
if (WaitForSingleObject(ProcessInfo.hProcess, INFINITE) !=
WAIT_FAILED) {
GetExitCodeProcess(ProcessInfo.hProcess,&dwExitCode);
}
CloseHandle(ProcessInfo.hProcess);
return WE_RANOK;
}
}
This WinExecWait function can now be called using a command line that runs MPL in the run-time mode. For
example:
Visual Basic supports a Shell function that allows you to run external programs, such as MPL, but it does not
wait for the program to finish. If you need a function that waits until MPL finishes, Visual Basic supports Win32
function calls and, therefore, will be very similar to the above example. Please contact Maximal Software if you
need sample copy of WinExecWait for Visual Basic.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
When you start MPL in stand-alone mode the main window appears. The main window consists of the title bar at the top, the
main menu, the toolbar, the work area, and the status line at the bottom.
The main menu in MPL offers the following menus and functions:
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The following is a quick overview on how to work in MPL and what you can do with each menu.
To start working on your model go to the File menu and choose either New to create a new model or
Open to edit an existing model file. When you have finished editing the model you can save it using
either Save or Save As from the File menu.
You can use the Cut and the Copy command from the Edit menu to copy block of text to the clipboard
and then the Paste command to place it elsewhere in your model. If you make a mistake while entering
your model you can use the Undo command from the Edit menu to correct it.
If you need to search for a text string in your model, you can use the Find command from the Search
menu or if you need to replace the text with an another text string use the Replace command.
If you are using MPL to work on multiple models, that use different files and option settings, it may be
beneficial to use Projects to manage the models. Projects are used to store information about open model
files and windows, the default working directory, and all the current option settings. The Project menu is
used to create new projects, and then open, save or close different project files.
After you have created your model in the editor choose Solve <solvername> from the Run menu to
optimize the model. While optimizing, MPL displays a status window that gives you information on the
solution progress. When the model has been solved, the solution is written to a solution file.
After the solver is finished optimizing the problem, you can use options from the View menu to display
various parts of the solution. You can also use the Graph menu to display a graph of the matrix and of
the objective function.
The Options menu allows you to change various default settings for MPL, including which solvers you
have, native solver options, contents of the solution file and other preferences.
The Windows menu is used to either tile or cascade the currently open windows, arrange at the bottom
minimized windows, and select from a list of open windows, the window you want to bring to the front.
Through the Help menu you can access the context sensitive on-line help system which has multiple
screens containing useful reference information. While you are running MPL you can also enter the help
system by pressing the F1 key.
We will now explain the Status Window and the MPL Error Message Window that are used while while
you are reading and solving your models.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Also, notice that some of the commands in the menus have an ellipsis '...' after them, indicating that you
have to supply more information in a dialog box before MPL can carry out the command.
Some of the menu items are followed by a Ctrl-key entry. These Ctrl-key combinations are there to
provide the user with a short-cut. Instead of pulling down menus and choosing the commands, you can
just press Ctrl and the appropriate key at the same time.
This chapter provides a reference to all the menu items available in MPL
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
In the following pages, each menu item will now be described in full detail.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The File menu is used to open, save, and print model files. To access the File menu, simply point at the
word File in the main menu and hold down the mouse button. The menu appears as shown here in Figure
4.1.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The Edit menu is used to cut, copy, and paste with the clipboard and to undo changes you have made to
your model file.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The Search menu is used to find and replace text, and go to a specific line in the model file.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The Project menu is used to open, save, and close projects. To access the Project menu, simply point at
the word Project in the main menu and hold down the mouse button. The menu appears as shown here in
Figure 4.14
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The Run menu is used when you want to solve the model, check the syntax, and generate input files.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The View menu is used after you have solved your model to view generated files and various parts of the solution
in a window. You can also get problem statistics and defined items in the model.
The view window stores the file in memory allowing you to quickly browse through the solution on screen using
the mouse. You can have multiple view windows open at the same time. The view window can handle very large
solution files, up to several megabytes, depending on how much memory you have available on your machine. If
the solution file becomes too large, you can change the contents of the file. Please refer to the Change Solution
File Options section in Chapter 4.9: The Options Menu for more information.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The Graph menu is used when you want to display a graph of the matrix or of the objective function
values for each iteration.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The Options menu allows you to change various options for the solvers, the solution file, and for MPL.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
To divide the main window equally between open windows, choose Tile from the Window menu. To
cascade or stack all open windows on top of each others so that you can see the title of each window
choose Cascade from the Window menu.
To arrange at the bottom all the windows that have been minimized down to an icon, choose Arrange
Icons from the Window menu.
To close all editor, view, and graph windows that are open, choose Close all from the Window menu.
MPL keeps a list of all open windows in the window menu that can be used to quickly search for and
switch between windows.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The Help menu is used when you need to access the MPL Help System. You can also use the shortcut
F1 to access the help system.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The MPL modeling language offers a natural algebraic notation that enables the model developer to
formulate complex optimization models in a concise, easy-to-read manner. Among modeling languages,
MPL is unrivaled in its expressive power, readability, and user-friendliness. The MPL modeling
language was designed to be very easy to use with a clear syntax making the process of formulating
models in MPL efficient and productive. MPL is a flexible language and can be used to formulate
models in many different areas of optimization ranging from production planning, scheduling, finance,
and distribution, to full-scale supply-chain optimization.
MPL is a very robust and stable software whose core modules have been through extensive use and
testing over more than a decade. This assures that the MPL software is both reliable and dependable and
can be used in mission-critical projects. Some of the more notable features of the MPL language include:
One of the most important features of any modeling language is how it handles large amounts of data.
What makes MPL so powerful is its ability to effectively handle very large sparse index and data sets. In
addition, MPL has extensive flexibility when working with subsets of indexes, functions of indexes, and
compound or multi-dimensional index sets. This allows the model formulator, for example, to index only
over products that are made by each machine in a specific plant instead of having to go through all the
products for all the machines and all the plants, which would be considerable slower.
MPL can easily handle very large matrices with millions of variables and constraints. This is especially
important when dealing with large supply-chain optimization models over multiple time periods that can
grow very quickly. MPL has its own memory manager that can dynamically store models of any size,
giving it a full scalability. The only limitation the model developer faces is how much memory is
available on his or her machine. Typically, MPL uses only a few megabytes of memory per 10,000
variables, which puts a minimal additional burden on the machine capacity needed to generate and solve
the model.
The matrix generation in MPL is extremely fast and efficient which is important since it contributes to
the overall time needed to obtain the solution of the model. Maximal has over the years invested
significant R&D efforts on continuing to improve the speed of the matrix generation. As a result, MPL
can now run models with millions of variables and generate a matrix for them in less than one minute.
This is very important, because if the model generation takes too long it can seriously add to the time
needed to reach the solution even if the fastest optimization solvers are used. MPL provides the fastest
and most scalable model generation capabilities available in a modeling system on the market today.
The MPL modeling language was developed with one key goal in mind; the input must resemble the
notation people use to write their problem formulations on paper as closely as possible. In order to
achieve that goal, advanced compiler and language parsing techniques normally reserved for writing high-
level computer languages were used. The resulting language includes many features that can be of great
assistance when formulating optimization models.
The MPL modeling language was developed with one key goal in mind; the input must resemble the
notation people use to write their problem formulations on paper as closely as possible. In order to
achieve that goal, advanced compiler and language parsing techniques normally reserved for writing high-
level computer languages were used. The resulting language includes many features that can be of great
assistance when formulating optimization models
The input to MPL is a file that contains the model formulation. This file is a standard ASCII text file and
can be created using the built-in model editor in MPL. Any text editor capable of working with text files
can also be used.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The MPL model file is divided into two main parts; the definition and the model. In the definition part
you define various items that are then used throughout the model. The model part, on the other hand,
contains the actual model formulation. Each part is further divided into sections, which are as follows:
MODEL
MAX or MIN - The objective function.
SUBJECT TO - The constraints.
BOUNDS - Simple upper and lower bounds.
FREE - Free variables.
INTEGER - Integer variables.
BINARY - Binary (0/1) variables.
END
None of the sections are actually required in MPL, but in order to have a valid optimization model you
will need at least the objective function and the constraints. MPL allows you to place the sections in any
order, but since any item must be declared before it is used in the model, the above order is used most of
the time. Multiple entries of each section are allowed. The keywords MODEL, SUBJECT TO and END
are optional, but used most of the time to aid readability. As an example of how simple the model in
MPL can be, here is one tiny but still perfectly legal input:
MAX x + y ;
x + 2y < 10 ;
In this chapter each of the aforementioned sections is explained in full detail. On the next page is the
MPL model file 'planning.mpl' that we will use as an example.
{ Planning.mpl }
TITLE
Production_Planning;
INDEX
product = 1..3;
month = (January,February,March,April,May,June,July,
August,September,October,November,December);
DATA
price[product] := (105.09, 234.00, 800.00);
Demand[month,product] := 1000 DATAFILE(demand.dat);
ProductionCapacity[product] := 1000 (10, 42, 14);
ProductionCost[product] := (64.30, 188.10, 653.20);
InventoryCost := 8.8 ;
DECISION VARIABLES
Inventory[product,month] -> Invt
Production[product,month] -> Prod
Sales[product,month] -> Sale
MACRO
Revenues := SUM(product,month: price * Sales);
TotalCost := SUM(product,month: InventoryCost * Inventory
+ ProductionCost * Production);
MODEL
SUBJECT TO
InventoryBalance[product,month] -> IBal :
Inventory = Inventory[month-1] + Production - Sales ;
BOUNDS
Sales < Demand ;
Production < ProductionCapacity ;
Inventory[month=January..November] < 90000 ;
Inventory[month=December] = 20000 ;
END
The title section is used to give each problem a name which we strongly reccomend. When you use a
name, MPL places it in the generated file where appropriate, which helps you keep track of files and
printouts. Your title section starts with the keyword TITLE, followed by the problem name. The name
can be of any length but cannot contain spaces or other delimiters. You may place a semicolon after the
name, although it is not necessary. If you omit the title, it defaults to the name Problem.
Example:
TITLE Production_Planning ;
The Definition Part is used to define various items to be used later in the model. Here you can, for
example, define subscripted variables, data to be imported from other programs and macros for repetitive
parts of the model.
The first section, after the title, is the index section, starting with the keyword INDEX. This is where you
define the indexes and the sets for the model. This will be covered in Chapter 6: Defining Sets and
Indexes.
After the indexes, the next step is to setup the data for the model in the DATA section. You can specify
both data defined directly in the model and also read in data from either external data files or databases.
This will be covered in Chapter 7: Data for the Model.
Following the data section you normally define the variables for the model in the DECISION
VARIABLES section. If you need to make the variables dependent on a certain sparse data vector you do
this using the WHERE command. See Chapter 8.1: Declaring Decision Variables for further information.
The last section in the Definition Part is the MACROS section. The macros can be used to give complex
expressions a distinctive name and then refer to these complex expressions throughout the model by the
macro. See Chapter 8.2: Defining Macros for further information.
Each section in the definition part, except the problem title, can appear as often as you want. These
sections normally appear in the order listed above, but they can appear in any order you choose. Please
note though that each item must be defined before it is referred. In the following chapters each section
will be discussed in detail.
The model part contains the actual problem formulation. Although the keyword MODEL is optional, it is
useful to mark the beginning of the problem formulation.
The layout of the model is straightforward. The first step is the objective function. Either the keyword
MAX or keyword MIN is used, depending on whether it is a maximization or minimization problem.
After the objective function, the next step is to list the constraints. The keyword SUBJECT TO is used as
a separator between the objective function and the constraints.
The next step is to enter simple upper and lower bounds on variables if they are used. You use the
keyword BOUNDS to mark the beginning of the bounds section.
Free variables are entered following the FREE keyword. Integer and binary variables are entered after the
INTEGER and BINARY keywords, respectively. SOS sets of variables are entered after the SOS
keywords. These last five sections (including bounds) are all optional and can be placed in any order.
The END keyword is optional and marks the end of the model. Everything that follows it is ignored.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Numbers
You can enter numbers as real numbers or as integers; MPL uses them all as real (floating point) numbers. Scientific notation
is not allowed. Integer numbers can be entered with a decimal point to the right. Numbers between -1.0 and 1.0 can be
entered without a leading zero.
24
4.8565
13.
-.7854
Names
The names of variables and constraints can be of any length. A name begins with a letter followed by any combination of
letters and digits. MPL is case sensitive by default, but you can change that in the MPL Environment Options dialog box in
the Option menu. See Chapter 4.9: The Options Menu for further nformation. You cannot use spaces in a name, but the
underscore character ‘_’ is allowed. For full list of characters allowed in variable names, refer to Appendix A: Character Set.
Examples of legal filenames:
x1
Inventory
An alternative way is to use double quotes ("). Then any character can be used, even spaces and other special characters. A
quote symbol in quoted name is represented by two adjacent quotes. An empty name (name without any characters in it),
which can be useful in name abbreviations, is written by two quotes with nothing between them (" ").
"Inventory in April"
Prod3 -> "P3"
x[foods] -> ""
Delimiters
MPL detects the end of a name when it encounters a delimiter. A delimiter is any of the following characters:
! $ : ; { } \ % ( ) * + - / , > = <
. # " ? [ ]
Furthermore, the space character, the end of an input line, and any character in the ASCII range 0..31 are also treated as
delimiters. This manual always specifies ASCII values with decimal (base 10) numbers.
White Space
MPL automatically skips over all white space characters when reading the input. White space characters are:
● The space character: Spaces are often used to make the formulation easier to read. We recommend you use them
extensively.
● The control characters (ASCII range 0..31): You can use various control characters in the input for printing
considerations without affecting MPL. This includes characters like Tab (ASCII 9) and FormFeed (ASCII 12).
Inserting Comments
A comment is a part of the input file that MPL does not process. Usually, comments are explanations of the formulation in
plain words, but you can also use them to tem-porarily "remove" various parts of the model. Typically, you might want to
hide a constraint, which you can later make visible again. Also, you can switch between sets of formulas or constraints.
Conditional directives and include files (explained later in this chapter) are also often used for this purpose. You can insert
comments anywhere in the input file. There are two basic types of comments:
Single-line comments: !
Single-line comments are used to add a comment of one line or a part of a line of text. When MPL finds the
exclamation mark, it simply skips the rest of the line.
Block comments are used to add several lines or pages of text. When MPL reads the input, it skips everything inside
the braces. For example to hide part of a formulation, perhaps only temporarily, you can add braces before and after
the part in question. A block of text can even have comments contained within it; i.e., MPL can handle nested
comments.
Include Files
Include files allows you, instead of storing the entire model in a single large file, to break it up into one or more files that are
then included in the main model file. Place the include command on a line by itself, at the point where you wish the include
file to be read. For example:
#include filename
In above example filename is the name of the file you wish to include. Include files can be nested up to 8 levels.
Include files make the construction of large models much easier and more reliable. The main advantages of using include
files are:
● Several models can share the common part of a formulation. This could be a large objective function containing many
prices, or several constraints that are the same in all the models. This sharing saves typing and simplifies the changes
since only one file must be modified. This is particularly important when you are creating a group of models that work
together.
● It is often convenient to group related parts of large problems together, and to put each group in a separate file to get
better overview and make them easier to maintain.
● When you use more than one version of a constraint, it is better to place each version into a separate include file than
to use many slightly different main files. With separate include file you can avoid repeating the parts of the model that
stay the same. Conditional directives can be used for the same purpose. Refer to the next section on Conditional
Directives for further information.
Conditional Directives
This feature in MPL is well known in computer programming. Conditional directives can be just as useful when developing
linear programming models as when developing programs. They allow you to define special symbols called directives and
then, based on these directives, to include or exclude some part of the model.
All directive commands take one line and must be the first item on that line. They start with the ‘#’ character followed by the
command and the symbol in question, where applicable. You can nest the #ifdef’s up to any level.
To illustrate this, lets say you have a problem with variables which can either be regular or integer variables. You can then
use conditional directives to decide whether they are to be defined as integer in the model.
#define IntegerProblem
.
.
.
#ifdef IntegerProblem
INTEGER
x,y
#endif
In this example, you define the directive IntegerProblem in the beginning of the model formulation. Then, if you want to
make the variables noninteger, you only have to delete or comment out the define for IntegerProblem.
Option Settings
In addition to setting options in the option dialog boxes (See Chapter 4.9: The Options Menu ), MPL allows you to set
certain options directly in the model file. This is accomplished by using the keyword OPTIONS anywhere in the model file,
followed by a line for each option entry. For example, if you want to specify a different Input Directory for data files and
change the model type to linear names you can enter the following:
OPTIONS
DatafileInputDir="Data"
Model Type=Nonlinear
The available option entries you can set in the model file are listed below. Each entry is listed with the name string that is
used, the original name of the option, and then a short description.
PlainVarDefined: (Plain Variables Must be Defined) Specifies whether plain variables must be defined in the Decision
Variable section of the model or can be introduced as they appear in the model. For larger models, requiring plain variables
to be defined, can increase the maintainability of the model.
DatafileInputDir: (Data Files Input Directory) Selects the folder where MPL will search for input data files. The default is
the current folder.
DatafileOutputDir: (Data Files Output Directory) Selects the folder where MPL will save output data files. The default is
the current folder.
CheckDuplicateData: (Check Sparse Data For Duplicate Entries) Specifies whether sparse data files are checked for
duplicate index entries. In some cases the user may want to read in a data file without receiving errors even if it has duplicate
entries. When there are duplicate entries, the last entry in the file will be used by MPL.
UseQuickSort: (Use quicksort for sparse data) Specifies whether sparse data is sorted with quicksort after it is read in. It is
normally faster to use quicksort but if there is an invalid entry, such as duplicates, in the data file MPL will not be able to
pinpoint the problem line accurately.
ModelType: (Default model type) Specifies the default model type for MPL language.
Linear (1) Accept only models that are either linear or mixed integer.
Quadratic (2) Accept models that are quadratic, in addition, to the standard
linear or mixed integer models.
Nonlinear (3) Accept models that are nonlinear. For example, models that have
variables multiplied together or use nonlinear arithmetic functions
such as LOG or EXP on the variables.
NameGenType: (Name Generation) Chooses the method MPL uses to generate names for vector variables and constraints.
2 (Prefixed Numeric Names) Generate names as numeric with the prefix based on
the vector
name.
MaxVarLen: (Max variable length) Most LP solvers have a restriction on the l ength of variable names. Since MPL, in most
cases, sends the matrix directly through memory to the solver, the variable names are normally not needed. If the are needed,
the value set here helps you ensure that the variable names generated are within limits.
MaxSubLen: (Max subscript length) This value decides how many characters of indexes are retained in the generated
variable name. This allows you to use long index names in the model, but keep variable names concise in the generated input
file.
DatabaseType: (Default) Chooses which of the supported databases is the default for the MPL database connection. Valid
entries are ODBC, Access, Excel, FoxPro and Dbase.
DatabaseDirectory: (Directory) When the database type is either FoxPro or Dbase you can use this option to specify the
directory where the database files are stored.
DatabaseODBC: (ODBC Data Source) When the database type selected is ODBC this option specifies which datasource, as
defined in the ODBC control panel, should be used.
DatabaseAccess: (Database File *.mbd) When the database type selected is Access this option specifies which database
should be used. Please note that if you use any special characters in the name you might have to enclose it with quotation
marks.
For example, if you want to read data from the Access database planning.mdb enter the following options in the model file:
OPTIONS
DatabaseType=Access
DatabaseAccess="planning.mdb"
DatabaseExcel: (Workbook File *.xls) When the database type selected is Excel or Excel4 this option specifies which
workbook should be used.
DatabaseUsername: (User) When you are working with databases that require a Username to log in, this option can be used
to specify it.
DatabasePassword: When you are working with databases that require a Password to log in, this option can be used to
specify it.
ExcelWorkbook: (Workbook File *.xls) Allows you to specify the default Excel Workbook filename when reading in Excel
ranges.
For example, if you want to read Excel ranges from the Excel workbook file cutstock.xls enter the following options in the
model file:
OPTIONS
ExcelWorkbook="cutstock.xls"
ExcelSheetname: (Worksheet name) When the Excel range data is not on the first default worksheet, you can use this option
to specify which sheet to read from.
ExcelSkipOverEmpty: When reading indexes from an Excel range, the default is to skip empty cells. You can use this
option to turn this Off causing MPL to stop reading at the first empty cell.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The index section is used to define the domains of the model. The indexes are then used throughout the
model when objects like subscripted variables and data coefficients, summations and structured
constraints are used. Indexes encapsulate the problem dimensions and make it easy to quickly adjust the
problem size.
There are two basic types of indexes; numeric and named. The numeric indexes are used to give each
subscript item a numerical value. The named indexes are used to give each subscript item a descriptive
name.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
product := 1..3 ;
After you have defined an index you can then use it to define data, variable, and constraint vectors. For
example, the following example would define a variable vector named Ship that contains three elements:
VARIABLES
Ship[product]
This definition will generate three variables (one for each product), named Ship1, Ship2, and Ship3.
The name length of most LP solvers is limited to eight characters. Therefore, only the minimum number
of characters are used, for each numeric index, is normally used when building variable and constraints
names in MPL.
It is not always desirable to have the default subscript length for all indexes in the model. You can set a
different length for each index by following the index definition with a colon and a new length. Here is
an example:
INDEX
i := 1..5 : 2;
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
month := (January,February,March,April,May,June,July,
August,September,October,November,December) ;
In most cases MPL sends the matrix to the LP solver directly through memory, which means that the
names are not used. But sometimes, there is a need to generate an input file either in MPS or the native
solver format. Because of the name size of most LP solvers is limited to eight characters, only the first
three characters, for each named index, are normally used when building variable and constraints names
in MPL. The default number of characters used can be set in the Max Subscript Length option in the
MPL Language dialog box in the Options menu. See Chapter 4.9: The Options Menu for more
information.
To make sure there are no name conflicts, keep at least the first three characters of the named subscripts
distinct. If that is difficult, you can abbreviate the names by using the becomes operator ‘->’. To use
the becomes operator insert the ‘->’ after the subscript list and place another list with shorter version of
the names beneath. These abbreviated names are then used instead when generating the input file. Here is
an example:
It is not always desirable to have the same subscript length for all indexes in the model. Therefore, you
can use a different length for each index by following the index definition with a colon and a new length.
Here is an example:
INDEX
month := (January,February,March,April,May,June) : 4;
This definition sets the subscript length for the month index to 4.
If the index contains numeric values, but you do want them treated as a named index, you can do so by
adding the keyword NAMED in front of the INDEX keyword. This is, for example, necessary when you
have product numbers that are all numeric, but you do not want them sorted according to their numerical
values.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
location := (A,B,C,D,);
dest := location;
source := location;
This expression defines the source and dest indexes as an alias index of the location index and allows
you, for example, to define the following variable:
DECISION VARIABLES
ship[source,dest]
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
When the offset value goes outside the defined range for the index, MPL by default omits that vector
entry. By defining an index as circular, you specify that when the offset value goes out of range, it takes
values instead from the opposite end.
Index are defined as circular by entering the keyword CIRCULAR after the index definition. For
example:
INDEX
day := (mon, tue, wed, thu, fri, sat, sun) CIRCULAR;
month := 1..12 CIRCULAR;
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
i := 1..10
m := (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
You can then use them to define these indexes as subsets of the original indexes:
j[i] := (2,3,5);
HolidayMonth[m] := (Apr,Jul,Aug);
RepairMonth[m] WHERE (m >=Apr) AND (m <= Jun);
You can also define an index as a list of numbers, i.e. an enumeration of numbers instead of strings.
MPL treats this kind of index as a subset index without an underlying index. For example:
k := (0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75);
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
For example, you are creating a model that schedules trucks to certain routes, but their current location is
not where each route starts. Therefore, in the model we create two function indexes. One that maps each
truck to the city where they are currently located and the other where we map each route to the city of
departure. In MPL this can be formulated as follows:
INDEX
truck := (T1, T2, T3, T4, T5, T6);
route := (R1, R2, R3, R4, R5, R6);
CurrentLoc[truck].Current :=
(T1,Atlanta, T2,Atlanta,
T3,Atlanta, T4,Atlanta,
T5,Chicago, T6,Chicago);
DepartLoc[route].Depart :=
(R1,Chicago, R2,Dallas,
R3,Denver, R4,Denver,
R5,NewYork, R6,NewYork);
DATA
Distance[Current, Depart] := ( 0, 717, 783, 1406, 886,
717, 0, 937, 1023, 807,
VARIABLES
Assign[truck, route];
Now we can create an objective function that minimizes the total distance for each assigned truck route as
follows:
MIN TotalDistance =
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The set difference operation is specified by using the minus (-) symbol between two indexes. It will
subtract from the first index all the elements that are in the second index and create a new index
containing the remaining elements.
The not operation on index is specified by placing the keyword NOT in front of the index. It will select
all the elements from the parent index that are not defined in the given index.
The set union operation can be specified by placing either the plus symbol (+), the OR keyword or the
UNION keyword between two indexes. It merges all the elements from both of the indexes into one large
index.
The set intersection operation is specified by placing either the AND keyword or the INTERSECTION
keyword between two indexes. It creates a new index that contains only the elements that are defined in
both of the indexes.
INDEX
plants := (NewYork, Chicago, London, Paris);
:= (Chicago, Paris)
! Not
USPlants[plants] := NOT EuropePlants;
:= (NewYork, Chicago)
! Union
OpenOrEurope[plants] := OpenPlants OR EuropePlants;
:= (NewYork, London, Paris)
! Intersection
OpenAndEurope[plants] := OpenPlants AND EuropePlants;
:= (London)
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
plant := (Atlanta, Chicago, Dallas);
machine := (Grind, Drill, Press);
PlantMachine[plant,machine] :=
(Atlanta.Grind,
Chicago.Drill,
Chicago.Press,
Dallas.Grind);
In the above example we created a two-dimensional index PlantMachine that contains, for each plant, the
machines that are available.
When referring to multi-dimensional indexes we sometimes call it the parent index and the indexes it is
derived from the domain indexes. When specifying which element pairs to include in the parent index
you can, as in the above example, list all the elements you want to include, with each domain index
element separated with a period so long as they are not numeric indexes. Alternatively, you can also
separate each domain index element with a comma. For clarity, you can also group each parent index
element with parentheses.
PlantMachine[plant,machine] :=
((Atlanta, Grind),
(Chicago, Drill),
(Chicago, Press),
(Dallas, Grind));
Instead of listing all the elements manually, you can also use the WHERE command to specify which
elements are included in the multi-dimensional index. We will now, on the following page, show several
examples on how the WHERE command can be used when defining multi-dimensional indexes.
In the example below we want to create an index WinterRepair that contains all the months in the Repair
index which are between November and March.
INDEX
month := (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
Repair[month] := (Jan,Mar,Jun,Oct,Nov);
WinterRepair[month] :=
In the next example we first define two indexes node1 and node2 that contains nodes that are in a
network and then use the WHERE command to create a two-dimensional index arcs that connects
together all the nodes except those that are the same.
INDEX
node1 := (n1,n2,n3,n4);
node2 := node1;
When defining indexes you can also use the WHERE command to make the index dependent on the
values of a datavector. In the example below, we want to create an index that contains the routes between
the plants and the warehouses that have shipping costs below 2400.
INDEX
plant := (Atlanta, Chicago, Dallas);
warehouse := (Pittsburgh, Charlotte, Memphis);
DATA
ShipCost[plant, warehouse] := (1200, 3000, 2300,
INDEX
BestRoutes[plant,warehouse] WHERE (ShipCost <= 2400);
! := (Atlanta.Pittsburgh, Atlanta.Dallas,
! Chicago.Charlotte,
! Dallas.Charlotte, Dallas.Memphis);
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Example:
INDEX
product := INDEXFILE("product.dat");
The file is a free-format text file, in which the elements of the index are read in the order they appear.
Separate the elements with commas or spaces. Everything inside curly braces and following an
exclamation mark is treated as a comment.
Sometimes, the file you want to read the index elements from contains other columns of data. MPL
allows you to specify which column is chosen for the index by adding a comma and a column number
inside the parenthesis. For example, if the product index is stored in the first column of the product.dat
file you would enter:
INDEX
product := INDEXFILE("product.dat", 1);
Sample index file with one column for the product index and two data columns is shown below:
Reading subset and multi-dimensional indexes from an index file is done in the same way as for normal
indexes. The only difference is that each entry in the index file needs to contain the elements for each of
the domain indexes. The entry in the model file is the same way as before.
INDEX
FactoryMachine[factory,machine] := INDEXFILE("factmach.dat");
Here is a sample index file with two columns, one for factory and one for machine:
fac1, mach1,
fac2, mach2,
fac2, mach3,
fac3, mach4,
fac3, mach5,
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
cuts := EXCELRANGE("Cutstock.xls","CutsRange");
In the above example, MPL will open the Excel spreadsheet Cutstock.xls, locate the CutsRange, and then read in
the entries for the index cuts.
To make sure there are no name conflicts when sending the problem to the solver, keep at least the first three
characters of the named subscripts distinct. If that is difficult, you can abbreviate the names by importing another
range from the spreadsheet containing shorter names. To import the short name range enter the keyword
BECOMES followed by the range name inside the parenthesis. Here is an example:
INDEX
cuts := EXCELRANGE("Cutstock.xls", "CutsRange", BECOMES "CutsShort");
It is not always desirable to have the same subscript length for all indexes in the model. Therefore you can use a
different length for each named index by following the index definition with a colon and a new length. For
example:
INDEX
cuts := EXCELRANGE("Cutstock.xls","CutsRange"):4;
This definition sets the subscript length for the month index to 4.
The EXCELRANGE command will read every cell in the range by default until an empty cell is encountered. In
some cases, you will want to read only a specific column from the range. MPL allows you to specify which
column to read by entering a comma and the column number after the range name. For example:
INDEX
cuts := EXCELRANGE("Cutstock.xls","CutsTable", 1);
This will read only the first column of the CutsTable range. Also note, that if you are reading multiple indexes
and data vectors from the same Excel spreadsheet, you can omit the workbook filename on all entries after the
first one.
For further information on importing indexes please refer to Chapter 11.1: Import Indexes from Database
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
depot := DATABASE(“Depots”,”DepotID”);
In the above example, MPL will open the database table Depots, locate the column DepotID, and then read in the
entries for the index depot. In most cases the imported indexes are the key fields for the table.
To make sure there are no name conflicts when sending the problem to the solver, keep at least the first three
characters of the named subscripts distinct. If that is difficult, you can abbreviate the names by importing another
column from the database table containing shorter names. To import the short name column enter the keyword
BECOMES followed by the column name inside the parenthesis. Here is an example:
INDEX
depot := DATABASE("Depots", "DepotName", BECOMES "DepotID");
It is not always desirable to have the same subscript length for all indexes in the model. Therefore you can use a
different length for each named index by following the index definition with a colon and a new length. For
example:
INDEX
depot := DATABASE("Depots","DepotID"):4;
This definition sets the subscript length for the month index to 4.
In some instances you do not want to create the index with all the elements that are in the table. In that case, you
can enter the keyword WHERE followed by a condition on one of the columns. Here is an example:
INDEX
For further information on importing indexes please refer to Chapter 11.1: Import Indexes from Database
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
In the data section you specify the data coefficients to be used in the model. These can be scalars,
vectors, and even arrays of multiple dimensions. By defining the data coefficients separately, the actual
model is free of numerical data and thus easier to maintain. Furthermore, by using the import feature you
can store the data in a separate file and retrieve it when generating the input file.
Each data coefficient is given a separate name that is used throughout the model. There are two different
types of data objects that MPL recognizes; data constants and data vectors. The following sections
describe how both are specified.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
To use the interactive method, place a question mark following the coefficient value.
Example:
DATA
InventoryCost := 8.8
MaximumInventory := 1200?
Here the InventoryCost is given the value 8.8 which will be used whenever the constant is referred to in
the model.
The value for MaximumInventory is prompted at runtime as in the Data Request dialog box like the one
shown here below in Figure 7.1. It will then used in the model like any other constant.
Named data constants can be used almost anywhere in the model. This can be used to help make the
model truly dynamic and easy to change. Here are some examples:
DATA
NrOfYears = 10 ?
December = 12
HolidayMonth = 7
INDEX
i := 1..NrOfYears
j := 1..December
VARIABLES
Inventory[i,j]
Production[i,j]
.
.
BOUNDS
Inventory[i,December] > 200 ;
Production[i,HolidayMonth] < 100 ;
END
The value of the named data constant NrOfYears is prompted at run-time using the default value of 10. It
is then used to define the index i. The HolidayMonth constant is used to enter a fixed month for the
Production variable.
Like with indexes and data vectors, MPL allows you to import data constant entries from datafiles and
Excel spreadsheets. Please note, that since data constants are not indexed they cannot easily be imported
from databases. To read from a datafile just enter the DATAFILE keyword followed by the filename in
parentheses. To read from an Excel spreadsheet, enter the EXCELRANGE keyword followed by the
workbook filename and the cell range in parentheses. For example:
DATA
NrOfYears = DATAFILE("years.dat");
December = 12;
HolidayMonth = EXCELRANGE("worksched.xls", "B5");
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The simplest way to define the values of the datavector is to enter them as a list of numbers directly after
an assignment symbol. Surround the list with parentheses and separate each number by either space,
comma, or both. To enter a zero value, you can alternatively enter only the comma to reduce typing.
Examples:
DATA
Price[product] := (105.09, 234.00, 800.00);
ProdCapacity[product] := 1000 (105, 42, 14);
Here price is a vector over one dimension product. Because there are three products, a list of three
numbers is given. There must be enough numbers to satisfy the size of the vector, but additional values
are allowed and simply ignored.
In ProductionCapacity 1000 is used as a multiplier. The actual values for the vector will be (105000,
42000, 14000).
Alternatively, you can put a multiplier in front of the parentheses and it is then applied to each number in
the list. This feature reduces typing and increases the models readability.
As an additional feature, when defining a datavector, constant formulas can be used instead of just
numbers for the elements. This includes features such as products, fractions, and arithmetic functions.
Here is an example:
When specifying tables of two or more dimensions, you can use just one set of parentheses for the whole
list or use new parentheses for each dimension.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
To define a sparse data vector, you surround the list of elements with brackets instead of the usual
parentheses. Inside the brackets you list each nonzero element preceded by its subscript:
In most cases when you have larger data sets the data itself is normally not specified in the actual model
file but instead either is stored in an external datafile or a database table. See Chapter 7.5 Reading Data
from External Datafiles and Chapter 7.6 Import Data from Database for further information.
MPL also allows you to separately specify whether the data will be stored sparse or dense in memory,
independently of how it is defined in the model. Simply put either of the keywords DENSE or SPARSE in
front of the section keyword DATA.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
DATA
A[i,j] := ...
B[i] := ...
C[i,j] := A + B/3;
Total := SUM(i,j: A);
If the formula starts with a datavector, its type is used to decide whether the resulting vector is dense or
sparse. If the formula is a summation, the resulting vector is always dense. If the formula does not start
with a datavector or a summation or you need to override the default type, you can use the keywords
DENSE() and SPARSE() to specify the type. For example, to specify the C[i,j] vector as stored sparse,
use:
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
When reading data from a text file, use the keyword DATAFILE followed by a filename inside
parentheses. If you use any characters in the filename, such as ‘-’ and ‘#’, that have special meaning to
MPL, you can enter them by including the filename in double quotes (").
In our example, the demand vector has 36 values, 12 months times 3 products, which are stored in the
file demand.dat. Each number in the file is multiplied by 1000 as it is read. The following is an example
of a data file.
{ Demand.dat }
! Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
! ------------------------------------------------------------
50, 60, 70, 80, 90, 100, 110, 120, 120, 120, 110, 100
24, 30, 36, 42, 48, 52, 50, 48, 44, 40, 36, 32
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 13
The file is a free-format text file, in which numbers are read in the order they appear. Separate the
numbers with commas or spaces and make sure there are enough numbers to satisfy the size of the
vector. In order to use comments in the DATAFILE insert everything inside curly braces for multi-line
comments and following an exclamation mark for single line comments. See Chapter 5.2: Basic Input
Elements for more information on inserting comments.
MPL allows you to read multiple data vectors and simple data constants from the same datafile. Simply
group them together in the data section and give the same filename inside the parentheses. MPL will
then continue reading the values from where it left off from the previous definition.
Sometimes, the data you need to read is sparse, meaning that not all the index entries have values. In this
case, to read the sparse data from an external file, use the keyword SPARSEFILE instead of DATAFILE.
MPL then expects both the subscripts and the values for each entry in the given file. Here is an example
that shows how you can read a sparse datafile into a data vector:
If the file you want to read the data elements from contains other columns of data, MPL allows you to
specify which column is chosen, by adding a comma and a column number after the filename inside the
parentheses.
This will read the production cost values from the fourth column of the data file. Here is a sample of the
datafile produce.dat:
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Excel has the Visual Basic programming language built in, which enables easy pre- and post-processing of the data.
The solution from the optimization can then be used to update the spreadsheet, and to create graphs that visually
represent the solution. Excel provides some excellent user-interface capabilities for optimization models. MPL builds
on this by offering the ability to import and export data directly from Excel ranges. This allows the developer to use
an Excel spreadsheet for the user interface and data manipulation while using MPL to specify the model formulation.
The model can then be solved with any solver supported by MPL with no limits on the size, speed or robustness of
the solution.
Furthermore, MPL is available as a part of the OptiMax 2000 Component Library, which is specially designed to
embed optimization models into application programs, such as Excel. OptiMax 2000 allows MPL models to be linked
directly with the Visual Basic for Applications language in Excel enabling the developer to create large-scale
optimization models that can be solved directly from an Excel spreadsheet. Please contact Maximal Software for
more details.
In the DATA section, where you define the data vector, enter the keyword EXCELRANGE after the assignment
symbol (:=), followed by parentheses containing the Excel workbook filename and the Excel range name you want to
import from. To give an example of how data is imported from an Excel range, here is an MPL statement that is used
to read in the pattern cuts generated for a cutting stock model:
DATA
CutsInPattern[patterns, cuts] := EXCELRANGE("Cutstock.xls","Patterns");
In the above example, MPL will open the Excel spreadsheet Cutstock.xls, locate the range Patterns, and then retrieve
the entries for the MPL data vector CutsInPattern.
In some cases, you will want to read only a specific column from the range. MPL allows you to specify which
column to read byentering a comma and the column number after the range name. The EXCELRANGE command is
used when the data is stored in a dense format in the spreadsheet. In some instances it is better to store the data in a
sparse column format where the first columns store the values for the indexes followed by columns containing the
data values. In this case you use the EXCELSPARSE command to specify that the data is to be read in a sparse format.
For example:
DATA
CutWidths[cuts] := EXCELSPARSE("CutsTable", 2);
CutDemand[cuts] := EXCELSPARSE("CutsTable", 3);
In this example the Excel range CutsTable contains three columns. The first column stores the values for the index
Cuts followed by two columns containing the widths and the demand for each cut. The column number 2 given means
the second column in the range while 3 specifies the third column in the range.
If the Excel range contains the data as an Excel List there will be an extra row at the top of the range that contains the
name of each column. MPL allows you to skip that row automatically by using the EXCELLIST command instead of
the EXCELSPARSE command.
Also note, that if you are reading multiple indexes and data vectors from the same Excel spreadsheet, you can omit
the workbook filename on all entries after the first one.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
DATA
FactDepCost[factory,depot] := DATABASE(“FactDep”,”TrCost”);
In the above example, MPL will open the database table FactDep, locate the columns TRCost, FactID,
and DepotID, and then read in the entries for the data vector FactDepCost.
In some instances you do not want to read all the data elements that are in the table. In that case, you can
enter the keyword WHERE followed by a condition on one of the columns. Here is an example:
DATA
FactDepCost[factory,depot] :=
DATABASE("FactDep","TrCost" WHERE Region="NorthWest");
In this example we only want to read the transportation costs from the FactDep table where the Region
column contains the entry NorthWest.
For further information on importing data vectors, please refer to Chapter 11.2: Import Data Vectors
from Database.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
<[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The decision variables are the elements under control of the model developer and their values determine
the solution of the model. Decision variables in MPL are defined as they come in the input file. The
name can be of any length. It starts with a letter, with the remainder consisting of letters and digits. MPL
is case sensitive by default so you need to be careful to distinguish between upper and lower case letters.
If you want MPL not to be case sensitive you can change the default by selecting MPL Language Dialog
Box in the Options menu. See Chapter 4.9: The Options Menu for further details.
There are two types of decision variables: plain variables and vector variables (sometimes called
subscripted variables). A plain variable is setup as a single column in the matrix that is sent to the LP
solver. A vector variable, on the other hand, is setup as range of columns in the matrix.
The DECISION VARIABLES section is mainly used to define subscripted or vector variables, but plain
variables can also be defined here. Vector variables must be defined before they are used in the model,
but with plain variables it is optional. Plain variables can either be defined in the Decision Variable
section or be introduced as they come into the model. It is recommended for larger models to define plain
variables in the Decision Variable section in order to decrease the chance of errors occurring in the
model. If you want to require plain variables to be defined you set the Plain Variables must be defined
option in the MPL Language Dialog Box in the Options menu.
Variable Names
For each vector variable, enter the name and then specify what indexes are to be used by listing them
inside brackets just after the name. For plain variables, enter just the name. You can use an optional
semicolon to separate each variable definition.
Because variable names in most LP solvers are limited to eight characters and the subscripts for vector
variables have to be included, only the first few characters are used when variable names are generated
for solvers by MPL. To make sure there are no name conflicts, keep the first few characters distinct or
use the becomes operator ‘->’ to enter a shorter version of the name. This feature allows you to use
long, descriptive names in your MPL model, and at the same time meet your LP package requirements
for short names.
DECISION VARIABLES
Inventory[product,month] -> Invt ;
Production[product,month] -> Prod ;
The preceding definition results in the generation of 108 variables (3 times 36). As an example of how
these variables are generated, here is the list of all the Inventory variables:
Even though you can use fairly long names for variables in MPL you might sometimes want to use
longer names or description for documentary purposes. MPL allows you to do that by following the
definition with the keyword IS and a text description. If the description contains spaces you will need to
enclose it with quotation marks.
DECISION VARIABLES
Production[product,month]
IS "Production of each per ";
Integer Variables
If some of the variables in the model are integer you can define them by putting the keyword INTEGER
in front of the keyword VARIABLES. For binary variables use the keyword BINARY.
INTEGER VARIABLES
Production[product,month];
MPL allows you also to define integer and binary variables at the end of the model. For more
information see Chapter 8.6: Integer and Binary Variables
Sometimes you want to be able to limit the number of variables defined in a vector dependent on a data
vector. In this case you can use a WHERE data condition following right after the definition of the
vector. This will result in only those variables being created where the condition is met.
DECISION VARIABLES
Production[product,month]
WHERE (Demand[product,month] > 0);
After optimizing the problem, MPL can export the variable values to separate data files which can be
used to report the solution back to the user. In the DECISION VARIABLES section, where you define the
variable vector, enter the keyword EXPORT TO, followed by the keyword SPARSEFILE and parentheses
containing the filename you want MPL to export to.
This will write the activity and the reduced cost values for each entry of the Prod variable vector to a text
file in the standard sparse format. Since this file is a standard sparse data file, MPL can read these values
back later into other models.
You can change which values will be exported by entering one or more of the following keywords
directly after the keyword EXPORT: Activity, ReducedCost, ObjectCoeff, ObjectLower, ObjectUpper. If
you want all of above entries you can use instead the ALL keyword.
MPL also allows you write solution values for variable vectors to data files in the same format as is used
in the standard MPL solution files.
When exporting to text files using the solution file format all the options the Solution File Options dialog
box will have effect.
MPL can also export the variable values to an Excel spreadsheet where it can be used to report the
solution back to the user. Following the declaration of the variable vector, enter the keyword EXPORT
TO, followed by the keyword EXCELRANGE and parentheses containing the Excel workbook name and
the Excel range name you want to export to. For example:
DECISION VARIABLES
PatternCount[patterns]
EXPORT TO EXCELRANGE("Cutstock.xls","PatCount");
In the above example, MPL will open the Excel spreadsheet Cutstock.xls, locate the range PatCount and
then export the solution values for the variable vector PatternCount.
The EXCELRANGE command can also be used to export activity values for plain variables. If the range
give contains more than one cell, only the first cell will be used for the exported value.
You can also export the data in sparse column format where the first columns store the values for the
indexes followed by a column containing the variable values. In this case, you use the EXCELSPARSE
command to specify that the data is to be written in a sparse format. For example:
DECISION VARIABLES
ExcessCuts[cuts]
In this example the Excel range CutsTable contains four columns. The first column stores the values for
the index Cuts followed by two columns containing the widths and the demand for each cut. The
activities values for the ExcessCuts variable vector will be stored in the fourth column of the CutsTable
range. If the Excel range contains the data as a Excel List there will be an extra row at the top of the
range that contains the name of each column. MPL allows you to skip that row automatically by using
the EXCELLIST command instead of the EXCELSPARSE command.
If you are writing multiple variable vectors to the same Excel spreadsheet, you can omit the workbook
filename on all entries after the first one. Please note, that since variable exports are performed at a
different time than imports, you will need to specify the spreadsheet workbook filename on the first
export statement even if it is the same as the one you were importing from.
After optimizing the problem, MPL can export the variable values to the database where it can be used
to report the solution back to the user. Following the declaration of the variable vector, enter the keyword
EXPORT TO, followed by the keyword DATABASE and parentheses containing the table name and the
column name you want to export to.
Example:
DECISION VARIABLES
FactDepShip[factory,depot]
EXPORT TO DATABASE("FactDep","Shipment");
In the above example, MPL will open the database table FactDep, locate the columns Shipment, FactID,
and DepotID, and then export the solution values for the variable vector FactDepShip. For further
information on exporting variable values please refer to Chapter 11.3: Export Variable Values to
Database.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
You define each macro item with a name on the left side and a formula or an ex-pression on the right side.
Whenever the macro name is encountered in the model, the formula is used instead. The formula cannot be
indexed. However, you can use summations and fixed vector items in the formula. A semicolon is required
after each macro definition.
MACROS
TotalRevenue := SUM(product,month: price * Sales) ;
TotalCost := SUM(product,month: InventoryCost * Inventory
+ ProductionCost * Production);
MODEL
MAX Profit = TotalRevenue - TotalCost ;
In this example the macros are used to give the above summations a descriptive name. The macro named
Revenues is defined as the sum of the revenues of all three prod-ucts over the whole year. The TotalCost
macro is the total cost of the inventory storage plus the total cost of the production. When these macros are
encountered in the model, their respective summations they represent will be placed into the model. See
Chapter 9.9 Using Macros for more information on how to refer to macros in the model.
After the model has been solved, MPL will create a solution file that contains the solution values of the
defined macros in the model. For example:
MACROS
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The name of the objective function is optional. It can be of any length, but cannot contain spaces or other
delimiters. If you omit it, the name defaults to ‘Z’. An equals sign follows the name. Finally, you enter
the formula for the actual function.
You can extend the objective function over many lines. When it is complete, mark the end with a
semicolon and/or the keyword SUBJECT TO.
You can use a constant value in the objective function. MPL places the constant directly into the
generated objective function if the LP package supports that feature. If not, MPL will add the constant to
the solution after optimizing.
Examples:
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The constraints for the model follow immediately after the objective function. Either the keyword SUBJECT TO or
a semicolon is required as a separator between the objective function and the constraints.
Plain constraints that are regular single constraints, similar to those LP packages accept in their input files
Vector constraints that are defined over indexes and MPL then expands to a list constraints when generating the
model.
Plain Constraints
Plain constraints are constraints that are defined without any indexes. They are normally used with constraints
containing plain variables and fixed vector variables. Plain constraints can also contain summations of vector
variables as long as all the indexes for the variables are accounted for.
The name of the constraint is optional. It can be of any length, but must not contain spaces or other delimiters. If
you omit the name, it defaults to ‘ci’, where i is the number of the constraint. The constraint name must be
followed by a colon.
Using meaningful names for the constraints is a good modeling practice and makes the model easier to work with.
The constraint name you provide is used where applicable when MPL solves the model or generates input files.
The constraint name is followed by an equation, which is entered as two formulas, separated by a comparison. The
comparison between the formulas can be any of the following:
The reason there are two formulas in each constraint is so that variables can be entered on both sides of the
comparison. This can enhance the readability of the model. For example if a variable has a negative coefficient it
can be moved over to the other side of the comparison in order to make it positive. When MPL reads in the model,
it moves all variables to the left side, all constants over to the right side, and changes signs where necessary.
If you refer to a variable more than once in a constraint, the coefficients will be added together in the model. For
more information on writing formulas, you can refer to Chapter 9: Buiding Formulas
Examples:
You can extend each constraint over many lines. You must end each constraint with a semicolon ‘;’ to seperate it
from the next constraint. Forgetting the semicolon is one of the more common mistakes people make when
formulating MPL models.
Vector Constraints
Very often models contain constraints that are subscripted, called vector constraints. For example, a vector
constraint can be defined in this way over a number of periods and products. A vector constraint is entered by
following the constraint name with a list of indexes inside brackets. The index list can contain one or more
indexes. When MPL parses the model, it will expand each vector constraint to a list of plain constraints, based on
the contents of the index list.
The constraint name in MPL, which is required for vector constraints, can be of any length. The name cannot
contain any spaces or other delimiters. See Chapter 5.2: Basic Input Elements for more information on names and
list of delimiters.
In some cases you may want to use MPL to generate an input file for the LP package. Most LP packages are
limited to eight characters for names and therefore only the first few characters will be used when the names are
built by MPL. Therefore, to avoid name conflicts, it is necessary to use the becomes operator ‘->’ to abbreviate
the name. This feature allows you to use long, descriptive names in your MPL model, and at the same time meet
your LP package requirements for short names.
Example:
SUBJECT TO
InventoryBalance[product,month] -> Ibal:
Even though you can use fairly long names for constraints in MPL you might sometimes want to use longer names
or description for documentary purposes. MPL allows you to do that by following the definition with the keyword
IS and a text description. If the description contains spaces you will need to enclose it with quotation marks.
SUBJECT TO
InventoryBalance[product,month]
IS "Balance of Inventory for each <product> per <month>";
If you do not want to generate constraints for all values of a particular index you can use a subrange of the index.
You can also use subranges when you want to use different constraints for certain values of the index, i.e. only the
first index value.
Examples:
InventoryBalance[month=Jan..Nov] : ...
InventoryBalance[month<=Jun] : ...
InventoryBalance[month=Dec] : ...
As with plain constraints, the constraint definition is followed by an equation, which is entered as two formulas,
separated by a comparison. The formulas in vector constraints can contain vector variables, coefficients and
summations.
Example:
In the example above, each of the variables referred to is a vector variable defined over the indexes product and
period. When reading the model, MPL will map these variable indexes to the same indexes used to define the
constraint InventoryBalance. Each index for a referred variable must be accounted for in either the constraint or an
enclosed summation. For example, if the Inventory variable had been defined with a third index, that could not be
mapped, MPL will report this with an error message.
Sometimes you want to be able to limit the number of constraints defined in a vector constraint dependent on the
contents of a data vector. In this case you can use a WHERE data condition following right after the definition of
the vector. This will result in only those constraints being created where the condition is met.
SUBJECT TO
InventoryBalance[product,month]
WHERE (month > Jan) :
After optimizing the problem, MPL can export the constraint values to separate data files which can be used to
report the solution back to the user. Following the constraint declaration, enter the keyword EXPORT TO, followed
by the keyword SPARSEFILE and parentheses containing the filename you want MPL to export to.
This will write the slack and the shadow price values for each entry of the InvtBal constraint vector to a text file in
the standard sparse format. You can change which values will be exported by entering one or more of the
following keywords directly after the keyword EXPORT: Activity, Slack, ShadowPrice, RhsValue, RhsLower,
RhsUpper. If you want all of above entries you can use instead the ALL keyword.
MPL also allows you write solution values for constraint vectors to data files in the same format as is used in the
standard MPL solution files.
When exporting to text files using the solution file format all the options the Solution File Options dialog box will
have effect.
MPL can also export the constraint values to an Excel spreadsheet where it can be used to report the solution back
to the user. Following the declaration of the constraint vector, enter the keyword EXPORT TO, followed by the
keyword EXCELRANGE and parentheses containing the Excel workbook name and the Excel range name you
want to export to. For example:
SUBJECT TO
CutReq[cuts]:
In the above example, MPL will open the Excel spreadsheet Cutstock.xls, locate the range ShadowPrice and then
export the shadow prices for the constraint vector CutReq.
The EXCELRANGE command can also be used to export solution values for plain constraints. If the range give
contains more than one cell, only the first cell will be used for the exported value.
You can also export the data in sparse column format where the first columns store the values for the indexes
followed by a column containing the constraint values. In this case, you use the EXCELSPARSE command to
specify that the data is to be written in a sparse format. For example:
SUBJECT TO
CutReq[cuts]:
In this example the Excel range CutsTable contains four columns. The first column stores the values for the index
Cuts followed by three columns containing the widths, the demand, and the excess for each cut. The shadow price
for the for the CutReq constraint vector will be stored in the fifth column of the CutsTable range.
If the Excel range contains the data as a Excel List there will be an extra row at the top of the range that contains
the name of each column. MPL allows you to skip that row automatically by using the EXCELLIST command
instead of the EXCELSPARSE command.
If you are writing multiple constraint vectors to the same Excel spreadsheet, you can omit the workbook filename
on all entries after the first one. Please note, that since variable and constraint exports are performed at a different
time than imports, you will need to specify the spreadsheet workbook filename on the first export statement even if
it is the same as the one you were importing from. Please refer to Chapter 4.9 for more details on the options
section.
If you are using the Database Connection option you can export the constraint solution values back to the database
after solving the problem. This allows you to present the solution to the end-user using the reporting capabilities of
the database package.
In order to export constraint solution values follow the definition of the constraint with the keyword EXPORT TO
followed by the keyword DATABASE and parentheses containing the table name and the column/field name you
want to export to.
Example:
SUBJECT TO
FactoryCapacity[factory]
EXPORT ShadowPrice TO DATABASE("Factory","ShadowPrice"): ...
In the above example, MPL will open the database table Factory, locate the columns FactID and ShadowPrice,
and then export in the shadow price values for the constraint FactoryCapacity. For further information on
exporting constraint values please refer to Chapter 11.4: Export Constraint Values to Database
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Semi-Continuous Variables
Most optimizers can handle upper and lower bounds on variables efficiently without making them
regular constraints. MPL allows you to enter bounds on variables in the BOUNDS section following the
constraint.
Examples:
BOUNDS
x <= 4*12 ;
z_bounds : 2 <= z <= 8 ;
CloseInv : Inventory[December] = 20000 ;
Just as with constraints, you separate bounds with a semicolon. To make your formulation easier to read,
you can use bound names in the same way as constraints. The bound names can be of any length, but
cannot contain spaces or other delimiters.
The first six are the same input forms you would use for standard constraints. Forms 5 and 6 are used to
fix a variable to a constant value so it will not be changed during the optimization. Forms 7 and 8 can be
used when a variable has both lower and upper bounds to make the ex-pression simpler and easier to
read.
The constant values in bounds can be entered using standard coefficient arithmetic. For more
information, refer to Chapter 9.1: Coefficients for Variables.
Bounds on vector variables can be entered with a bound name and a corresponding index list for the
bound, similar to the way vector constraints are specified.
You can also enter the bound without a bound name and the index list. In this instance MPL will look up
the declaration of the variable for the index list.
If you want to use a subrange of an index, instead of the declared index you can enter it inside the
brackets.
BOUNDS
MaxInv[month<=Nov] : Inventory <= 90000 ;
Inventory[month=Dec] = 90000 ;
Sales %lt;= Demand ;
Free Variables
MPL assumes that all decision variables are non-negative. You can override that assumption, by defining
the variables as "free", which will then make their values unrestricted. To define free variables, use the
keyword FREE followed by a list of the variables that are free. This free section can be placed anywhere
after the constraints section. The variables can be both plain and vector variables.
FREE
Inventory[month] ;
In this example all the inventory variables will be declared as free variables.
Semi-Continuous Variables
MPL also allows you to define semi-continuous variables for solvers that support that feature. You
specify a variable to be semi-continuous by using the keyword SEMICONT followed by the variable
name. The semi-continuous section can be placed anywhere after the constraint section.
BOUNDS
MinMach <= MachineHours[machine] <= MaxMach;
SEMICONT
MachineHours[machine] ;
In this example, the MachineHours variable is defined as semi-continuous with a feasible range which
includes any value between its upper and lower bounds as well as zero.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Binary variables are integer variables that can only have values of zero or one. You define them in the
same way as integer variables, using the keyword BINARY instead.
INTEGER
Production[month,product] ;
BINARY
ShopOpen ;
MPL will direct the solver to use integer and binary variables if they are supported by the solver
MPL allows you to define Special Ordered Sets (SOS) of variables in the model. For each set, use one of
the keywords SOS1, SOS2, or SOS3, and follow it with a list of the variables that belong to the set. This
section can be anywhere after the constraints section. The variables can be either plain or structured. If
you need to specify the reference row use the keyword REFERENCE immediately after the SOS
keyword.
Examples:
SOS1
x1, x2, x3 ;
Please check if the solver you are using supports SOS by referencing the solver documentation. MPL
will generate the sets for the solver if they are supported, but will otherwise ignore them.
MPL also supports specifying multiple SOS sets for subsets of a vector variable range. This can be very
useful when you have a vector variable with multiple indexes, but there is a separate set for each element
of one or more of the indexes. The indexes that are used in each set are specified using the SET keyword
as shown here below:
Examples:
SOS1
s[i]: SET(k: x[i,k]);
This will create a separate SOS set for each i with each set containing the x variables for all the elements
of the k index.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
You can enter coefficients as simple numbers or as any combination of products, fractions, percentages,
and arithmetic functions. Parentheses containing constant expressions can also be used in the
denominators of the coefficients.
MPL evaluates those expressions when it reads the model file, and puts the results in the input file. This
capability enables you, for example, to enter fractions with complete accuracy. Named data constants
declared in the DATA section can be used as any other numbers.
Examples of coefficients:
4 { = 4.0 }
1/3 { = 0.33333333333 }
1/(3+5) { = 0.125 }
2 * InvtCost { = 2 * 8.8 = 17.6 }
1.32 / 24.5% * 53 { = 285.55102041 }
In the fourth line it is assumed that the InvtCost is a named data constant which has been defined as 8.8.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Arithmetic functions:
Trigonometric functions:
Integer functions:
The arithmetic functions expect a constant value (which can be a coef-ficient formula)or a datavector as
argument, and return a real number. The functions operate on real numbers, except SQRT, LOG and
LOG10 that take only positive numbers, EXP that takes only values less than 40, PI that has no
arguments, and RANDOM that takes either no argument (returns real number between 0 and 1) or whole
numbers (returns a whole number less than argument). You can also set a new seed value for the
RANDOM function by adding seed=number after the argument. The integer functions expect a constant
value as argument and return a whole number which can be used in subscript formulas. The data vector
functions expect a defined data vector as argument and return a real number.
Examples of functions:
ARCTAN(3.1415);
SQR(183/2);
RANDOM(100,seed=42);
AVG(Demand);
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
There are two types of decision variables: plain variables and vector variables (some-times called
subscripted variables). A plain variable is setup as a single column in the matrix that is sent to the LP
solver. A vector variable, on the other hand, is setup as range of columns in the matrix. The DECISION
VARIABLES section is used to define the vector variables. See Chapter 8.1: Declaring Decision Variables
for further details.
The most important thing to remember when referring to vector variables is that all the indexes defined
for the vector must be accounted for in the domain, either by the constraint specification, the enclosing
summation, or the subscript.
Vector variables can be referred in the model in a number of ways. The quickest is to enter the vector
without the indexes and let MPL figure it out from the definition. Another way is to write the vector as it
was defined, with all the indexes listed, for example Inventory[product,month]. The order of the indexes
is actually irrelevant; MPL gets the correct order from the definition.
Sometimes the index of the constraint and the index of the vector may have to differ by some offset, for
example, when the inventory for each month depends on the inventory of the previous month. You can
enter this by using an offset value, which can be specified as a constant, a datavector or an index. To
specify the offset value, the appropriate index is followed by either a plus or minus sign and the slide
value. For example:
In the constraint for the month of December, the November subscript is used for the initial inventory.
This method works for any integer offset value, and the relevant index is the only one that must be
specified. Entries that fall out of bounds are ignored. For example, the constraint for January would be:
Values of index variables can also be fixed or set to a specific value, rather than range over the index
domain. Simply use the value in place of the index variable. In that case, the order of the indexes
becomes important. As a rule, when a fixed value is used, all indexes should be specified in the same
order as when the vector was defined. For example:
Inventory[1,December] = 20000 ;
Another way to implement fixed values is to use subindexes in the constraint specification with a range
of a single value. For more details see the Chapter 8.4: Specifying Constraints
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
When you are working with the objective function or a simple constraint, the formula term consists of a
variable and its associated coefficient, or just a single constant. The coefficient can either be placed in
front of the variable or trailing it. These terms are then added together to make a formula.
Examples of formulas:
Terms in structured constraints consist of coefficients, up to eight data vectors, and a decision vector. For
example, the following terms for the vector variable Inventory are legal:
8.8 Inventory
InvtCost * Inventory
12%/2 * InvtCost * InvtCount * Inventory
Note that the multiplication performed is a element wise multiplication, not a matrix multiplication.
When the vectors being multiplied have the same set of index variables, the result is what you would
expect. However, when the index variable sets are not identical, the vectors are expanded and replicated
in the missing dimensions.
DATA
Cost[product] = (1,2,3);
Sales[month] = (12,16,18,20);
(1,2,3) (12,12,12)
Cost = (1,2,3) Sales = (16,16,16)
(1,2,3) (18,18,18)
(1,2,3) (20,20,20)
When two or more variables share the same coefficient i.e. the coefficients have a common divisor, you
can factor them out using parentheses. This will be explained better in the Parentheses section later in
this chapter.
Simple terms are valid in structured constraints and get expanded appropriately. Sums and macros are
also valid terms and are discussed in later sections in this chapter.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The same term can be entered using the IIF function statement which sometimes is more readable:
When you are choosing between two terms based on a data value, you can use the ELSE statement to specify
the alternative term. For example:
InvtBal[prod, month]:
IF (month = 1) THEN StartInvt[prod] ELSE Invt[month-1] ENDIF + ...
InvtBal[prod, month]:
IIF(month = 1, StartInvt[prod], Invt[month-1])
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
For example, assume that you have a datavector A[i,j] filled with sparse data and you only want the
following constraint where the values are greater than zero. You would write:
The same rule applies when you want to use the WHERE condition on formula terms:
In this example the variable x[i] is used wherever b[i] is not equal to one. The EXCEPT keyword inverts
the set of values.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
DATA
A[i,j] := DENSE(10*(i-1)+j);
Furthermore, the integer functions FIRST(index), LAST(index), and COUNT(index) are available. They
provide the first subscript, the last subscript, and the number of subscripts, respectively, of the given
index and can be used both in formulas and in subscript arithmetic.
INDEX
i := 1..10;
k[i] := i - (first(i), last(i))
DATA
A[i] := i;
B[i] := DENSE(count(i)-i+1);
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
The parentheses contain decision variables and even full-fledged formulas. Those formulas can, in turn,
have more parenthesized expressions, so nested parentheses are allowed. You can enter coefficients in
front of the parentheses.
Four main rules apply when you use parentheses. Parenthesized expressions cannot be:
1. Multiplied together.
2. Multiplied by a variable.
3. Used in a denominator if they contain variables.
4. Followed by a coefficient.
(x + y) / 3 { Rule 4 }
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
Both variable and data vectors can be included in the summation formula. The vectors can be added and
subtracted, and parentheses and other summations are allowed within the sum. This example shows how
sums are used:
The above constraint means that sum of the Production variables for all months has to be less than 1200.
The resulting constraint in the input file generated, is:
Now assume that you have three products and want to limit the production for each. Then the constraint
would be:
This summation generates three constraints, one for each product. The Production vector is now defined
over the indexes product and month. The constraint for a given product contains the sum of the
Production variables for all months, but with the product fixed.
The main rule when using sums is that all declared indexes of a vector term must be accounted for, either
by the sum indexes, the constraint indexes, or by a fixed subscript.
When summing over a single vector, you can omit the list of index variables. MPL automatically uses
the dimension of the vector when it expands the sum.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
A defined macro can be used in the formula of a constraint as a term. The macro is expanded as it is
replaced by the expression it represents. Macro terms can be preceded by coefficients.
Example:
MACROS
Revenues := SUM(product,month: price * Sales);
TotalCost := SUM(product,month: IventoryCost * Inventory
+ ProductionCost * Production);
MODEL
Macros are helpful to aid readability by giving complex expressions a distinctive name. They are also
used to eliminate unnecessary constraints from the model and thereby reduce the size of the problem to
be solved by the LP package. See Chapter 8.2: Defining Macros for more information.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
In the example below, MPL will stop and display an error message because the index Top3Plants does
not contain 3 elements.
INDEX
plants := (Atlanta, Chicago, Dallas, NewYork, SanDiego);
In the example below, we are checking if two subset indexes, which should be mutually exclusive, have
any common elements. As both indexes contain the city Dallas MPL will stop and issue the error
message.
INDEX
EastCoast[plants] := (Atlanta, Chicago, Dallas, NewYork);
WestCoast[plants] := (Dallas, SanDiego);
You can also use the ABORT IF condition to check if the values of the datavectors are within the allowed
range. For example, in the example below, the capacity for each plant must be at least 200.
DATA
Capacity[plants] := (120, 300, 250, 400, 500);
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-20039 Maximal Software, Inc. - All rights reserved.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
plant := (Atlanta, Chicago, Dallas);
machine := (Grind, Drill, Press);
product := (p1,p2,p3,p4);
PlantMach[plant,machine] :=
:= (Atlanta.Grind, Atlanta.Press,
Chicago.Drill, Chicago.Press,
Dallas.Grind);
.
SUBJECT TO
PlantCapacity[plant] :
In the above example, we sum together how much is produced with each machine and then make sure
that the total production is limited to the maximum capacity at each plant.
We can also use the IN operator to join together two multi-dimensional indexes. For example, say that
you also have an index that defines which products are produced by which machine. You can then use
the IN operator, in conjunction with the WHERE command, to create a new index that contains which
products can be produced in which plants.
INDEX
MachProd[machine,product] :=
:= (Grind.p1, Grind.p4,
Drill.p2, Drill.p3, Drill.p4,
Press.p1, Press.p3);
PlantProduct[plant,product] WHERE
In the example on the previous page, we join the plants and the products together through the machine
index. This is done by MPL going through each plant.machine pair in the PlantMach index and
matching the machine to the machine.product pair in the MachProd index. This will give us a new index
PlantProduct which contains, for each plant, the products that can be produced at that plant. If you are
familiar with relational databases and view the indexes in MPL as columns, then you will notice that this
operation is the same as the natural join operation in databases.
When formulating the model with a lot of sparsity, you can use the IN operator to let MPL quickly skip
index elements that are not needed. For example, say you want to define a produce variable for each
plant, machine, and product, but you only want to include those variables that are members of the two
parent indexes PlantMach and MachProd. This can be accomplished in MPL by using the IN operator
when you are listing the domain indexes for the variable. For example:
DECISION VARIABLES
Produce[plant, machine IN PlantMach, product IN MachProd];
MPL will now include a machine index element only in theProduce variable if the plant.machine pair is
in the PlantMach index and then a product index element only if the machine.product index is in the
MachProd index. This will result in the total number of variables defined to be much smaller and speed
up the parsing time for the rest of the model considerably, especially for large, sparse models.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
FromNode := (n1,n2,n3,n4);
ToNode := FromNode;
Arcs[FromNode,ToNode] := (...);
DECISION VARIABLES
END
In the above example, we want the Ship variable to contain all the elements of Arcs, where the
FromNode is not the same as theToNode.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
depot := ...
factory := ...
FactDepot[factory,depot] := ...
SUBJECT TO
DepotCapacity[depot]:
In this example we need to sum over the factories that ship to the depot and make sure that the total amount
shipped is less than the capacity for the depot. Notice that in this example the Ship variable is defined with
the FactDepot index.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
SUM(i,j<i: formula)
The above condition defines a double sum over the indexes i and j with the additional condition that it
only sums the values where j is less than i, i.e., the lower triangular matrix, excluding the diagonal. The
conditions can also contain more complex subscript arithmetic. For example:
constr[i,k=2i+3] : ...
This example generates a constraint for all i and k where k is equal to 2i+3. The other constraints are still
generated, but they do not contain any terms and are therefore specified as empty constraints. MPL will
not send the empty constraints to the solver.
Please note that conditional indexes are also allowed in the definition part when you are defining data
and variable vectors. However, these conditions do not have any effect until the vectors are used in the
model formulation. For example, when you define the datavector A[i,j < =i] in the DATA section, the list
of numbers that follows must also contain values for the elements where j is greater than i. The condition
is not used until the datavector is referred to later in the model.
You can put a condition on every index in vectors, summations, and constraints. Be sure to keep in mind
that this powerful tool can easily make the model very complex and, therefore, harder to maintain.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
To give you an example, when formulating trans-shipment problems, you frequently encounter constraints
similar to this one:
Continuity[k] :
In the above example, we want to sum on the left-hand side, how much is shipped to location k, and on the
right-hand side, how much is shipped from location k. Since the Ship variable is defined over the indexes i
and j, we use direct assignment to assign them the value of k.
Sometimes you need a full-fledged formula to specify the subscripts for the index.
SUM(i: x[i,j:=last(i)-i+1])
In this example, direct assignment is used to let the subscript j decrease as the subscript i increases.
Assignment of subscripts can also be used to perform multiplication of matrixes and vectors as shown here
below:
INDEX
i := 1..3;
i2 := i;
j := 1..4;
DATA
A[i,j] := (1, 2, 3, 4,
5, 6, 7, 8,
9,10,11,12);
! Transpose of matrix A
B[j,i] := A[i,j];
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Importing data from a variety of corporate database systems into optimization models is frequently an
essential requirement for optimization projects. One of the advanced features of MPL is the database
connection option that directly links MPL with relational databases and other data sources. This option
enables the model developer to gather both indexes and data values from various data sources and import
them directly into the model. After the model has been optimized, the solution output can be exported
back into the database. This, along with the run-time features of MPL, allows the model developer to
easily create customized end-user applications for optimization using the built-in data entry and reporting
capabilities of the database.
The database connection in MPL has the ability to access data from many different sources, such as
databases, Excel spreadsheets, external data files, and the Internet. This gives the model developer the
flexibility to choose the most efficient and convenient way to incorporate the data into the model. Among
the data formats that are supported by MPL are: Microsoft Access and Excel, ODBC, Paradox, FoxPro,
Dbase, SQL Server, and Oracle.
Relational databases are designed to store and retrieve structured data enabling the user to access
corporate data such as plants, products, machines, and etc., on the symbolic level. The purpose of the
modeling language is to take this structured data and generate a mathematical matrix from the model that
the optimization solver can process.
One alternative to using a modeling language is to write a customized matrix generator in a programming
language. This kind of programming is very difficult and causes the resulting application to be highly
dependent on specific methods and libraries, of both the database and the solver. MPL offers clear
benefits to this approach, because with the database connection it can automatically map the columns of
the database tables to the indexes and data vectors of the model without involving any programming.
This gives the model developer unprecedented flexibility and expressive power and the ability to focus
mainly on formulating the model and connecting the data instead of programming.
In the following sections, we will describe each import and export operation in detail. Refer to the
Database Options dialog box in Chapter 4.9: The Options Menu: Database Options to select the database
you will be using.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
INDEX
depot := DATABASE("Depots","DepotID");
In the above example, MPL will open the database table Depots, locate the column DepotID, and then
read in the entries for the index depot. In most cases the imported indexes are the key fields for the table
which are underlined in the following examples.
DepotID Capacity
Atlanta 400000
Chicago 50000
NewYork 70000
Dallas 100000
The column name defaults to the name of the index so if it is the same you do not have to specify it. In
the example below the column name in the database table is DepotID which is the same as the index
DepotID.
INDEX
DepotID := DATABASE("Depots");
MPL supports multiple databases. The default database is specified in the Database Options dialog box
in the Options menu. See Chapter 4.9: The Options Menu for more information.
MPL can import from more than one database in the same run. If you need to import an index from table
in a database other than the default, you can do so by specifying the database name before the name of
the table. In the example below, MPL will read in the factory index from Access, instead of the default
database.
INDEX
factory := DATABASE(Access,"Factory","FactID");
MPL also allows you to import subset indexes from database tables.
INDEX
FactoryDepot[factory,depot] := DATABASE("FactDep");
The above statement will open the database table FactDep and locate the columns for factory and depot
and then read in the entries for FactoryDepot.
Notice that MPL automatically uses the same name as default for the columns FactID and DepotID, as
in the original tables the indexes were defined from. If an index column does have a different name than
in the original table, you can specify it following the table name by first entering the index name
followed by an equal sign and the column name.
INDEX
FactoryDepot[factory,depot] :=
DATABASE("FactDep",factory="Factory",depot="Depot");
This means if you are consistent in naming the columns in different tables you do not have to specify
them each time you refer to them in MPL.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Example:
DATA
FactDepCost[factory,depot] := DATABASE("FactDep","TrCost");
In the above example, MPL will open the database table FactDep, locate the columns TRCost, actID, and
DepotID, and then read in the entries for the data vector FactDepCost.
Notice that MPL automatically uses the same name as the default for the index columns FactID and
DepotID as in the original tables that the indexes were defined from. If an index column does have a
different name than in the original table, you can specify it following the table name by first entering the
index name, followed by an equal sign and the column name.
DATA
FactDepCost[factory,depot] :=
DATABASE("FactDep","TrCost",factory="Factory",depot="Depot");
This means if you are consistent in naming the columns in different tables you do not have to specify them
each time you refer to them in MPL.
The column name defaults to the name of the data vector, so if it is the same you do not have to specify it. In
the example below the column name in the database table is TrCost which is the same as the data vector
TrCost.
DATA
TrCost := DATABASE("FactDep");
MPL can import from more than one database in the same run. The default database is specified in the
Database Options dialog box in the Options menu. If you need to import a data vector from table in a
database other than the default, you can do so by specifying the database name before the name of the table.
In the example below, MPL will read in the data vector DepotCustCost from Access instead of the default
database.
DATA
DepotCustCost := DATABASE(Access,"DepCust","TrCost");
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Example:
DECISION VARIABLES
FactDepShip[factory,depot]
EXPORT TO DATABASE("FactDep","Shipment");
In the above example, MPL will open the database table FactDep, locate the columns Shipment, FactID,
and DepotID, and then export the solution values for the variable vector FactDepShip.
Here is an example of the FactDep table after the solution values have been exported.
Notice that MPL automatically uses the same name as the default for the index columns FactID and
DepotID, as in the original tables the indexes were defined from.
If an index column does have a different name than in the original table you can specify it following the
table name by first entering the index name followed by an equal sign and the column name.
DECISION VARIABLES
FactDepShip[factory,depot]
EXPORT TO DATABASE("FactDep","Shipment"
factory="Factory",
depot="Depot");
This means, if you are consistent in naming the columns in different tables, you do not have to specify
them each time you refer to them in MPL.
The column name defaults to the name of the datavector so if it is the same you do not have to specify it.
In the example below, the column name in the database table is FactDepShip which is the same is the
datavector FactDepShip.
DECISION VARIABLES
FactDepShip[factory,depot]
EXPORT DATABASE("FactDep");
MPL supports multiple databases for both importing and exporting data. The default database is
specified in the Database Options dialog box in the Options menu. If you need to export a variable
vector to a table in a database other than the default, you can do so by specifying the database name
before the name of the table.
In the example below, MPL will export the solutions values of the variable vector FactDepShip from
Paradox instead of the default database.
DECISION VARIABLES
FactDepShip[factory,depot]
EXPORT TO DATABASE(DBase,"FactDep","Shipment");
MPL also allows you to export variable values other than the activity. You can export the reduced costs,
the upper and lower ranges for the objective function, as well as the objective function coefficient values.
You can change which values will be exported by entering one of the following keywords directly after
the keyword EXPORT: Activity, ReducedCost, ObjectCoeff, ObjectLower, ObjectUpper. For example, if
you want to export the reduced cost for a variable enter the following:
DECISION VARIABLES
FactDepShip[factory,depot]
EXPORT ReducedCost TO DATABASE("FactDep","ReducedCost");
If you need to export more than one value for a variable vector you can do so by entering multiple export
statements after the variable definition.
MPL offers three different options on how the database table is updated by the EXPORT statement. The
first one, which is the default, searches through the database and for each record locates the
corresponding value in the solver solution and updates the database entry with it. This option minimizes
the changes done to the database table since only the existing values are updated, but can sometimes be
slow especially on SQL type databases.
The second option is to use the REFILL keyword right after the EXPORT keyword to specify that the
whole database table should be emptied and then refilled with the entries from the solver solution. Since
this takes out the necessity to search the table this can often lead to faster export times for larger tables.
The third option is to use the CREATE keyword right after the EXPORT keyword to specify that the
database table should be created and then filled with the entries from the solver solution. This option is
mainly useful when exporting to the database table for the first time.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Example:
SUBJECT TO
FactoryCapacity[factory]
EXPORT ShadowPrice TO DATABASE("Factory","ShadowPrice");
In the above example, MPL will open the database table Factory, locate the columns FactID and
ShadowPrice, and then export in the shadow price values for the constraint FactoryCapacity.
Here is an example of the Factory table after the shadow price values have been exported.
Notice that MPL automatically uses the same name as the default for the index column FactID, as in the
original tables the factory index was defined from. If an index column does have a different name than in
the original table you can specify it following the table name by first entering the index name followed
by an equal sign and the column name.
SUBJECT TO
FactoryCapacity[factory]
EXPORT ShadowPrice TO DATABASE("Factory","ShadowPrice"
factory="Factory");
This means, if you are consistent in naming the columns in different tables, you do not have to specify
them each time you refer to them in MPL.
MPL supports multiple databases for both importing and exporting data. The default database is
specified in the Database Options dialog box in the Options menu. If you need to export a constraint
vector to table in a database other than the default, you can do so by specifying the database name before
the name of the table.
In the example below, MPL will export the shadow price of the constraint vector FactoryCapacity from
FoxPro instead of the default database.
SUBJECT TO
FactoryCapacity[factory]
EXPORT ShadowPrice TO DATABASE(FoxPro,"Factory","ShadowPrice");
MPL also allows you to export constraint values other than the shadow price. You can export the slack
values, the upper and lower ranges for the right-hand-side as well as the right-hand-side values. You
change which values will be exported by entering one of the following keywords directly after the
keyword EXPORT: Activity, Slack, ShadowPrice, RhsValue, RhsLower, RhsUpper. For example, if you
want to export the slack for a constraint enter the following:
SUBJECT TO
FactoryCapacity[factory]
EXPORT Slack TO DATABASE("Factory","Slack");
If you need to export more than one value for a variable vector you can do so by entering multiple export
statements after the variable definition.
MPL offers three different options on how the database table is updated by the EXPORT statement. The
first one, which is the default, searches through the database and for each record locates the
corresponding value in the solver solution and updates the database entry with it. This option minimizes
the changes done to the database table since only the existing values are updated, but can sometimes be
slow especially on SQL type databases.
The second option is to use the REFILL keyword right after the EXPORT keyword to specify that the
whole database table should be emptied and then refilled with the entries from the solver solution. Since
this takes out the necessity to search the table this can often lead to faster export times for larger tables.
The third option is to use the CREATE keyword right after the EXPORT keyword to specify that the
database table should be created and then filled with the entries from the solver solution. This option is
mainly useful when exporting to the database table for the first time.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Character Set
Letters
65-90 A..Z Upper case letters
97-122 a..z Lower case letters
38 & Ampersand
39 ' Aphostrophe
64 @ At-sign
95 _ Underscore
96 ` Grave accent
Digits
48-57 0..9 Digits
46 . Decimal point
Special Symbols
34 " Double quotation mark (quoted names)
35 # Number sign (include commands)
36 $ Dollar sign (advanced command)
44 , Comma (item separator)
45,62 -> Becomes (name abbreviation)
46,46 .. Dots (index range)
58 : Colon (constraint name)
59 ; Semicolon (separator)
63 ? Question mark (interactive data value)
91 [ Left bracket (vector index)
93 ] Right bracket (vector index)
Arithmetic Operators
37 % Percent sign
40 ( Left parenthesis
41 ) Right parenthesis
42 * Multiplication symbol
43 + Plus sign
45 - Minus sign
47 / Division symbol
94 ^ Circumflex
Relational Operators
60 < Less than
61 = Equal sign
62 > Greater than
60,61 <= Less than or equal
62,61 >= Greater than or equal
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.
Error Messages
In the presentation of error messages, any text presented as xxxxx is a place holder. On your screen, it
will be replaced by text or a keyword specific to the error in your formulation.
1. The model file must start with a defined keyword, but I found instead ‘xxxxx’.
2. I expected to see a problem name after the keyword TITLE, but found instead ‘xxxxx’.
Example:
TITLE + FAME_Simulation ;
^
3. I expected to see a keyword starting the next section, but found instead ‘xxxxx’.
Example:
TITLE Plan_for_1_year ;
The model file must contain an objective function, which in turn must begin with the
keywords MAX or MIN. In this example the objective function is missing.
4. I expected to see a semicolon ';' after the objective function, but found instead ‘xxxxx’.
Example:
5. I expected to see a semicolon ';' after the previous constraint, but found instead ‘xxxxx’.
Example:
x1 < 4 ;
2 x2 < 12 { note the lack of semicolon }
-3 x1 + 2 x2 < 18 ;
^
Note that semicolon errors are normally not noticed until the next constraint is parsed.
Furthermore, if the next constraint begins with plus or minus sign, the missing semicolon is
normally not noticed until the comparison in that constraint has been reached.
Example:
Example:
3x + log 3 < 5 ;
^
A pair of parentheses must be around the argument for the arithmetic functions.
8. I expected to see a ')', closing the parenthesis, but found instead ‘xxxxx’.
Example:
11. I expected to see a semicolon ';' after the previous bound,but found instead ‘xxxxx’.
Example:
BOUNDS
work1 < 60 {note the lack of semicolon }
work2 < 60 ;
^
Example:
BOUNDS
3 < + invt1 ;
^
13. I expected to see a relational operator such as '<' or '>', but found instead ‘xxxxx’.
Example:
BOUNDS
x 3 ;
^
14. I expected to see a less than operator such as '<',but found instead ‘xxxxx’.
Example:
BOUNDS
3 < x > 4 ;
^
15. I expected to see a greater than operator such as '>', but found instead ‘xxxxx’.
Example:
BOUNDS
3 > x = 4 ;
^
16. A lower bound 'xxxxx' has already been defined for the variable ‘xxxxx’.
Example:
BOUNDS
x > 3;
4 < x;
A lower bound ‘xxxxx’ has already been defined for the variable ‘xxxxx’.
17. An upper bound 'xxxxx' has already been defined for the variable 'xxxxx'.
Example:
BOUNDS
z < 4;
y < 4;
z < 3;
This is the second time an upper bound is defined for the variable ‘z’.
18. The lower bound 'xxxxx' is higher than the already defined upper bound 'xxxxx'.
Example:
BOUNDS
5 < x < 3 ;
^
19. The upper bound 'xxxxx' is lower than the already defined lower bound 'xxxxx'.
Example:
BOUNDS
x < -5 ;
^
The upper bound for a variable must be greater than zero unless the variable is given a
negative lower bound.
28. I expected to see an assignment of a new seed value, but found instead ‘xxxxx’.
Example:
32. I expected to see a closing text quote '"' before reaching the end of the line.
Example:
33. I found an end of comment '}' without the corresponding beginning '{'.
34. I expected to see a closing braces '}', closing this comment, but reached instead the end
of the file.
Your comments are not paired up properly. Check to make sure that each left braces have an
accompanying right braces.
35. I expected to see a description of 'xxxxx' after the keyword IS, but found instead
‘xxxxx’.
42. I expected to see an assignment symbol ':=', but found instead ‘xxxxx’.
Example:
INDEX
product 1..3 ;
^
Example:
DECISION VARIABLES
Inventory [month] ->
Model
^
44. I expected to see an equal sign '=', but found instead ‘xxxxx’.
Example:
SUM(i, price*product)
^
47. I expected to see a semicolon after the data vector formula, but found instead ‘xxxxx’.
52. I expected to see a defined data vector, but found instead ‘xxxxx’.
Example:
INDEX
i = 1..5;
DECISION VARIABLES
x[i]
DATA
A[i] := x ;
^
Example:
INDEX
i = 1..5;
DATA
d[i] := (1,2,3,4,5) ;
DECISION VARIABLES ;
x
BOUNDS
d[i] < x ;
^
54. I expected to see data or variable vector in the sum, but found instead ‘xxxxx’.
Example:
DECISION VARIABLES ;
x
MAX
Z = SUM(x)
55. I expected to see an integer subscript entry for the index 'xxxxx', but found instead
‘xxxxx’.
Example:
INDEX
i = 1..5;
MAX
Z = x[Jan]
^
56. I expected to see a an name subscript entry for the index 'xxxxx', but found instead
‘xxxxx’.
Example:
INDEX
month := (Jan,Feb,Mar,Apr,May,Jun) ;
MAX
Z = SUM(month<Dec: Invt) ;
^
57. I expected to see an offset value for the index, but found instead ‘xxxxx’.
Example:
SUM(i,j: x[i-y]);
^
The offset value for a index subscript must be a scalar number, another index or a data vector.
58. I expected to see an offset value for the index, but found instead ‘xxxxx’.
Example:
DATA
d(i) := (1,2,3,4,5) ;
^
59. I expected to see a right bracket ']', but found instead ‘xxxxx’.
Example:
DECISION VARIABLES
production[i -> Prod] ;
^
61. I expected to see a definition such as subscript range for the index 'xxxxx', but found
instead ‘xxxxx’.
Example:
INDEX
i := 1.. ;
^
Example:
Datafile(DATA):
^
The data filename must not be keyword such as DATA unless it is put in quotes.
63. I expected to see a number element for the data vector, but found instead ‘xxxxx’.
64. I expected to see a comma separator ',' between data elements, but found instead
‘xxxxx’.
67. I expected to see a field or column number, but found instead ‘xxxxx’.
68. I expected to see a semicolon ';' after the previous macro definition, but found instead
‘xxxxx’.
Example:
MACRO
A := SUM(i: x) { Note the lack of semicolon }
B := SUM(i: y)
^
Example:
INDEX
product = 3..1 ;
^
The first number in a index range must be less than or equal to the second one.
72. The subscript 'xxxxx' is not within the defined range of the index 'xxxxx'.
Example:
INDEX
i := 1..5;
k[i] := (2,4,6);
^
73. The subscript 'xxxxx' has already been given for this subindex.
Example:
INDEX
month := (Jan,Feb,Mar,Apr,May,Jun);
Holiday[month] := (Apr,May,Jun,Apr);
^
74. This set difference operation failed as this set is not a subsetof the earlier.
Example:
INDEX
month := (Jan,Feb,Mar) : { Note the lack }
DATA { of sublength }
^
76. This short name list is not the same size as the previous named subscript list (xxxxx).
Example:
INDEX
product := (ProductA,ProductB) -> (A,B,C);
^
81. The index 'xxxxx' must have the same declaration as the index 'xxxxx'.
82. The index 'xxxxx' does not match the declaration of the vector 'xxxxx'.
Example:
DECISION VARIABLES
x[j]
MODEL
MAX Z := SUM(i,j: x[i,j]);
^
83. The index 'xxxxx' is not specified in the underlying index list.
84. The index 'xxxxx' in vector 'xxxxx' is not specified in the underlying index list.
Example:
SUBJECT TO
constr[i] : x[i,j] < 5:
85. The fixed subscript ‘xxxxx’ for the index ‘xxxxx’ is not possible here as the index has
already been referred in the vector.
86. The index 'xxxxx' has already been given a condition where this vector was defined.
\ | ~
The following keywords are reserved for use in future releases of MPL:
DEFINE, FOR, FOREACH, INIT, INITIAL, INITIALIZE, INF, MOD, NORMAL, POWER,
ST, UNIT, UNITS, USING
Most likely, the filename is not a legal filename, or the file can't be found in the current
directory.
141. Cannot open the datafile filename for reading. File not found.
143. I expected to see a valid integer subscript entry for the index 'xxxxx', but found instead
'xxxxx'.
144. I expected to see a valid name subscript entry for the index 'xxxxx', but found instead
'xxxxx'.
145. I expected to see the next data value entry, but found instead 'xxxxx'.
147. I expected to see a closing text quote (") before reaching the end of the line.
156. The row name 'xxxxx' was not defined in the ROWS section.
157. The column name 'xxxxx' was not defined in the COLUMNS section.
161. This problem has too many constraints. The maximum number is 2100000000.
162. This problem has too many decision variables. The maximum number is 2100000000.
163. This problem has too many nonzeros. The maximum number is 2100000000.
164. This problem has too many nonzeros in rim vectors. The maximum number is
2100000000.
165. This problem has too many elements in data vectors. The maximum number is
2100000000.
170. This problem has too many symbols. The maximum number is 64000.
171. This problem has too many named data constants. The maximum number is 16000.
172. This problem has too many indexes. The maximum number is 16000.
173. This problem has too many data and variable vectors. The maximum number is 16000.
174. This problem has too many variable vectors. The maximum number is 16000.
175. This problem has too many constraints vectors. The maximum number is 16000.
176. This problem has too many defined macros. The maximum number is 16000.
177. This problem has too many special ordered sets. The maximum number is 16000.
181. This named index has too many subscript elements.The maximum number is 100000.
182. This subindex has too many subscript elements.The maximum number is 100000.
183. This index list has too many indexes.The maximum number is 16.
184. This term has too many index referrals.The maximum number is 16.
185. The term has too many data vector referrals.The maximum number is 8.
186. This index formula has too many index referrals. The maximum number is 4.
191. The multi-dimensional index 'xxxxx' is too large for the 32-bit version of MPL. The
maximum size for all the indexes multiplied together is 4294967295 (2^32). Please
contact Maximal Software for details on how to get a 64-bit version that can handle
problems of this size.
192. The vector 'xxxxx' is too large for the 32-bit version of MPL. The maximum size for all
the indexes multiplied together is 4294967295 (2^32). Please contact Maximal Software
for details on how to get a 64-bit version that can handle problems of this size
199. This machine does not have enough free memory to read in this model.
200. This version of MPL does not have the database connection installed. For more
information, please contact Maximal Software.
201. I expected to see the index 'xxxxx', but found instead 'xxxxx'.
202. I expected to see either the data vector 'xxxxx' or an index name, but found instead
'xxxxx'.
203. I expected to see either the variable vector 'xxxxx' or an index name, but found instead
'xxxxx'.
205. I expected to see an index from the vector, but found instead 'xxxxx'.
206. I expected to see an import column entry, but found instead 'xxxxx'.
207. I expected to see either INDEX or DATA keyword, but found instead 'xxxxx'.
208. I expected to see the DATABASE keyword, but found instead 'xxxxx'.
211. I expected to see a database table name, but found instead 'xxxxx'.
212. I expected to see a database column name, but found instead 'xxxxx'.
213. The column 'xxxxx' was not found in the database table.
216. I expected to see a SQL statement string, but found instead ‘xxxxx’.
Back to Top | Maximal Home Page | Table of Contents | Previous Page | Next Page
[email protected]. Copyright (C) 1997-2003 Maximal Software, Inc. - All rights reserved.