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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
|
/* glpmip.h (branch-and-bound method) */
/*----------------------------------------------------------------------
-- This code is part of GNU Linear Programming Kit (GLPK).
--
-- Copyright (C) 2000, 01, 02, 03, 04, 05, 06 Andrew Makhorin,
-- Department for Applied Informatics, Moscow Aviation Institute,
-- Moscow, Russia. All rights reserved. E-mail: <mao@mai2.rcnet.ru>.
--
-- GLPK is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, or (at your option)
-- any later version.
--
-- GLPK is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
-- License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with GLPK; see the file COPYING. If not, write to the Free
-- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-- 02110-1301, USA.
----------------------------------------------------------------------*/
#ifndef _GLPMIP_H
#define _GLPMIP_H
#include "glplpx.h"
#define mip_create_tree glp_mip_create_tree
#define mip_revive_node glp_mip_revive_node
#define mip_freeze_node glp_mip_freeze_node
#define mip_clone_node glp_mip_clone_node
#define mip_delete_node glp_mip_delete_node
#define mip_delete_tree glp_mip_delete_tree
#define mip_pseudo_root glp_mip_pseudo_root
#define mip_best_node glp_mip_best_node
#define mip_relative_gap glp_mip_relative_gap
#define mip_solve_node glp_mip_solve_node
#define mip_driver glp_mip_driver
typedef struct MIPTREE MIPTREE; /* branch-and-bound tree */
typedef struct MIPSLOT MIPSLOT; /* node subproblem slot */
typedef struct MIPNODE MIPNODE; /* node subproblem descriptor */
typedef struct MIPBNDS MIPBNDS; /* bounds change entry */
typedef struct MIPSTAT MIPSTAT; /* status change entry */
struct MIPTREE
{ /* branch-and-bound tree */
/*--------------------------------------------------------------*/
/* global information (valid for all subproblems) */
int m;
/* number of rows */
int n;
/* number of columns */
int dir;
/* optimization direction:
LPX_MIN - minimization
LPX_MAX - maximization */
int int_obj;
/* if this flag is set, the objective function is integral */
int *int_col; /* int int_col[1+n]; */
/* integer column flags;
int_col[0] is not used;
int_col[j], 1 <= j <= n, is the flag of j-th column; if this
flag is set, corresponding structural variable is required to
be integer */
/*--------------------------------------------------------------*/
/* memory management */
DMP *node_pool;
/* memory pool for MIPNODE objects */
DMP *bnds_pool;
/* memory pool for MIPBNDS objects */
DMP *stat_pool;
/* memory pool for MIPSTAT objects */
/*--------------------------------------------------------------*/
/* branch-and-bound tree */
int nslots;
/* length of the array of slots (increased automatically) */
int avail;
/* index of first free slot; 0 means all slots are in use */
MIPSLOT *slot; /* MIPSLOT slot[1+nslots]; */
/* array of slots:
slot[0] is never used;
slot[p], 1 <= p <= nslots, either contains a pointer to some
node of the branch-and-bound tree, in which case p is used on
api level as the reference number of corresponding subproblem,
or is free; all free slots are linked into single linked list;
slot[1] always contains a pointer to the root node (it is free
only if the tree is empty) */
MIPNODE *head;
/* pointer to the head of the active list */
MIPNODE *tail;
/* pointer to the tail of the active list */
/* the active list is a doubly linked list of active subproblems
which correspond to leaves of the tree; all subproblems in the
active list are ordered chronologically (each a new subproblem
is always added to the tail of the list) */
int a_cnt;
/* current number of active nodes (including the current one) */
int n_cnt;
/* current number of all (active and inactive) nodes */
int t_cnt;
/* total number of nodes including those which have been already
removed from the tree; this count is increased whenever a new
node is created and never decreased */
/*--------------------------------------------------------------*/
/* best known integer feasible solution */
int found;
/* if this flag is set, at least one integer feasible solution has
been found */
double best;
/* incumbent objective value, that is the objective value which
corresponds to the best known integer feasible solution (it is
undefined if the flag found is not set); this value is a global
upper (minimization) or lower (maximization) bound for integer
optimal solution of the original problem being solved */
double *mipx; /* double mipx[1+m+n]; */
/* values of auxiliary and structural variables which correspond
to the best known integer feasible solution (these are values
are undefined if the flag found is not set):
mipx[0] is not used;
mipx[i], 1 <= i <= m, is a value of i-th auxiliary variable;
mipx[m+j], 1 <= j <= n, is a value of j-th structural variable
note: if j-th structural variable is required to be integer,
its value mipx[m+j] is provided to be integral */
/*--------------------------------------------------------------*/
/* current subproblem and its LP relaxation */
MIPNODE *curr;
/* pointer to the current subproblem (which can be only active);
NULL means the current subproblem does not exist */
LPX *lp;
/* LP relaxation of the current subproblem (this problem object
contains global data valid for all subproblems, namely, the
sets of rows and columns, objective coefficients, as well as
the constraint matrix; only bounds and statuses of some rows
and/or columns may be changed for a particular subproblem) */
int *old_type; /* int old_type[1+m+n]; */
double *old_lb; /* double old_lb[1+m+n]; */
double *old_ub; /* double old_ub[1+m+n]; */
int *old_stat; /* int old_stat[1+m+n]; */
/* these four arrays contain attributes of rows and columns which
they have in the parent subproblem (types, lower bounds, upper
bounds, and statuses); this information is used to build change
lists on freezing the current subproblem; note that if the root
subproblem is current, standard attributes of rows and columns
are used (all rows are free and basic, all columns are fixed at
zero and non-basic) */
int *non_int; /* int non_int[1+n]; */
/* these column flags are set once LP relaxation of the current
subproblem has been solved;
non_int[0] is not used;
non_int[j], 1 <= j <= n, is the flag of j-th column; if this
flag is set, corresponding structural variable is required to
be integer, but its value in basic solution is fractional */
/*--------------------------------------------------------------*/
/* control parameters and statistics */
int msg_lev;
/* level of messages issued by the solver:
0 - no output
1 - error messages only
2 - normal output
3 - detailed step-by-step output */
int branch; /* MIP */
/* branching heuristic:
0 - branch on first variable
1 - branch on last variable
2 - branch using heuristic by Driebeck and Tomlin
3 - branch on most fractional variable */
int btrack; /* MIP */
/* backtracking heuristic:
0 - select most recent node (depth first search)
1 - select earliest node (breadth first search)
2 - select node using the best projection heuristic
3 - select node with best local bound */
double tol_int;
/* absolute tolerance used to check if the current basic solution
is integer feasible */
double tol_obj;
/* relative tolerance used to check if the value of the objective
function is better than the incumbent objective value */
double tm_lim;
/* searching time limit, in seconds; if this value is positive,
it is decreased whenever one complete round of the search is
performed by the amount of time spent for the round, and
reaching zero value signals the solver to stop the search;
negative value means no time limit */
double out_frq;
/* output frequency, in seconds; this parameter specifies how
frequently the solver sends information about the progress of
the search to the standard output */
double out_dly;
/* output delay, in seconds; this parameter specifies how long
output from the LP solver is delayed on solving LP relaxation
of the current subproblem; zero value means no delay */
double tm_beg;
/* starting time of the search, in seconds; the total time of the
search is the difference between utime() and tm_beg */
double tm_lag;
/* the most recent time, in seconds, at which the progress of the
the search was displayed */
};
struct MIPSLOT
{ /* node subproblem slot */
MIPNODE *node;
/* pointer to subproblem descriptor; NULL means free slot */
int next;
/* index of another free slot (only if this slot is free) */
};
struct MIPNODE
{ /* node subproblem descriptor */
int p;
/* subproblem reference number (it is the index to corresponding
slot, i.e. slot[p] points to this descriptor) */
MIPNODE *up;
/* pointer to parent subproblem; NULL means this node is the root
of the tree, in which case p = 1 */
int level;
/* node level (the root node has level 0) */
int count;
/* if count = 0, this subproblem is active; if count > 0, this
subproblem is inactive, in which case count is the number of
its child subproblems */
MIPBNDS *bnds;
/* linked list of rows and columns whose types and bounds were
changed; this list is destroyed on reviving and built anew on
freezing the subproblem */
MIPSTAT *stat;
/* linked list of rows and columns whose statuses were changed;
this list is destroyed on reviving and built anew on freezing
the subproblem */
double bound;
/* local lower (minimization) or upper (maximization) bound of
integer optimal solution of *this* subproblem; this bound is
local in the sense that only subproblems in the subtree rooted
at this node cannot have better integer feasible solutions;
on creating a subproblem its local bound is inherited from its
parent and then can be made stronger (never weaker); for the
root subproblem its local bound is initially set to -DBL_MAX
(minimization) or +DBL_MAX (maximization) and then improved as
the root LP relaxation has been solved */
/* if this subproblem is inactive, the following two quantities
correspond to final optimal solution of its LP relaxation; for
active subproblems these quantities are undefined */
int ii_cnt;
/* number of columns (structural variables) of integer kind whose
primal values are fractional */
double ii_sum;
/* the sum of integer infeasibilities */
MIPNODE *temp;
/* auxiliary pointer used by some routines */
MIPNODE *prev;
/* pointer to previous subproblem in the active list */
MIPNODE *next;
/* pointer to next subproblem in the active list */
};
struct MIPBNDS
{ /* bounds change entry */
int k;
/* ordinal number of corresponding row (1 <= k <= m) or column
(m+1 <= k <= m+n) */
int type;
/* new type */
double lb;
/* new lower bound */
double ub;
/* new upper bound */
MIPBNDS *next;
/* pointer to next entry for the same subproblem */
};
struct MIPSTAT
{ /* status change entry */
int k;
/* ordinal number of corresponding row (1 <= k <= m) or column
(m+1 <= k <= m+n) */
int stat;
/* new status */
MIPSTAT *next;
/* pointer to next entry for the same subproblem */
};
/* exit codes returned by the routine mip_driver: */
#define MIP_E_OK 1200 /* the search is completed */
#define MIP_E_ITLIM 1201 /* iterations limit exhausted */
#define MIP_E_TMLIM 1202 /* time limit exhausted */
#define MIP_E_ERROR 1203 /* error on solving LP relaxation */
MIPTREE *mip_create_tree(int m, int n, int dir);
/* create branch-and-bound tree */
void mip_revive_node(MIPTREE *tree, int p);
/* revive specified subproblem */
void mip_freeze_node(MIPTREE *tree);
/* freeze current subproblem */
void mip_clone_node(MIPTREE *tree, int p, int nnn, int ref[]);
/* clone specified subproblem */
void mip_delete_node(MIPTREE *tree, int p);
/* delete specified subproblem */
void mip_delete_tree(MIPTREE *tree);
/* delete branch-and-bound tree */
int mip_pseudo_root(MIPTREE *tree);
/* find pseudo-root of the branch-and-bound tree */
int mip_best_node(MIPTREE *tree);
/* find active node with best local bound */
double mip_relative_gap(MIPTREE *tree);
/* compute relative mip gap */
int mip_solve_node(MIPTREE *tree);
/* solve LP relaxation of current subproblem */
int mip_driver(MIPTREE *tree);
/* branch-and-bound driver */
#endif
/* eof */
|