Repository navigation
Expand file tree
/
Copy pathREADME.suf
More file actions
124 lines (96 loc) · 4.66 KB
/
Copy pathREADME.suf
File metadata and controls
124 lines (96 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
Unfortunately, we have not yet had time to update "Hooking Your Solver
to AMPL" to explain facilities we added a few years ago for exchanging
suffixes with AMPL. Use of these facilities from a user's perspective
are described in chapter 14 of the second edition of the AMPL book,
with older descriptions appearing in
http://www.ampl.com/NEW/statuses.html
and
http://www.ampl.com/NEW/suffixes.html
If your solver deals with a basis, it would be good if your driver
could accept an incoming basis and return an optimal basis. The
process is fairly straightforward. You declare
static SufDecl
suftab[] = {
{ "sstatus", 0, ASL_Sufkind_var, 1 },
{ "sstatus", 0, ASL_Sufkind_con, 1 }
};
Before calling the .nl reader, you invoke
suf_declare(suftab, sizeof(suftab)/sizeof(SufDecl));
to tell the reader to save the incoming .sstatus values. If you were
interested in other incoming or outgoing suffix values, you would also
include lines for them in suftab. See, for example,
/netlib/ampl/solvers/cplex/cplex.c or /netlib/ampl/solvers/osl/osl.c .
To access an incoming suffix array (after calling the .nl reader,
which reads them), say an array of priorities on variables, declare
SufDesc *dp;
and invoke
dp = suf_get("priority", ASL_Sufkind_var);
suf_get returns a pointer to a SufDesc (which is declared in asl.h);
the second argument indicates the kind of entity to which the suffix
pertains: variable, constraints, objective, or problem.
If you wanted to see integer values for the suffix, then dp->u.i is
the array of suffix values; otherwise dp->u.r is the array of (real)
suffix values.
To return .sstatus values (i.e., a basis), you call suf_iput
twice, once for constraint.sstatus and once for variable.sstatus.
It's probably simplest to proceed as in /netlib/ampl/solvers/minos/m55.c:
having declared
int *varstat;
SufDesc *csd, *vsd;
and having computed NB = M + N, where M >= n_con and N >= n_var are the
numbers of constraints and variables (possibly adjusted, depending on the
needs of your solver -- for example, some solvers require adding an
extra variable and possibly an extra constraint to add a constant term
to the objective values that they report if they're asked to print
progress lines during their solution process), you allocate storage
for the .sstatus values by (something equivalent to)
varstat = (int*)M1alloc(NB*sizeof(int));
vsd = suf_iput("sstatus", ASL_Sufkind_var, varstat);
csd = suf_iput("sstatus", ASL_Sufkind_con, varstat + N);
before invoking the .nl reader. After calling the reader, deal
appropriately with the incoming .sstatus values, if present:
if (vsd->kind & ASL_Sufkind_input)
then you have incoming variable.sstatus values in array varstat
(the third argument to suf_iput); similarly,
if (csd->kind & ASL_Sufkind_input)
then you have incoming constraint.sstatus values (which, in the
above example, are in varstat+N, though you might wish to give
a separate name to this array). The values are encoded as in
the first column of AMPL's default $sstatus_table:
0 none no status assigned
1 bas basic
2 sup superbasic
3 low nonbasic <= (normally =) lower bound
4 upp nonbasic >= (normally =) upper bound
5 equ nonbasic at equal lower and upper bounds
6 btw nonbasic between bounds
After solving the problem and before calling write_sol (which will
transmit the suffix arrays mentioned in previous suf_iput and, for
real, i.e., double, values, suf_rput calls), translate your basis
information to values in the outgoing status arrays that accord with
the above table.
For returning real (floating-point) suffix values, call suf_rput
rather than suf_iput. Examples (for sensitivity information, i.e.,
suffixes .up, .current, and .down) appear in the cplex.c and osl.c
files mentioned above.
Another detail not yet documented in "Hooking Your Solver..." is that
you should assign a solve_result_num value to indicate success,
failure, iteration limit, etc. before calling write_sol. This is
an integer value in one of the ranges indicated by AMPL's default
$solve_result_table:
0 solved
100 solved?
200 infeasible
300 unbounded
400 limit
500 failure
For successful solves, solve_result_num should thus be an integer
in [0,99]. If the problem might be solved, but tolerances may have
been too tight to satisfy all stopping tests, assign an integer in
[100,199], etc. -- any value >= 500 indicates failure (such as
insufficient memory). Then AMPL's symbolic solve_result will be
assigned one of the values in the second column of the above table,
and scripts that need more detail can base tests on solve_result_num.
Many of the sample solver interfaces appearing in subdirectories
of netlib's ampl/solvers directory make use of suffixes and supply
solve_result_num.