Script | Uses | Implements |
---|---|---|
cut1.run | cut1.mod cut.dat | Gilmore-Gomory column generation procedure for the cutting-stock (roll trim) problem |
cut2.run | cut2.mod cut.dat | Same as cut1.run, but using an alternative arrangement wherein problems are defined immediately before before their members are declared |
cut3.run | cut1.mod cut.dat | Same as cut1.run, but with better formatting of output |
multi1.run | multi1.mod multi1.dat | Dantzig-Wolfe decomposition for a multi-commodity transportation problem, using a single subproblem |
multi2.run | multi2.mod multi2.dat | Same as multi1.run, but using a separate subproblem for each product; subproblems represented in AMPL by an indexed collection of named problems |
multi3.run | multi3.mod multi3.dat | Same as multi2.run, except that the separate subproblems are realized by changing the data to a single AMPL named problem |
stoch1.run | stoch1.mod stoch.dat | Benders decomposition for a stochastic programming variant of a multi-period production problem (see Exercise 4-5) |
stoch2.run | stoch2.mod stoch.dat | Same as stoch1.run, but using a separate subproblem for each scenario; subproblems are represented in AMPL by an indexed collection of named problems |
stoch3.run | stoch3.mod stoch.dat | Same as stoch2.run, except that the separate subproblems are realized by changing the data to a single AMPL named problem |
trnloc1d.run | trnloc1d.mod trnloc1.dat | Benders decomposition for a location-transportation problem |
trnloc1p.run | trnloc1p.mod trnloc1.dat | Same as trnloc1d.run, but using a primal rather than dual formulation of the subproblem |
trnloc2a.run | trnloc2a.mod trnloc2.dat | Lagrangian relaxation for a location-transportation problem |
trnloc2b.run | trnloc2b.mod trnloc2.dat | Same as trnloc2a.run, but model has upper limits on the Ship variables to give better lower bounds on the objective |
trnloc2c.run | trnloc2c.mod trnloc2.dat | Same as trnloc2b.run, but model has 0-1 constraints disaggregated to give better LP relaxation |
AMPL offers a variety of commands for working with named problems, based in many cases on the forms and commands already used for other purposes. We consider first the several ways to define named problems, and then survey the commands for using and displaying them.
You can define a problem most straightforwardly through a problem command that gives the problem's name and its list of components. Thus in Figure 2 we have:
problem Cutting_Opt: Cut, Number, Fill;A new problem named Cutting_Opt is defined, and is specified to contain all of the Cut variables, the objective Number, and all of the Fill constraints from the model in Figure 1. At the same time, Cutting_Opt becomes the current problem. Any fixed Cut variables are unfixed, while all other declared variables are fixed (at their current values). The objective Number is restored if it had been previously dropped, while all other declared objectives are dropped; and similarly any dropped Fill constraints are restored, while all other declared constraints are dropped.
For more complex models, the list of a problem's components typically includes several collections of variables and constraints, as in this example from stoch.run:
problem Sub: Make, Inv, Sell, Stage2_Profit, Time, Balance2, Balance;By specifying an indexing-expression after the problem name, you can define an indexed collection of problems, such as these in multi2.run:
problem SubII {p in PROD}: Reduced_Cost[p], {i in ORIG, j in DEST} Trans[i,j,p], {i in ORIG} Supply[i,p], {j in DEST} Demand[j,p];For each p in the set PROD, a problem SubII[p] is defined. Its components include the objective Reduced_Cost[p], the variables Trans[i,j,p] for each combination of i in ORIG and j in DEST, and the constraints Supply[i,p] and Demand[j,p] for each i in ORIG and each j in DEST, respectively.
In general, a problem declaration's form and interpretation somewhat resemble those of the display command (Section 10.3). The declaration begins with the keyword problem, a problem-name not previously used for any other model component, an optional indexing-expression (to define an indexed collection of problems), and a colon. Following the colon is the comma-separated list of variables, objectives and constraints to be included in the problem. This list may contain items of any of the following forms, where "component" refers to any variable, objective or constraint:
{i in ORIG} Supply1[i,p], {i in ORIG} Supply2[i,p], {i in ORIG, j in DEST} Trans[i,j,p], {i in ORIG, j in DEST} Use[i,j,p] {i in ORIG} (Supply1[i,p], Supply2[i,p]), {i in ORIG, j in DEST} (Trans[i,j,p], Use[i,j,p]) {i in ORIG} (Supply1[i,p], Supply2[i,p], {j in DEST} Trans[i,j,p], {j in DEST} Use[i,j,p]) {i in ORIG} (Supply1[i,p], Supply2[i,p], {j in DEST} (Trans[i,j,p],Use[i,j,p]))As these examples show, the list inside the parentheses may contain any item that is valid in a component-list, even an indexing-expression followed by another parenthesized list. This sort of recursion is also found in AMPL's function and print commands, but is more general than the list format allowed in display commands.
Any variables, objectives or constraints that you declare are automatically added to the current problem. Thus in our earlier example, all of Figure 1's model components are first placed by default into the problem Initial; then, when Figure 2's script is run, the components are divided into the problems Cutting_Opt and Pattern_Gen by use of problem statements. As an alternative, you can declare empty problems and then fill in their members through AMPL declarations. Figure 6 (cut2.mod) shows how this would be done for the Figure 1 models. The associated script (cut2.run) is similar to the previous one. This approach is sometimes clearer or easier for the simpler applications.
Figure 6. An alternative way of specifying the two named problems for Figure 1's the cutting-stock problem (cut2.mod). The associated script (cut2.run) is similar to the one previously shown.
--------------------------------------------------------------- problem Cutting_Opt; # ====================== param nPAT integer >= 0, default 0; param roll_width; set PATTERNS := 1..nPAT; set WIDTHS; param orders {WIDTHS} > 0; param nbr {WIDTHS,PATTERNS} integer >= 0; check {j in PATTERNS}: sum {i in WIDTHS} i * nbr[i,j] <= roll_width; var Cut {PATTERNS} >= 0; minimize Number: sum {j in PATTERNS} Cut[j]; subj to Fill {i in WIDTHS}: sum {j in PATTERNS} nbr[i,j] * Cut[j] >= orders[i]; problem Pattern_Gen; # ====================== param price {WIDTHS}; var Use {WIDTHS} integer >= 0; minimize Reduced_Cost: 1 - sum {i in WIDTHS} price[i] * Use[i]; subj to Width_Limit: sum {i in WIDTHS} i * Use[i] <= roll_width; ---------------------------------------------------------------
Any use of drop/restore or
fix/unfix (Section 10.8) also modifies the current
problem. The drop command has the effect of removing
constraints or objectives from the current problem, while the
restore command has the effect of adding constraints or
objectives. Similarly, the fix command removes variables
from the current problem and the unfix command adds
variables. As an example, multi1.run uses the following
problem statements,
problem MasterI: Artificial, Weight, Excess, Multi, Convex; problem MasterII: Total_Cost, Weight, Multi, Convex;to define master problems for phases I and II of its decomposition procedure. Instead it could specify
problem Master: Artificial, Weight, Excess, Multi, Convex;to define the master problem initially, and then
drop Artificial; restore Total_Cost; fix Excess;when the time comes to convert the master problem to a form appropriate for the second phase. With a similar change to the definition of the subproblem, one loop suffices to implement both phases as seen in multi1a.run.
Alternatively, the redeclare problem command can be employed to specify a new definition for a problem. The drop, restore, and fix commands above could be replaced, for instance, by
redeclare problem Master: Total_Cost, Weight, Multi, Convex;Like other declarations, however, this cannot be used within a compound statment (if, for or repeat) and so cannot be used in the multi1a.run example. (Other uses of the new redeclare keyword are discussed further in . . . ).
A form of the reset command lets you undo any changes made to the definition of a problem. For example,
reset problem Cutting_Opt;resets the definition of Cutting_Opt to the list of components in the problem statement that most recently defined it.
Any problem statement that refers to just one problem will make that problem current. As an example, at the beginning of the cutting-stock script we want to make first one and then the other named problem current, so that we can adjust certain options in the problems' environments. The problem statements in cut1.run (Figure 2),
problem Cutting_Opt: Cut, Number, Fill; option relax_integrality 1; problem Pattern_Gen: Use, Reduced_Cost, Width_Limit; option relax_integrality 0;serve both to define the new problems and to make those problems current. The analogous statements in cut2.run are simpler:
problem Cutting_Opt; option relax_integrality 1; problem Pattern_Gen; option relax_integrality 0;These statements serve only to make the named problems current, because the problems have already been defined by problem statements in cut2.mod (Figure 6).
A problem statement may also refer to an indexed collection of problems, as in the stoch.run example cited previously:
problem SubII {p in PROD}: Reduced_Cost[p], {i in ORIG, j in DEST} Trans[i,j,p], {i in ORIG} Supply[i,p], {j in DEST} Demand[j,p];This form defines potentially many problems. Subsequent declarations go into all of these problems, as long as the unsubscripted problem name is current. Subsequent problem statements can make members of a collection current one at a time, as in a loop having the form
for {p in PROD} { problem SubII[p]; ... }or in a statement such as problem SubII["coils"] that refers to a particular member.
As seen in previous examples, the solve statement can also include a problem-name, in which case the named problem is made current and then sent to the solver. The effect of a statement such as solve Pattern_Gen is thus exactly the same as the effect of problem Pattern_Gen followed by solve.
ampl: model cut1.mod; ampl: data cut.dat; ampl: problem; problem Initial; ampl: problem Cutting_Opt: Cut, Number, Fill; ampl: problem Pattern_Gen: Use, Reduced_Cost, Width_Limit; ampl: problem; problem Pattern_Gen;The current problem is always Initial until other named problems have been defined.
Use the show command to get a list of the named problems that you have defined:
ampl: show problems; problems: Cutting_Opt Pattern_GenThe predefined set _PROBS also contains these names:
ampl: display _PROBS; set _PROBS := Cutting_Opt Pattern_Gen;Also use show to see the variables, objectives and constraints that make up a particular problem,
ampl: show Cutting_Opt, Pattern_Gen; problem Cutting_Opt: Fill, Number, Cut; problem Pattern_Gen: Width_Limit, Reduced_Cost, Use;or indexed collection of problems.
Use expand to see the explicit objectives and constraints of the current problem, after all data values have been substituted:
ampl: expand Pattern_Gen; minimize Reduced_Cost: -0.166667*Use[20] - 0.416667*Use[45] - 0.5*Use[50] - 0.5*Use[55] - 0.833333*Use[75] + 1; s.t. Width_Limit: 20*Use[20] + 45*Use[45] + 50*Use[50] + 55*Use[55] + 75*Use[75] <= 110;See the Examining Models and Data section of this supplement for further discussion of expand. [[At present, expand can be applied only to the current problem.]]
Named environments are automatically defined and changed when you define and change named problems. We begin by describing this mode of operation, which is sufficient for many purposes. We then describe several alternatives that afford a greater degree of control over environments, by permitting them to be managed independently of problems.
When you use the problem statement as shown above, the current environment always has the same name as the current problem. Sprcifically, at the start of an AMPL session the current environment is named Initial, and each subsequent problem statement that defines a new named problem also defines a new environment having the same name. An environment initially inherits all the option settings that existed when it was created, but it may be changed to new option settings. Any subsequent problem or solve statement that changes the current problem also switches to the correspondingly named environment.
As an example, our script for the cutting stock problem (Figure 2) sets up the model and data and then proceeds as follows:
option solver cplex; option solution_round 6; problem Cutting_Opt: Cut, Number, Fill; option relax_integrality 1; problem Pattern_Gen: Use, Reduced_Cost, Width_Limit; option relax_integrality 0;Options solver and solution_round are reset (by the first two option statements) before any of the problem statements; hence their new settings are inherited by subsequently defined environments and are the same throughout the rest of the script. Next a problem statement defines a new problem and a new environment named Cutting_Opt, and makes them current. The ensuing option statement changes relax_integrality to 1. Thereafter, when Cutting_Opt is the current problem (and environment) in the script, relax_integrality will have the value 1. Finally, another problem and option statement do much the same for problem (and environment) Pattern_Gen, except that relax_integrality is set back to 0 in that environment.
The result of these initial statements is to guarantee a proper setup for each of the subsequent solve statements in the repeat loop. The result of solve Cutting_Opt is to set the current environment to Cutting_Opt, thereby setting relax_integrality to 1 and causing the linear relaxation of the cutting optimization problem to be solved. Similarly the result of solve Pattern_Gen is to cause the pattern generation problem to be solved as an integer program. We could instead have used option statements within the loop to switch the setting of relax_integrality, but with this approach we have kept the loop -- the key part of the script -- as simple as possible. The advantages of this approach can be much more pronounced in scripts for more complex algorithms.
To come:
[[qualified option name ... ]] [[optional "environ envname" in problem statement]] [[environ command -- define with optional assign]] [[show environments]]
Return to the AMPL update page.