alpar@1
|
1 |
/* glpios.h (integer optimization suite) */
|
alpar@1
|
2 |
|
alpar@1
|
3 |
/***********************************************************************
|
alpar@1
|
4 |
* This code is part of GLPK (GNU Linear Programming Kit).
|
alpar@1
|
5 |
*
|
alpar@1
|
6 |
* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
alpar@1
|
7 |
* 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
|
alpar@1
|
8 |
* Moscow Aviation Institute, Moscow, Russia. All rights reserved.
|
alpar@1
|
9 |
* E-mail: <mao@gnu.org>.
|
alpar@1
|
10 |
*
|
alpar@1
|
11 |
* GLPK is free software: you can redistribute it and/or modify it
|
alpar@1
|
12 |
* under the terms of the GNU General Public License as published by
|
alpar@1
|
13 |
* the Free Software Foundation, either version 3 of the License, or
|
alpar@1
|
14 |
* (at your option) any later version.
|
alpar@1
|
15 |
*
|
alpar@1
|
16 |
* GLPK is distributed in the hope that it will be useful, but WITHOUT
|
alpar@1
|
17 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
alpar@1
|
18 |
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
alpar@1
|
19 |
* License for more details.
|
alpar@1
|
20 |
*
|
alpar@1
|
21 |
* You should have received a copy of the GNU General Public License
|
alpar@1
|
22 |
* along with GLPK. If not, see <http://www.gnu.org/licenses/>.
|
alpar@1
|
23 |
***********************************************************************/
|
alpar@1
|
24 |
|
alpar@1
|
25 |
#ifndef GLPIOS_H
|
alpar@1
|
26 |
#define GLPIOS_H
|
alpar@1
|
27 |
|
alpar@1
|
28 |
#define GLP_TREE_DEFINED
|
alpar@1
|
29 |
typedef struct glp_tree glp_tree;
|
alpar@1
|
30 |
|
alpar@1
|
31 |
#include "glpapi.h"
|
alpar@1
|
32 |
|
alpar@1
|
33 |
typedef struct IOSLOT IOSLOT;
|
alpar@1
|
34 |
typedef struct IOSNPD IOSNPD;
|
alpar@1
|
35 |
typedef struct IOSBND IOSBND;
|
alpar@1
|
36 |
typedef struct IOSTAT IOSTAT;
|
alpar@1
|
37 |
typedef struct IOSROW IOSROW;
|
alpar@1
|
38 |
typedef struct IOSAIJ IOSAIJ;
|
alpar@1
|
39 |
typedef struct IOSPOOL IOSPOOL;
|
alpar@1
|
40 |
typedef struct IOSCUT IOSCUT;
|
alpar@1
|
41 |
|
alpar@1
|
42 |
struct glp_tree
|
alpar@1
|
43 |
{ /* branch-and-bound tree */
|
alpar@1
|
44 |
int magic;
|
alpar@1
|
45 |
/* magic value used for debugging */
|
alpar@1
|
46 |
DMP *pool;
|
alpar@1
|
47 |
/* memory pool to store all IOS components */
|
alpar@1
|
48 |
int n;
|
alpar@1
|
49 |
/* number of columns (variables) */
|
alpar@1
|
50 |
/*--------------------------------------------------------------*/
|
alpar@1
|
51 |
/* problem components corresponding to the original MIP and its
|
alpar@1
|
52 |
LP relaxation (used to restore the original problem object on
|
alpar@1
|
53 |
exit from the solver) */
|
alpar@1
|
54 |
int orig_m;
|
alpar@1
|
55 |
/* number of rows */
|
alpar@1
|
56 |
unsigned char *orig_type; /* uchar orig_type[1+orig_m+n]; */
|
alpar@1
|
57 |
/* types of all variables */
|
alpar@1
|
58 |
double *orig_lb; /* double orig_lb[1+orig_m+n]; */
|
alpar@1
|
59 |
/* lower bounds of all variables */
|
alpar@1
|
60 |
double *orig_ub; /* double orig_ub[1+orig_m+n]; */
|
alpar@1
|
61 |
/* upper bounds of all variables */
|
alpar@1
|
62 |
unsigned char *orig_stat; /* uchar orig_stat[1+orig_m+n]; */
|
alpar@1
|
63 |
/* statuses of all variables */
|
alpar@1
|
64 |
double *orig_prim; /* double orig_prim[1+orig_m+n]; */
|
alpar@1
|
65 |
/* primal values of all variables */
|
alpar@1
|
66 |
double *orig_dual; /* double orig_dual[1+orig_m+n]; */
|
alpar@1
|
67 |
/* dual values of all variables */
|
alpar@1
|
68 |
double orig_obj;
|
alpar@1
|
69 |
/* optimal objective value for LP relaxation */
|
alpar@1
|
70 |
/*--------------------------------------------------------------*/
|
alpar@1
|
71 |
/* branch-and-bound tree */
|
alpar@1
|
72 |
int nslots;
|
alpar@1
|
73 |
/* length of the array of slots (enlarged automatically) */
|
alpar@1
|
74 |
int avail;
|
alpar@1
|
75 |
/* index of the first free slot; 0 means all slots are in use */
|
alpar@1
|
76 |
IOSLOT *slot; /* IOSLOT slot[1+nslots]; */
|
alpar@1
|
77 |
/* array of slots:
|
alpar@1
|
78 |
slot[0] is not used;
|
alpar@1
|
79 |
slot[p], 1 <= p <= nslots, either contains a pointer to some
|
alpar@1
|
80 |
node of the branch-and-bound tree, in which case p is used on
|
alpar@1
|
81 |
API level as the reference number of corresponding subproblem,
|
alpar@1
|
82 |
or is free; all free slots are linked into single linked list;
|
alpar@1
|
83 |
slot[1] always contains a pointer to the root node (it is free
|
alpar@1
|
84 |
only if the tree is empty) */
|
alpar@1
|
85 |
IOSNPD *head;
|
alpar@1
|
86 |
/* pointer to the head of the active list */
|
alpar@1
|
87 |
IOSNPD *tail;
|
alpar@1
|
88 |
/* pointer to the tail of the active list */
|
alpar@1
|
89 |
/* the active list is a doubly linked list of active subproblems
|
alpar@1
|
90 |
which correspond to leaves of the tree; all subproblems in the
|
alpar@1
|
91 |
active list are ordered chronologically (each a new subproblem
|
alpar@1
|
92 |
is always added to the tail of the list) */
|
alpar@1
|
93 |
int a_cnt;
|
alpar@1
|
94 |
/* current number of active nodes (including the current one) */
|
alpar@1
|
95 |
int n_cnt;
|
alpar@1
|
96 |
/* current number of all (active and inactive) nodes */
|
alpar@1
|
97 |
int t_cnt;
|
alpar@1
|
98 |
/* total number of nodes including those which have been already
|
alpar@1
|
99 |
removed from the tree; this count is increased by one whenever
|
alpar@1
|
100 |
a new node is created and never decreased */
|
alpar@1
|
101 |
/*--------------------------------------------------------------*/
|
alpar@1
|
102 |
/* problem components corresponding to the root subproblem */
|
alpar@1
|
103 |
int root_m;
|
alpar@1
|
104 |
/* number of rows */
|
alpar@1
|
105 |
unsigned char *root_type; /* uchar root_type[1+root_m+n]; */
|
alpar@1
|
106 |
/* types of all variables */
|
alpar@1
|
107 |
double *root_lb; /* double root_lb[1+root_m+n]; */
|
alpar@1
|
108 |
/* lower bounds of all variables */
|
alpar@1
|
109 |
double *root_ub; /* double root_ub[1+root_m+n]; */
|
alpar@1
|
110 |
/* upper bounds of all variables */
|
alpar@1
|
111 |
unsigned char *root_stat; /* uchar root_stat[1+root_m+n]; */
|
alpar@1
|
112 |
/* statuses of all variables */
|
alpar@1
|
113 |
/*--------------------------------------------------------------*/
|
alpar@1
|
114 |
/* current subproblem and its LP relaxation */
|
alpar@1
|
115 |
IOSNPD *curr;
|
alpar@1
|
116 |
/* pointer to the current subproblem (which can be only active);
|
alpar@1
|
117 |
NULL means the current subproblem does not exist */
|
alpar@1
|
118 |
glp_prob *mip;
|
alpar@1
|
119 |
/* original problem object passed to the solver; if the current
|
alpar@1
|
120 |
subproblem exists, its LP segment corresponds to LP relaxation
|
alpar@1
|
121 |
of the current subproblem; if the current subproblem does not
|
alpar@1
|
122 |
exist, its LP segment corresponds to LP relaxation of the root
|
alpar@1
|
123 |
subproblem (note that the root subproblem may differ from the
|
alpar@1
|
124 |
original MIP, because it may be preprocessed and/or may have
|
alpar@1
|
125 |
additional rows) */
|
alpar@1
|
126 |
unsigned char *non_int; /* uchar non_int[1+n]; */
|
alpar@1
|
127 |
/* these column flags are set each time when LP relaxation of the
|
alpar@1
|
128 |
current subproblem has been solved;
|
alpar@1
|
129 |
non_int[0] is not used;
|
alpar@1
|
130 |
non_int[j], 1 <= j <= n, is j-th column flag; if this flag is
|
alpar@1
|
131 |
set, corresponding variable is required to be integer, but its
|
alpar@1
|
132 |
value in basic solution is fractional */
|
alpar@1
|
133 |
/*--------------------------------------------------------------*/
|
alpar@1
|
134 |
/* problem components corresponding to the parent (predecessor)
|
alpar@1
|
135 |
subproblem for the current subproblem; used to inspect changes
|
alpar@1
|
136 |
on freezing the current subproblem */
|
alpar@1
|
137 |
int pred_m;
|
alpar@1
|
138 |
/* number of rows */
|
alpar@1
|
139 |
int pred_max;
|
alpar@1
|
140 |
/* length of the following four arrays (enlarged automatically),
|
alpar@1
|
141 |
pred_max >= pred_m + n */
|
alpar@1
|
142 |
unsigned char *pred_type; /* uchar pred_type[1+pred_m+n]; */
|
alpar@1
|
143 |
/* types of all variables */
|
alpar@1
|
144 |
double *pred_lb; /* double pred_lb[1+pred_m+n]; */
|
alpar@1
|
145 |
/* lower bounds of all variables */
|
alpar@1
|
146 |
double *pred_ub; /* double pred_ub[1+pred_m+n]; */
|
alpar@1
|
147 |
/* upper bounds of all variables */
|
alpar@1
|
148 |
unsigned char *pred_stat; /* uchar pred_stat[1+pred_m+n]; */
|
alpar@1
|
149 |
/* statuses of all variables */
|
alpar@1
|
150 |
/****************************************************************/
|
alpar@1
|
151 |
/* built-in cut generators segment */
|
alpar@1
|
152 |
IOSPOOL *local;
|
alpar@1
|
153 |
/* local cut pool */
|
alpar@1
|
154 |
void *mir_gen;
|
alpar@1
|
155 |
/* pointer to working area used by the MIR cut generator */
|
alpar@1
|
156 |
void *clq_gen;
|
alpar@1
|
157 |
/* pointer to working area used by the clique cut generator */
|
alpar@1
|
158 |
/*--------------------------------------------------------------*/
|
alpar@1
|
159 |
void *pcost;
|
alpar@1
|
160 |
/* pointer to working area used on pseudocost branching */
|
alpar@1
|
161 |
int *iwrk; /* int iwrk[1+n]; */
|
alpar@1
|
162 |
/* working array */
|
alpar@1
|
163 |
double *dwrk; /* double dwrk[1+n]; */
|
alpar@1
|
164 |
/* working array */
|
alpar@1
|
165 |
/*--------------------------------------------------------------*/
|
alpar@1
|
166 |
/* control parameters and statistics */
|
alpar@1
|
167 |
const glp_iocp *parm;
|
alpar@1
|
168 |
/* copy of control parameters passed to the solver */
|
alpar@1
|
169 |
glp_long tm_beg;
|
alpar@1
|
170 |
/* starting time of the search, in seconds; the total time of the
|
alpar@1
|
171 |
search is the difference between xtime() and tm_beg */
|
alpar@1
|
172 |
glp_long tm_lag;
|
alpar@1
|
173 |
/* the most recent time, in seconds, at which the progress of the
|
alpar@1
|
174 |
the search was displayed */
|
alpar@1
|
175 |
int sol_cnt;
|
alpar@1
|
176 |
/* number of integer feasible solutions found */
|
alpar@1
|
177 |
/*--------------------------------------------------------------*/
|
alpar@1
|
178 |
/* advanced solver interface */
|
alpar@1
|
179 |
int reason;
|
alpar@1
|
180 |
/* flag indicating the reason why the callback routine is being
|
alpar@1
|
181 |
called (see glpk.h) */
|
alpar@1
|
182 |
int stop;
|
alpar@1
|
183 |
/* flag indicating that the callback routine requires premature
|
alpar@1
|
184 |
termination of the search */
|
alpar@1
|
185 |
int next_p;
|
alpar@1
|
186 |
/* reference number of active subproblem selected to continue
|
alpar@1
|
187 |
the search; 0 means no subproblem has been selected */
|
alpar@1
|
188 |
int reopt;
|
alpar@1
|
189 |
/* flag indicating that the current LP relaxation needs to be
|
alpar@1
|
190 |
re-optimized */
|
alpar@1
|
191 |
int reinv;
|
alpar@1
|
192 |
/* flag indicating that some (non-active) rows were removed from
|
alpar@1
|
193 |
the current LP relaxation, so if there no new rows appear, the
|
alpar@1
|
194 |
basis must be re-factorized */
|
alpar@1
|
195 |
int br_var;
|
alpar@1
|
196 |
/* the number of variable chosen to branch on */
|
alpar@1
|
197 |
int br_sel;
|
alpar@1
|
198 |
/* flag indicating which branch (subproblem) is suggested to be
|
alpar@1
|
199 |
selected to continue the search:
|
alpar@1
|
200 |
GLP_DN_BRNCH - select down-branch
|
alpar@1
|
201 |
GLP_UP_BRNCH - select up-branch
|
alpar@1
|
202 |
GLP_NO_BRNCH - use general selection technique */
|
alpar@1
|
203 |
int child;
|
alpar@1
|
204 |
/* subproblem reference number corresponding to br_sel */
|
alpar@1
|
205 |
};
|
alpar@1
|
206 |
|
alpar@1
|
207 |
struct IOSLOT
|
alpar@1
|
208 |
{ /* node subproblem slot */
|
alpar@1
|
209 |
IOSNPD *node;
|
alpar@1
|
210 |
/* pointer to subproblem descriptor; NULL means free slot */
|
alpar@1
|
211 |
int next;
|
alpar@1
|
212 |
/* index of another free slot (only if this slot is free) */
|
alpar@1
|
213 |
};
|
alpar@1
|
214 |
|
alpar@1
|
215 |
struct IOSNPD
|
alpar@1
|
216 |
{ /* node subproblem descriptor */
|
alpar@1
|
217 |
int p;
|
alpar@1
|
218 |
/* subproblem reference number (it is the index to corresponding
|
alpar@1
|
219 |
slot, i.e. slot[p] points to this descriptor) */
|
alpar@1
|
220 |
IOSNPD *up;
|
alpar@1
|
221 |
/* pointer to the parent subproblem; NULL means this node is the
|
alpar@1
|
222 |
root of the tree, in which case p = 1 */
|
alpar@1
|
223 |
int level;
|
alpar@1
|
224 |
/* node level (the root node has level 0) */
|
alpar@1
|
225 |
int count;
|
alpar@1
|
226 |
/* if count = 0, this subproblem is active; if count > 0, this
|
alpar@1
|
227 |
subproblem is inactive, in which case count is the number of
|
alpar@1
|
228 |
its child subproblems */
|
alpar@1
|
229 |
/* the following three linked lists are destroyed on reviving and
|
alpar@1
|
230 |
built anew on freezing the subproblem: */
|
alpar@1
|
231 |
IOSBND *b_ptr;
|
alpar@1
|
232 |
/* linked list of rows and columns of the parent subproblem whose
|
alpar@1
|
233 |
types and bounds were changed */
|
alpar@1
|
234 |
IOSTAT *s_ptr;
|
alpar@1
|
235 |
/* linked list of rows and columns of the parent subproblem whose
|
alpar@1
|
236 |
statuses were changed */
|
alpar@1
|
237 |
IOSROW *r_ptr;
|
alpar@1
|
238 |
/* linked list of rows (cuts) added to the parent subproblem */
|
alpar@1
|
239 |
int solved;
|
alpar@1
|
240 |
/* how many times LP relaxation of this subproblem was solved;
|
alpar@1
|
241 |
for inactive subproblem this count is always non-zero;
|
alpar@1
|
242 |
for active subproblem, which is not current, this count may be
|
alpar@1
|
243 |
non-zero, if the subproblem was temporarily suspended */
|
alpar@1
|
244 |
double lp_obj;
|
alpar@1
|
245 |
/* optimal objective value to LP relaxation of this subproblem;
|
alpar@1
|
246 |
on creating a subproblem this value is inherited from its
|
alpar@1
|
247 |
parent; for the root subproblem, which has no parent, this
|
alpar@1
|
248 |
value is initially set to -DBL_MAX (minimization) or +DBL_MAX
|
alpar@1
|
249 |
(maximization); each time the subproblem is re-optimized, this
|
alpar@1
|
250 |
value is appropriately changed */
|
alpar@1
|
251 |
double bound;
|
alpar@1
|
252 |
/* local lower (minimization) or upper (maximization) bound for
|
alpar@1
|
253 |
integer optimal solution to *this* subproblem; this bound is
|
alpar@1
|
254 |
local in the sense that only subproblems in the subtree rooted
|
alpar@1
|
255 |
at this node cannot have better integer feasible solutions;
|
alpar@1
|
256 |
on creating a subproblem its local bound is inherited from its
|
alpar@1
|
257 |
parent and then can be made stronger (never weaker); for the
|
alpar@1
|
258 |
root subproblem its local bound is initially set to -DBL_MAX
|
alpar@1
|
259 |
(minimization) or +DBL_MAX (maximization) and then improved as
|
alpar@1
|
260 |
the root LP relaxation has been solved */
|
alpar@1
|
261 |
/* the following two quantities are defined only if LP relaxation
|
alpar@1
|
262 |
of this subproblem was solved at least once (solved > 0): */
|
alpar@1
|
263 |
int ii_cnt;
|
alpar@1
|
264 |
/* number of integer variables whose value in optimal solution to
|
alpar@1
|
265 |
LP relaxation of this subproblem is fractional */
|
alpar@1
|
266 |
double ii_sum;
|
alpar@1
|
267 |
/* sum of integer infeasibilities */
|
alpar@1
|
268 |
#if 1 /* 30/XI-2009 */
|
alpar@1
|
269 |
int changed;
|
alpar@1
|
270 |
/* how many times this subproblem was re-formulated (by adding
|
alpar@1
|
271 |
cutting plane constraints) */
|
alpar@1
|
272 |
#endif
|
alpar@1
|
273 |
int br_var;
|
alpar@1
|
274 |
/* ordinal number of branching variable, 1 <= br_var <= n, used
|
alpar@1
|
275 |
to split this subproblem; 0 means that either this subproblem
|
alpar@1
|
276 |
is active or branching was made on a constraint */
|
alpar@1
|
277 |
double br_val;
|
alpar@1
|
278 |
/* (fractional) value of branching variable in optimal solution
|
alpar@1
|
279 |
to final LP relaxation of this subproblem */
|
alpar@1
|
280 |
void *data; /* char data[tree->cb_size]; */
|
alpar@1
|
281 |
/* pointer to the application-specific data */
|
alpar@1
|
282 |
IOSNPD *temp;
|
alpar@1
|
283 |
/* working pointer used by some routines */
|
alpar@1
|
284 |
IOSNPD *prev;
|
alpar@1
|
285 |
/* pointer to previous subproblem in the active list */
|
alpar@1
|
286 |
IOSNPD *next;
|
alpar@1
|
287 |
/* pointer to next subproblem in the active list */
|
alpar@1
|
288 |
};
|
alpar@1
|
289 |
|
alpar@1
|
290 |
struct IOSBND
|
alpar@1
|
291 |
{ /* bounds change entry */
|
alpar@1
|
292 |
int k;
|
alpar@1
|
293 |
/* ordinal number of corresponding row (1 <= k <= m) or column
|
alpar@1
|
294 |
(m+1 <= k <= m+n), where m and n are the number of rows and
|
alpar@1
|
295 |
columns, resp., in the parent subproblem */
|
alpar@1
|
296 |
unsigned char type;
|
alpar@1
|
297 |
/* new type */
|
alpar@1
|
298 |
double lb;
|
alpar@1
|
299 |
/* new lower bound */
|
alpar@1
|
300 |
double ub;
|
alpar@1
|
301 |
/* new upper bound */
|
alpar@1
|
302 |
IOSBND *next;
|
alpar@1
|
303 |
/* pointer to next entry for the same subproblem */
|
alpar@1
|
304 |
};
|
alpar@1
|
305 |
|
alpar@1
|
306 |
struct IOSTAT
|
alpar@1
|
307 |
{ /* status change entry */
|
alpar@1
|
308 |
int k;
|
alpar@1
|
309 |
/* ordinal number of corresponding row (1 <= k <= m) or column
|
alpar@1
|
310 |
(m+1 <= k <= m+n), where m and n are the number of rows and
|
alpar@1
|
311 |
columns, resp., in the parent subproblem */
|
alpar@1
|
312 |
unsigned char stat;
|
alpar@1
|
313 |
/* new status */
|
alpar@1
|
314 |
IOSTAT *next;
|
alpar@1
|
315 |
/* pointer to next entry for the same subproblem */
|
alpar@1
|
316 |
};
|
alpar@1
|
317 |
|
alpar@1
|
318 |
struct IOSROW
|
alpar@1
|
319 |
{ /* row (constraint) addition entry */
|
alpar@1
|
320 |
char *name;
|
alpar@1
|
321 |
/* row name or NULL */
|
alpar@1
|
322 |
unsigned char origin;
|
alpar@1
|
323 |
/* row origin flag (see glp_attr.origin) */
|
alpar@1
|
324 |
unsigned char klass;
|
alpar@1
|
325 |
/* row class descriptor (see glp_attr.klass) */
|
alpar@1
|
326 |
unsigned char type;
|
alpar@1
|
327 |
/* row type (GLP_LO, GLP_UP, etc.) */
|
alpar@1
|
328 |
double lb;
|
alpar@1
|
329 |
/* row lower bound */
|
alpar@1
|
330 |
double ub;
|
alpar@1
|
331 |
/* row upper bound */
|
alpar@1
|
332 |
IOSAIJ *ptr;
|
alpar@1
|
333 |
/* pointer to the row coefficient list */
|
alpar@1
|
334 |
double rii;
|
alpar@1
|
335 |
/* row scale factor */
|
alpar@1
|
336 |
unsigned char stat;
|
alpar@1
|
337 |
/* row status (GLP_BS, GLP_NL, etc.) */
|
alpar@1
|
338 |
IOSROW *next;
|
alpar@1
|
339 |
/* pointer to next entry for the same subproblem */
|
alpar@1
|
340 |
};
|
alpar@1
|
341 |
|
alpar@1
|
342 |
struct IOSAIJ
|
alpar@1
|
343 |
{ /* constraint coefficient */
|
alpar@1
|
344 |
int j;
|
alpar@1
|
345 |
/* variable (column) number, 1 <= j <= n */
|
alpar@1
|
346 |
double val;
|
alpar@1
|
347 |
/* non-zero coefficient value */
|
alpar@1
|
348 |
IOSAIJ *next;
|
alpar@1
|
349 |
/* pointer to next coefficient for the same row */
|
alpar@1
|
350 |
};
|
alpar@1
|
351 |
|
alpar@1
|
352 |
struct IOSPOOL
|
alpar@1
|
353 |
{ /* cut pool */
|
alpar@1
|
354 |
int size;
|
alpar@1
|
355 |
/* pool size = number of cuts in the pool */
|
alpar@1
|
356 |
IOSCUT *head;
|
alpar@1
|
357 |
/* pointer to the first cut */
|
alpar@1
|
358 |
IOSCUT *tail;
|
alpar@1
|
359 |
/* pointer to the last cut */
|
alpar@1
|
360 |
int ord;
|
alpar@1
|
361 |
/* ordinal number of the current cut, 1 <= ord <= size */
|
alpar@1
|
362 |
IOSCUT *curr;
|
alpar@1
|
363 |
/* pointer to the current cut */
|
alpar@1
|
364 |
};
|
alpar@1
|
365 |
|
alpar@1
|
366 |
struct IOSCUT
|
alpar@1
|
367 |
{ /* cut (cutting plane constraint) */
|
alpar@1
|
368 |
char *name;
|
alpar@1
|
369 |
/* cut name or NULL */
|
alpar@1
|
370 |
unsigned char klass;
|
alpar@1
|
371 |
/* cut class descriptor (see glp_attr.klass) */
|
alpar@1
|
372 |
IOSAIJ *ptr;
|
alpar@1
|
373 |
/* pointer to the cut coefficient list */
|
alpar@1
|
374 |
unsigned char type;
|
alpar@1
|
375 |
/* cut type:
|
alpar@1
|
376 |
GLP_LO: sum a[j] * x[j] >= b
|
alpar@1
|
377 |
GLP_UP: sum a[j] * x[j] <= b
|
alpar@1
|
378 |
GLP_FX: sum a[j] * x[j] = b */
|
alpar@1
|
379 |
double rhs;
|
alpar@1
|
380 |
/* cut right-hand side */
|
alpar@1
|
381 |
IOSCUT *prev;
|
alpar@1
|
382 |
/* pointer to previous cut */
|
alpar@1
|
383 |
IOSCUT *next;
|
alpar@1
|
384 |
/* pointer to next cut */
|
alpar@1
|
385 |
};
|
alpar@1
|
386 |
|
alpar@1
|
387 |
#define ios_create_tree _glp_ios_create_tree
|
alpar@1
|
388 |
glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm);
|
alpar@1
|
389 |
/* create branch-and-bound tree */
|
alpar@1
|
390 |
|
alpar@1
|
391 |
#define ios_revive_node _glp_ios_revive_node
|
alpar@1
|
392 |
void ios_revive_node(glp_tree *tree, int p);
|
alpar@1
|
393 |
/* revive specified subproblem */
|
alpar@1
|
394 |
|
alpar@1
|
395 |
#define ios_freeze_node _glp_ios_freeze_node
|
alpar@1
|
396 |
void ios_freeze_node(glp_tree *tree);
|
alpar@1
|
397 |
/* freeze current subproblem */
|
alpar@1
|
398 |
|
alpar@1
|
399 |
#define ios_clone_node _glp_ios_clone_node
|
alpar@1
|
400 |
void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]);
|
alpar@1
|
401 |
/* clone specified subproblem */
|
alpar@1
|
402 |
|
alpar@1
|
403 |
#define ios_delete_node _glp_ios_delete_node
|
alpar@1
|
404 |
void ios_delete_node(glp_tree *tree, int p);
|
alpar@1
|
405 |
/* delete specified subproblem */
|
alpar@1
|
406 |
|
alpar@1
|
407 |
#define ios_delete_tree _glp_ios_delete_tree
|
alpar@1
|
408 |
void ios_delete_tree(glp_tree *tree);
|
alpar@1
|
409 |
/* delete branch-and-bound tree */
|
alpar@1
|
410 |
|
alpar@1
|
411 |
#define ios_eval_degrad _glp_ios_eval_degrad
|
alpar@1
|
412 |
void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up);
|
alpar@1
|
413 |
/* estimate obj. degrad. for down- and up-branches */
|
alpar@1
|
414 |
|
alpar@1
|
415 |
#define ios_round_bound _glp_ios_round_bound
|
alpar@1
|
416 |
double ios_round_bound(glp_tree *tree, double bound);
|
alpar@1
|
417 |
/* improve local bound by rounding */
|
alpar@1
|
418 |
|
alpar@1
|
419 |
#define ios_is_hopeful _glp_ios_is_hopeful
|
alpar@1
|
420 |
int ios_is_hopeful(glp_tree *tree, double bound);
|
alpar@1
|
421 |
/* check if subproblem is hopeful */
|
alpar@1
|
422 |
|
alpar@1
|
423 |
#define ios_best_node _glp_ios_best_node
|
alpar@1
|
424 |
int ios_best_node(glp_tree *tree);
|
alpar@1
|
425 |
/* find active node with best local bound */
|
alpar@1
|
426 |
|
alpar@1
|
427 |
#define ios_relative_gap _glp_ios_relative_gap
|
alpar@1
|
428 |
double ios_relative_gap(glp_tree *tree);
|
alpar@1
|
429 |
/* compute relative mip gap */
|
alpar@1
|
430 |
|
alpar@1
|
431 |
#define ios_solve_node _glp_ios_solve_node
|
alpar@1
|
432 |
int ios_solve_node(glp_tree *tree);
|
alpar@1
|
433 |
/* solve LP relaxation of current subproblem */
|
alpar@1
|
434 |
|
alpar@1
|
435 |
#define ios_create_pool _glp_ios_create_pool
|
alpar@1
|
436 |
IOSPOOL *ios_create_pool(glp_tree *tree);
|
alpar@1
|
437 |
/* create cut pool */
|
alpar@1
|
438 |
|
alpar@1
|
439 |
#define ios_add_row _glp_ios_add_row
|
alpar@1
|
440 |
int ios_add_row(glp_tree *tree, IOSPOOL *pool,
|
alpar@1
|
441 |
const char *name, int klass, int flags, int len, const int ind[],
|
alpar@1
|
442 |
const double val[], int type, double rhs);
|
alpar@1
|
443 |
/* add row (constraint) to the cut pool */
|
alpar@1
|
444 |
|
alpar@1
|
445 |
#define ios_find_row _glp_ios_find_row
|
alpar@1
|
446 |
IOSCUT *ios_find_row(IOSPOOL *pool, int i);
|
alpar@1
|
447 |
/* find row (constraint) in the cut pool */
|
alpar@1
|
448 |
|
alpar@1
|
449 |
#define ios_del_row _glp_ios_del_row
|
alpar@1
|
450 |
void ios_del_row(glp_tree *tree, IOSPOOL *pool, int i);
|
alpar@1
|
451 |
/* remove row (constraint) from the cut pool */
|
alpar@1
|
452 |
|
alpar@1
|
453 |
#define ios_clear_pool _glp_ios_clear_pool
|
alpar@1
|
454 |
void ios_clear_pool(glp_tree *tree, IOSPOOL *pool);
|
alpar@1
|
455 |
/* remove all rows (constraints) from the cut pool */
|
alpar@1
|
456 |
|
alpar@1
|
457 |
#define ios_delete_pool _glp_ios_delete_pool
|
alpar@1
|
458 |
void ios_delete_pool(glp_tree *tree, IOSPOOL *pool);
|
alpar@1
|
459 |
/* delete cut pool */
|
alpar@1
|
460 |
|
alpar@1
|
461 |
#define ios_preprocess_node _glp_ios_preprocess_node
|
alpar@1
|
462 |
int ios_preprocess_node(glp_tree *tree, int max_pass);
|
alpar@1
|
463 |
/* preprocess current subproblem */
|
alpar@1
|
464 |
|
alpar@1
|
465 |
#define ios_driver _glp_ios_driver
|
alpar@1
|
466 |
int ios_driver(glp_tree *tree);
|
alpar@1
|
467 |
/* branch-and-bound driver */
|
alpar@1
|
468 |
|
alpar@1
|
469 |
/**********************************************************************/
|
alpar@1
|
470 |
|
alpar@1
|
471 |
typedef struct IOSVEC IOSVEC;
|
alpar@1
|
472 |
|
alpar@1
|
473 |
struct IOSVEC
|
alpar@1
|
474 |
{ /* sparse vector v = (v[j]) */
|
alpar@1
|
475 |
int n;
|
alpar@1
|
476 |
/* dimension, n >= 0 */
|
alpar@1
|
477 |
int nnz;
|
alpar@1
|
478 |
/* number of non-zero components, 0 <= nnz <= n */
|
alpar@1
|
479 |
int *pos; /* int pos[1+n]; */
|
alpar@1
|
480 |
/* pos[j] = k, 1 <= j <= n, is position of (non-zero) v[j] in the
|
alpar@1
|
481 |
arrays ind and val, where 1 <= k <= nnz; pos[j] = 0 means that
|
alpar@1
|
482 |
v[j] is structural zero */
|
alpar@1
|
483 |
int *ind; /* int ind[1+n]; */
|
alpar@1
|
484 |
/* ind[k] = j, 1 <= k <= nnz, is index of v[j] */
|
alpar@1
|
485 |
double *val; /* double val[1+n]; */
|
alpar@1
|
486 |
/* val[k], 1 <= k <= nnz, is a numeric value of v[j] */
|
alpar@1
|
487 |
};
|
alpar@1
|
488 |
|
alpar@1
|
489 |
#define ios_create_vec _glp_ios_create_vec
|
alpar@1
|
490 |
IOSVEC *ios_create_vec(int n);
|
alpar@1
|
491 |
/* create sparse vector */
|
alpar@1
|
492 |
|
alpar@1
|
493 |
#define ios_check_vec _glp_ios_check_vec
|
alpar@1
|
494 |
void ios_check_vec(IOSVEC *v);
|
alpar@1
|
495 |
/* check that sparse vector has correct representation */
|
alpar@1
|
496 |
|
alpar@1
|
497 |
#define ios_get_vj _glp_ios_get_vj
|
alpar@1
|
498 |
double ios_get_vj(IOSVEC *v, int j);
|
alpar@1
|
499 |
/* retrieve component of sparse vector */
|
alpar@1
|
500 |
|
alpar@1
|
501 |
#define ios_set_vj _glp_ios_set_vj
|
alpar@1
|
502 |
void ios_set_vj(IOSVEC *v, int j, double val);
|
alpar@1
|
503 |
/* set/change component of sparse vector */
|
alpar@1
|
504 |
|
alpar@1
|
505 |
#define ios_clear_vec _glp_ios_clear_vec
|
alpar@1
|
506 |
void ios_clear_vec(IOSVEC *v);
|
alpar@1
|
507 |
/* set all components of sparse vector to zero */
|
alpar@1
|
508 |
|
alpar@1
|
509 |
#define ios_clean_vec _glp_ios_clean_vec
|
alpar@1
|
510 |
void ios_clean_vec(IOSVEC *v, double eps);
|
alpar@1
|
511 |
/* remove zero or small components from sparse vector */
|
alpar@1
|
512 |
|
alpar@1
|
513 |
#define ios_copy_vec _glp_ios_copy_vec
|
alpar@1
|
514 |
void ios_copy_vec(IOSVEC *x, IOSVEC *y);
|
alpar@1
|
515 |
/* copy sparse vector (x := y) */
|
alpar@1
|
516 |
|
alpar@1
|
517 |
#define ios_linear_comb _glp_ios_linear_comb
|
alpar@1
|
518 |
void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y);
|
alpar@1
|
519 |
/* compute linear combination (x := x + a * y) */
|
alpar@1
|
520 |
|
alpar@1
|
521 |
#define ios_delete_vec _glp_ios_delete_vec
|
alpar@1
|
522 |
void ios_delete_vec(IOSVEC *v);
|
alpar@1
|
523 |
/* delete sparse vector */
|
alpar@1
|
524 |
|
alpar@1
|
525 |
/**********************************************************************/
|
alpar@1
|
526 |
|
alpar@1
|
527 |
#define ios_gmi_gen _glp_ios_gmi_gen
|
alpar@1
|
528 |
void ios_gmi_gen(glp_tree *tree);
|
alpar@1
|
529 |
/* generate Gomory's mixed integer cuts */
|
alpar@1
|
530 |
|
alpar@1
|
531 |
#define ios_mir_init _glp_ios_mir_init
|
alpar@1
|
532 |
void *ios_mir_init(glp_tree *tree);
|
alpar@1
|
533 |
/* initialize MIR cut generator */
|
alpar@1
|
534 |
|
alpar@1
|
535 |
#define ios_mir_gen _glp_ios_mir_gen
|
alpar@1
|
536 |
void ios_mir_gen(glp_tree *tree, void *gen);
|
alpar@1
|
537 |
/* generate MIR cuts */
|
alpar@1
|
538 |
|
alpar@1
|
539 |
#define ios_mir_term _glp_ios_mir_term
|
alpar@1
|
540 |
void ios_mir_term(void *gen);
|
alpar@1
|
541 |
/* terminate MIR cut generator */
|
alpar@1
|
542 |
|
alpar@1
|
543 |
#define ios_cov_gen _glp_ios_cov_gen
|
alpar@1
|
544 |
void ios_cov_gen(glp_tree *tree);
|
alpar@1
|
545 |
/* generate mixed cover cuts */
|
alpar@1
|
546 |
|
alpar@1
|
547 |
#define ios_clq_init _glp_ios_clq_init
|
alpar@1
|
548 |
void *ios_clq_init(glp_tree *tree);
|
alpar@1
|
549 |
/* initialize clique cut generator */
|
alpar@1
|
550 |
|
alpar@1
|
551 |
#define ios_clq_gen _glp_ios_clq_gen
|
alpar@1
|
552 |
void ios_clq_gen(glp_tree *tree, void *gen);
|
alpar@1
|
553 |
/* generate clique cuts */
|
alpar@1
|
554 |
|
alpar@1
|
555 |
#define ios_clq_term _glp_ios_clq_term
|
alpar@1
|
556 |
void ios_clq_term(void *gen);
|
alpar@1
|
557 |
/* terminate clique cut generator */
|
alpar@1
|
558 |
|
alpar@1
|
559 |
#define ios_pcost_init _glp_ios_pcost_init
|
alpar@1
|
560 |
void *ios_pcost_init(glp_tree *tree);
|
alpar@1
|
561 |
/* initialize working data used on pseudocost branching */
|
alpar@1
|
562 |
|
alpar@1
|
563 |
#define ios_pcost_branch _glp_ios_pcost_branch
|
alpar@1
|
564 |
int ios_pcost_branch(glp_tree *T, int *next);
|
alpar@1
|
565 |
/* choose branching variable with pseudocost branching */
|
alpar@1
|
566 |
|
alpar@1
|
567 |
#define ios_pcost_update _glp_ios_pcost_update
|
alpar@1
|
568 |
void ios_pcost_update(glp_tree *tree);
|
alpar@1
|
569 |
/* update history information for pseudocost branching */
|
alpar@1
|
570 |
|
alpar@1
|
571 |
#define ios_pcost_free _glp_ios_pcost_free
|
alpar@1
|
572 |
void ios_pcost_free(glp_tree *tree);
|
alpar@1
|
573 |
/* free working area used on pseudocost branching */
|
alpar@1
|
574 |
|
alpar@1
|
575 |
#define ios_feas_pump _glp_ios_feas_pump
|
alpar@1
|
576 |
void ios_feas_pump(glp_tree *T);
|
alpar@1
|
577 |
/* feasibility pump heuristic */
|
alpar@1
|
578 |
|
alpar@1
|
579 |
#define ios_process_cuts _glp_ios_process_cuts
|
alpar@1
|
580 |
void ios_process_cuts(glp_tree *T);
|
alpar@1
|
581 |
/* process cuts stored in the local cut pool */
|
alpar@1
|
582 |
|
alpar@1
|
583 |
#define ios_choose_node _glp_ios_choose_node
|
alpar@1
|
584 |
int ios_choose_node(glp_tree *T);
|
alpar@1
|
585 |
/* select subproblem to continue the search */
|
alpar@1
|
586 |
|
alpar@1
|
587 |
#define ios_choose_var _glp_ios_choose_var
|
alpar@1
|
588 |
int ios_choose_var(glp_tree *T, int *next);
|
alpar@1
|
589 |
/* select variable to branch on */
|
alpar@1
|
590 |
|
alpar@1
|
591 |
#endif
|
alpar@1
|
592 |
|
alpar@1
|
593 |
/* eof */
|