Professional Documents
Culture Documents
Glpsol Tutorial
Glpsol Tutorial
GLPK is a library of functions written in C for use in linear and integer programming. However, GLPK includes a standard LP and IP solver, glpsol, built from these routines and a modeling language, GMPL (or GNU MathProg). This tutorial covers using glpsol to solve LPs and IPs. It is also possible to use the GLPK library in C, but that is not covered in this tutorial. GLPK includes a reference manual for the API functions if you are interested in using GLPK in that way. These instructions are aimed at Windows users, though once you get to a command prompt, the commands are almost the same for Windows or unix-like systems. Unfortunately, GLPK does not provide a graphical interface. Therefore you will need to use a command prompt to run glpsol on your model le. The following steps are necessary to use glpsol: Download a copy of GLPK Create a model to solve Start a command prompt (Change directories to be in the directory with GLPK and your model) Type the command to run glpsol
Download GLPK
GLPK is free and open-source software. That means it is legal for you to use it for any purpose, share it with friends, and even see and edit the source code if you want. Most importantly, it will be available to you for free download after you graduate, whether you are working in industry or in grad school. You can download a compiled version for Windows from the class website. Talk to me if you use an operating system other than Windows; I will be happy to help you get it working. Once you download the le, extract the les stored in it. There is no install necessary, so you can put these on any computer or even USB drive.
Running glpsol
Assuming that you have a GNU MathProg input le called example.txt and want to get output in a le called results.txt, you would issue the following command:
glpsol --help
This will show you all the possible options, and will start to give you an idea of the exibility of glpsol.
Errors
If glpsol cannot understand your input le, it will immediately complain with an error that will also tell you which line number was to blame. As with other programming, it may be that the true error is on that line, or it may have occurred earlier in the le. Make adjustments to your le using a text editor, save the le, and run glpsol again (the up arrow will usually show you the previous command on the command prompt).
glpsols output
If glpsol understands your input le, then it will begin to process it. As it does so, it will print a status line at least every second to show you how its doing. For an LP, each line will look something like this: * 26: objval = 1.610000000e+02 infeas = 0.000000000e+00 (2) The * means that a basic feasible solution has been found. The 26: means that there have been 26 simplex pivots so far. objval tells the current objective value (which should gradually improve) and infeas tells the amount of infeasibility. Once a feasible solution has been found, this value will be either zero or very small. When glpsol has nished, it will indicate whether it has found an optimal solution, how much time it took, and how much memory it used.
The solution
To see the solution, you need to look in the output le that you specied on the command prompt. Just open it with a text editor, like Notepad, Abiword, Wordpad, or Word. You should be able to interpret many of the results, so I wont give details here. We will talk about it later.
Example model le
# A TRANSPORTATION PROBLEM # # This problem finds a least cost shipping schedule that meets # requirements at markets and supplies at factories. # # References: # Dantzig G B, "Linear Programming and Extensions." # Princeton University Press, Princeton, New Jersey, 1963, # Chapter 3-3. # *** Anything that follows a # is a comment /* *** C-style comments can also be used */ # *** The general model is given first. Exact values of parameters # will be specified later in the data section. # *** We often start by naming the sets we will need. At this point # we just give the name and a descriptive comment. set I; /* canning plants */ set J; /* markets */ # *** Parameters are listed, but exact values wont be given until # later in the data section. param a{i in I}; /* capacity of plant i in cases */ # *** This set of parameters has one for each plant in I. # *** To reference a specific value later, use a[i]. param b{j in J}; /* demand at market j in cases */ param d{i in I, j in J}; /* distance in thousands of miles */ # *** To reference this later, use d[i,j]. param f; /* freight in dollars per case per thousand miles */ # *** This parameter is a scalar, unlike the previous ones.
param c{i in I, j in J} := f * d[i,j] / 1000; /* transport cost in thousands of dollars per case */ # *** In this case, the parameter is computed based on other # parameters. It wont have to be specified later. var x{i in I, j in J} >= 0; /* shipment quantities in cases */ # *** These are the only variables in this model. In general you can # have as many different variables as you like. # *** Nonnegativity and upper bounds can be specified at this point.
minimize cost: sum{i in I, j in J} c[i,j] * x[i,j]; /* total transportation costs in thousands of dollars */ # *** This is the objective function, which you can give any name you # like. Can you understand the summation syntax? s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i]; /* observe supply limit at plant i */ # *** Each constraint has a name. In this case, it is a set of # constraints, one for each plant in I. s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j]; /* satisfy demand at market j */ data; # *** This begins the data section, where we specify specific values # for each set and parameter set I := Cleveland Buffalo Detroit; # *** Listing sets is easy. set J := Pittsburgh Philadelphia; param a := Cleveland 350 Buffalo 250 Detroit 600; # *** In giving these parameters, the spacing and lines dont matter; # just that each value is preceded by an element from set I. param b := Pittsburgh Philadelphia param d : 500 650;
Pittsburgh Philadelphia := Cleveland 2.5 1.8 Buffalo 2.5 1.4 Detroit 2.0 1.9; # *** In this case, a table is used. Note that tables start with : # instead of :=. param f := 90;
set J := Pittsburgh Philadelphia; param a := Cleveland Buffalo Detroit param b := Pittsburgh Philadelphia param d : Cleveland Buffalo Detroit 2.0 param f := 90; end; 350 250 600; 500 650;