src/glpios03.c
changeset 1 c445c931472f
equal deleted inserted replaced
-1:000000000000 0:81caa67f1337
       
     1 /* glpios03.c (branch-and-cut driver) */
       
     2 
       
     3 /***********************************************************************
       
     4 *  This code is part of GLPK (GNU Linear Programming Kit).
       
     5 *
       
     6 *  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
       
     7 *  2009, 2010 Andrew Makhorin, Department for Applied Informatics,
       
     8 *  Moscow Aviation Institute, Moscow, Russia. All rights reserved.
       
     9 *  E-mail: <mao@gnu.org>.
       
    10 *
       
    11 *  GLPK is free software: you can redistribute it and/or modify it
       
    12 *  under the terms of the GNU General Public License as published by
       
    13 *  the Free Software Foundation, either version 3 of the License, or
       
    14 *  (at your option) any later version.
       
    15 *
       
    16 *  GLPK is distributed in the hope that it will be useful, but WITHOUT
       
    17 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
       
    18 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
       
    19 *  License for more details.
       
    20 *
       
    21 *  You should have received a copy of the GNU General Public License
       
    22 *  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
       
    23 ***********************************************************************/
       
    24 
       
    25 #include "glpios.h"
       
    26 
       
    27 /***********************************************************************
       
    28 *  show_progress - display current progress of the search
       
    29 *
       
    30 *  This routine displays some information about current progress of the
       
    31 *  search.
       
    32 *
       
    33 *  The information includes:
       
    34 *
       
    35 *  the current number of iterations performed by the simplex solver;
       
    36 *
       
    37 *  the objective value for the best known integer feasible solution,
       
    38 *  which is upper (minimization) or lower (maximization) global bound
       
    39 *  for optimal solution of the original mip problem;
       
    40 *
       
    41 *  the best local bound for active nodes, which is lower (minimization)
       
    42 *  or upper (maximization) global bound for optimal solution of the
       
    43 *  original mip problem;
       
    44 *
       
    45 *  the relative mip gap, in percents;
       
    46 *
       
    47 *  the number of open (active) subproblems;
       
    48 *
       
    49 *  the number of completely explored subproblems, i.e. whose nodes have
       
    50 *  been removed from the tree. */
       
    51 
       
    52 static void show_progress(glp_tree *T, int bingo)
       
    53 {     int p;
       
    54       double temp;
       
    55       char best_mip[50], best_bound[50], *rho, rel_gap[50];
       
    56       /* format the best known integer feasible solution */
       
    57       if (T->mip->mip_stat == GLP_FEAS)
       
    58          sprintf(best_mip, "%17.9e", T->mip->mip_obj);
       
    59       else
       
    60          sprintf(best_mip, "%17s", "not found yet");
       
    61       /* determine reference number of an active subproblem whose local
       
    62          bound is best */
       
    63       p = ios_best_node(T);
       
    64       /* format the best bound */
       
    65       if (p == 0)
       
    66          sprintf(best_bound, "%17s", "tree is empty");
       
    67       else
       
    68       {  temp = T->slot[p].node->bound;
       
    69          if (temp == -DBL_MAX)
       
    70             sprintf(best_bound, "%17s", "-inf");
       
    71          else if (temp == +DBL_MAX)
       
    72             sprintf(best_bound, "%17s", "+inf");
       
    73          else
       
    74             sprintf(best_bound, "%17.9e", temp);
       
    75       }
       
    76       /* choose the relation sign between global bounds */
       
    77       if (T->mip->dir == GLP_MIN)
       
    78          rho = ">=";
       
    79       else if (T->mip->dir == GLP_MAX)
       
    80          rho = "<=";
       
    81       else
       
    82          xassert(T != T);
       
    83       /* format the relative mip gap */
       
    84       temp = ios_relative_gap(T);
       
    85       if (temp == 0.0)
       
    86          sprintf(rel_gap, "  0.0%%");
       
    87       else if (temp < 0.001)
       
    88          sprintf(rel_gap, "< 0.1%%");
       
    89       else if (temp <= 9.999)
       
    90          sprintf(rel_gap, "%5.1f%%", 100.0 * temp);
       
    91       else
       
    92          sprintf(rel_gap, "%6s", "");
       
    93       /* display progress of the search */
       
    94       xprintf("+%6d: %s %s %s %s %s (%d; %d)\n",
       
    95          T->mip->it_cnt, bingo ? ">>>>>" : "mip =", best_mip, rho,
       
    96          best_bound, rel_gap, T->a_cnt, T->t_cnt - T->n_cnt);
       
    97       T->tm_lag = xtime();
       
    98       return;
       
    99 }
       
   100 
       
   101 /***********************************************************************
       
   102 *  is_branch_hopeful - check if specified branch is hopeful
       
   103 *
       
   104 *  This routine checks if the specified subproblem can have an integer
       
   105 *  optimal solution which is better than the best known one.
       
   106 *
       
   107 *  The check is based on comparison of the local objective bound stored
       
   108 *  in the subproblem descriptor and the incumbent objective value which
       
   109 *  is the global objective bound.
       
   110 *
       
   111 *  If there is a chance that the specified subproblem can have a better
       
   112 *  integer optimal solution, the routine returns non-zero. Otherwise, if
       
   113 *  the corresponding branch can pruned, zero is returned. */
       
   114 
       
   115 static int is_branch_hopeful(glp_tree *T, int p)
       
   116 {     xassert(1 <= p && p <= T->nslots);
       
   117       xassert(T->slot[p].node != NULL);
       
   118       return ios_is_hopeful(T, T->slot[p].node->bound);
       
   119 }
       
   120 
       
   121 /***********************************************************************
       
   122 *  check_integrality - check integrality of basic solution
       
   123 *
       
   124 *  This routine checks if the basic solution of LP relaxation of the
       
   125 *  current subproblem satisfies to integrality conditions, i.e. that all
       
   126 *  variables of integer kind have integral primal values. (The solution
       
   127 *  is assumed to be optimal.)
       
   128 *
       
   129 *  For each variable of integer kind the routine computes the following
       
   130 *  quantity:
       
   131 *
       
   132 *     ii(x[j]) = min(x[j] - floor(x[j]), ceil(x[j]) - x[j]),         (1)
       
   133 *
       
   134 *  which is a measure of the integer infeasibility (non-integrality) of
       
   135 *  x[j] (for example, ii(2.1) = 0.1, ii(3.7) = 0.3, ii(5.0) = 0). It is
       
   136 *  understood that 0 <= ii(x[j]) <= 0.5, and variable x[j] is integer
       
   137 *  feasible if ii(x[j]) = 0. However, due to floating-point arithmetic
       
   138 *  the routine checks less restrictive condition:
       
   139 *
       
   140 *     ii(x[j]) <= tol_int,                                           (2)
       
   141 *
       
   142 *  where tol_int is a given tolerance (small positive number) and marks
       
   143 *  each variable which does not satisfy to (2) as integer infeasible by
       
   144 *  setting its fractionality flag.
       
   145 *
       
   146 *  In order to characterize integer infeasibility of the basic solution
       
   147 *  in the whole the routine computes two parameters: ii_cnt, which is
       
   148 *  the number of variables with the fractionality flag set, and ii_sum,
       
   149 *  which is the sum of integer infeasibilities (1). */
       
   150 
       
   151 static void check_integrality(glp_tree *T)
       
   152 {     glp_prob *mip = T->mip;
       
   153       int j, type, ii_cnt = 0;
       
   154       double lb, ub, x, temp1, temp2, ii_sum = 0.0;
       
   155       /* walk through the set of columns (structural variables) */
       
   156       for (j = 1; j <= mip->n; j++)
       
   157       {  GLPCOL *col = mip->col[j];
       
   158          T->non_int[j] = 0;
       
   159          /* if the column is not integer, skip it */
       
   160          if (col->kind != GLP_IV) continue;
       
   161          /* if the column is non-basic, it is integer feasible */
       
   162          if (col->stat != GLP_BS) continue;
       
   163          /* obtain the type and bounds of the column */
       
   164          type = col->type, lb = col->lb, ub = col->ub;
       
   165          /* obtain value of the column in optimal basic solution */
       
   166          x = col->prim;
       
   167          /* if the column's primal value is close to the lower bound,
       
   168             the column is integer feasible within given tolerance */
       
   169          if (type == GLP_LO || type == GLP_DB || type == GLP_FX)
       
   170          {  temp1 = lb - T->parm->tol_int;
       
   171             temp2 = lb + T->parm->tol_int;
       
   172             if (temp1 <= x && x <= temp2) continue;
       
   173 #if 0
       
   174             /* the lower bound must not be violated */
       
   175             xassert(x >= lb);
       
   176 #else
       
   177             if (x < lb) continue;
       
   178 #endif
       
   179          }
       
   180          /* if the column's primal value is close to the upper bound,
       
   181             the column is integer feasible within given tolerance */
       
   182          if (type == GLP_UP || type == GLP_DB || type == GLP_FX)
       
   183          {  temp1 = ub - T->parm->tol_int;
       
   184             temp2 = ub + T->parm->tol_int;
       
   185             if (temp1 <= x && x <= temp2) continue;
       
   186 #if 0
       
   187             /* the upper bound must not be violated */
       
   188             xassert(x <= ub);
       
   189 #else
       
   190             if (x > ub) continue;
       
   191 #endif
       
   192          }
       
   193          /* if the column's primal value is close to nearest integer,
       
   194             the column is integer feasible within given tolerance */
       
   195          temp1 = floor(x + 0.5) - T->parm->tol_int;
       
   196          temp2 = floor(x + 0.5) + T->parm->tol_int;
       
   197          if (temp1 <= x && x <= temp2) continue;
       
   198          /* otherwise the column is integer infeasible */
       
   199          T->non_int[j] = 1;
       
   200          /* increase the number of fractional-valued columns */
       
   201          ii_cnt++;
       
   202          /* compute the sum of integer infeasibilities */
       
   203          temp1 = x - floor(x);
       
   204          temp2 = ceil(x) - x;
       
   205          xassert(temp1 > 0.0 && temp2 > 0.0);
       
   206          ii_sum += (temp1 <= temp2 ? temp1 : temp2);
       
   207       }
       
   208       /* store ii_cnt and ii_sum to the current problem descriptor */
       
   209       xassert(T->curr != NULL);
       
   210       T->curr->ii_cnt = ii_cnt;
       
   211       T->curr->ii_sum = ii_sum;
       
   212       /* and also display these parameters */
       
   213       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   214       {  if (ii_cnt == 0)
       
   215             xprintf("There are no fractional columns\n");
       
   216          else if (ii_cnt == 1)
       
   217             xprintf("There is one fractional column, integer infeasibil"
       
   218                "ity is %.3e\n", ii_sum);
       
   219          else
       
   220             xprintf("There are %d fractional columns, integer infeasibi"
       
   221                "lity is %.3e\n", ii_cnt, ii_sum);
       
   222       }
       
   223       return;
       
   224 }
       
   225 
       
   226 /***********************************************************************
       
   227 *  record_solution - record better integer feasible solution
       
   228 *
       
   229 *  This routine records optimal basic solution of LP relaxation of the
       
   230 *  current subproblem, which being integer feasible is better than the
       
   231 *  best known integer feasible solution. */
       
   232 
       
   233 static void record_solution(glp_tree *T)
       
   234 {     glp_prob *mip = T->mip;
       
   235       int i, j;
       
   236       mip->mip_stat = GLP_FEAS;
       
   237       mip->mip_obj = mip->obj_val;
       
   238       for (i = 1; i <= mip->m; i++)
       
   239       {  GLPROW *row = mip->row[i];
       
   240          row->mipx = row->prim;
       
   241       }
       
   242       for (j = 1; j <= mip->n; j++)
       
   243       {  GLPCOL *col = mip->col[j];
       
   244          if (col->kind == GLP_CV)
       
   245             col->mipx = col->prim;
       
   246          else if (col->kind == GLP_IV)
       
   247          {  /* value of the integer column must be integral */
       
   248             col->mipx = floor(col->prim + 0.5);
       
   249          }
       
   250          else
       
   251             xassert(col != col);
       
   252       }
       
   253       T->sol_cnt++;
       
   254       return;
       
   255 }
       
   256 
       
   257 /***********************************************************************
       
   258 *  fix_by_red_cost - fix non-basic integer columns by reduced costs
       
   259 *
       
   260 *  This routine fixes some non-basic integer columns if their reduced
       
   261 *  costs indicate that increasing (decreasing) the column at least by
       
   262 *  one involves the objective value becoming worse than the incumbent
       
   263 *  objective value. */
       
   264 
       
   265 static void fix_by_red_cost(glp_tree *T)
       
   266 {     glp_prob *mip = T->mip;
       
   267       int j, stat, fixed = 0;
       
   268       double obj, lb, ub, dj;
       
   269       /* the global bound must exist */
       
   270       xassert(T->mip->mip_stat == GLP_FEAS);
       
   271       /* basic solution of LP relaxation must be optimal */
       
   272       xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS);
       
   273       /* determine the objective function value */
       
   274       obj = mip->obj_val;
       
   275       /* walk through the column list */
       
   276       for (j = 1; j <= mip->n; j++)
       
   277       {  GLPCOL *col = mip->col[j];
       
   278          /* if the column is not integer, skip it */
       
   279          if (col->kind != GLP_IV) continue;
       
   280          /* obtain bounds of j-th column */
       
   281          lb = col->lb, ub = col->ub;
       
   282          /* and determine its status and reduced cost */
       
   283          stat = col->stat, dj = col->dual;
       
   284          /* analyze the reduced cost */
       
   285          switch (mip->dir)
       
   286          {  case GLP_MIN:
       
   287                /* minimization */
       
   288                if (stat == GLP_NL)
       
   289                {  /* j-th column is non-basic on its lower bound */
       
   290                   if (dj < 0.0) dj = 0.0;
       
   291                   if (obj + dj >= mip->mip_obj)
       
   292                      glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++;
       
   293                }
       
   294                else if (stat == GLP_NU)
       
   295                {  /* j-th column is non-basic on its upper bound */
       
   296                   if (dj > 0.0) dj = 0.0;
       
   297                   if (obj - dj >= mip->mip_obj)
       
   298                      glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++;
       
   299                }
       
   300                break;
       
   301             case GLP_MAX:
       
   302                /* maximization */
       
   303                if (stat == GLP_NL)
       
   304                {  /* j-th column is non-basic on its lower bound */
       
   305                   if (dj > 0.0) dj = 0.0;
       
   306                   if (obj + dj <= mip->mip_obj)
       
   307                      glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++;
       
   308                }
       
   309                else if (stat == GLP_NU)
       
   310                {  /* j-th column is non-basic on its upper bound */
       
   311                   if (dj < 0.0) dj = 0.0;
       
   312                   if (obj - dj <= mip->mip_obj)
       
   313                      glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++;
       
   314                }
       
   315                break;
       
   316             default:
       
   317                xassert(T != T);
       
   318          }
       
   319       }
       
   320       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   321       {  if (fixed == 0)
       
   322             /* nothing to say */;
       
   323          else if (fixed == 1)
       
   324             xprintf("One column has been fixed by reduced cost\n");
       
   325          else
       
   326             xprintf("%d columns have been fixed by reduced costs\n",
       
   327                fixed);
       
   328       }
       
   329       /* fixing non-basic columns on their current bounds does not
       
   330          change the basic solution */
       
   331       xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS);
       
   332       return;
       
   333 }
       
   334 
       
   335 /***********************************************************************
       
   336 *  branch_on - perform branching on specified variable
       
   337 *
       
   338 *  This routine performs branching on j-th column (structural variable)
       
   339 *  of the current subproblem. The specified column must be of integer
       
   340 *  kind and must have a fractional value in optimal basic solution of
       
   341 *  LP relaxation of the current subproblem (i.e. only columns for which
       
   342 *  the flag non_int[j] is set are valid candidates to branch on).
       
   343 *
       
   344 *  Let x be j-th structural variable, and beta be its primal fractional
       
   345 *  value in the current basic solution. Branching on j-th variable is
       
   346 *  dividing the current subproblem into two new subproblems, which are
       
   347 *  identical to the current subproblem with the following exception: in
       
   348 *  the first subproblem that begins the down-branch x has a new upper
       
   349 *  bound x <= floor(beta), and in the second subproblem that begins the
       
   350 *  up-branch x has a new lower bound x >= ceil(beta).
       
   351 *
       
   352 *  Depending on estimation of local bounds for down- and up-branches
       
   353 *  this routine returns the following:
       
   354 *
       
   355 *  0 - both branches have been created;
       
   356 *  1 - one branch is hopeless and has been pruned, so now the current
       
   357 *      subproblem is other branch;
       
   358 *  2 - both branches are hopeless and have been pruned; new subproblem
       
   359 *      selection is needed to continue the search. */
       
   360 
       
   361 static int branch_on(glp_tree *T, int j, int next)
       
   362 {     glp_prob *mip = T->mip;
       
   363       IOSNPD *node;
       
   364       int m = mip->m;
       
   365       int n = mip->n;
       
   366       int type, dn_type, up_type, dn_bad, up_bad, p, ret, clone[1+2];
       
   367       double lb, ub, beta, new_ub, new_lb, dn_lp, up_lp, dn_bnd, up_bnd;
       
   368       /* determine bounds and value of x[j] in optimal solution to LP
       
   369          relaxation of the current subproblem */
       
   370       xassert(1 <= j && j <= n);
       
   371       type = mip->col[j]->type;
       
   372       lb = mip->col[j]->lb;
       
   373       ub = mip->col[j]->ub;
       
   374       beta = mip->col[j]->prim;
       
   375       /* determine new bounds of x[j] for down- and up-branches */
       
   376       new_ub = floor(beta);
       
   377       new_lb = ceil(beta);
       
   378       switch (type)
       
   379       {  case GLP_FR:
       
   380             dn_type = GLP_UP;
       
   381             up_type = GLP_LO;
       
   382             break;
       
   383          case GLP_LO:
       
   384             xassert(lb <= new_ub);
       
   385             dn_type = (lb == new_ub ? GLP_FX : GLP_DB);
       
   386             xassert(lb + 1.0 <= new_lb);
       
   387             up_type = GLP_LO;
       
   388             break;
       
   389          case GLP_UP:
       
   390             xassert(new_ub <= ub - 1.0);
       
   391             dn_type = GLP_UP;
       
   392             xassert(new_lb <= ub);
       
   393             up_type = (new_lb == ub ? GLP_FX : GLP_DB);
       
   394             break;
       
   395          case GLP_DB:
       
   396             xassert(lb <= new_ub && new_ub <= ub - 1.0);
       
   397             dn_type = (lb == new_ub ? GLP_FX : GLP_DB);
       
   398             xassert(lb + 1.0 <= new_lb && new_lb <= ub);
       
   399             up_type = (new_lb == ub ? GLP_FX : GLP_DB);
       
   400             break;
       
   401          default:
       
   402             xassert(type != type);
       
   403       }
       
   404       /* compute local bounds to LP relaxation for both branches */
       
   405       ios_eval_degrad(T, j, &dn_lp, &up_lp);
       
   406       /* and improve them by rounding */
       
   407       dn_bnd = ios_round_bound(T, dn_lp);
       
   408       up_bnd = ios_round_bound(T, up_lp);
       
   409       /* check local bounds for down- and up-branches */
       
   410       dn_bad = !ios_is_hopeful(T, dn_bnd);
       
   411       up_bad = !ios_is_hopeful(T, up_bnd);
       
   412       if (dn_bad && up_bad)
       
   413       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   414             xprintf("Both down- and up-branches are hopeless\n");
       
   415          ret = 2;
       
   416          goto done;
       
   417       }
       
   418       else if (up_bad)
       
   419       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   420             xprintf("Up-branch is hopeless\n");
       
   421          glp_set_col_bnds(mip, j, dn_type, lb, new_ub);
       
   422          T->curr->lp_obj = dn_lp;
       
   423          if (mip->dir == GLP_MIN)
       
   424          {  if (T->curr->bound < dn_bnd)
       
   425                 T->curr->bound = dn_bnd;
       
   426          }
       
   427          else if (mip->dir == GLP_MAX)
       
   428          {  if (T->curr->bound > dn_bnd)
       
   429                 T->curr->bound = dn_bnd;
       
   430          }
       
   431          else
       
   432             xassert(mip != mip);
       
   433          ret = 1;
       
   434          goto done;
       
   435       }
       
   436       else if (dn_bad)
       
   437       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   438             xprintf("Down-branch is hopeless\n");
       
   439          glp_set_col_bnds(mip, j, up_type, new_lb, ub);
       
   440          T->curr->lp_obj = up_lp;
       
   441          if (mip->dir == GLP_MIN)
       
   442          {  if (T->curr->bound < up_bnd)
       
   443                 T->curr->bound = up_bnd;
       
   444          }
       
   445          else if (mip->dir == GLP_MAX)
       
   446          {  if (T->curr->bound > up_bnd)
       
   447                 T->curr->bound = up_bnd;
       
   448          }
       
   449          else
       
   450             xassert(mip != mip);
       
   451          ret = 1;
       
   452          goto done;
       
   453       }
       
   454       /* both down- and up-branches seem to be hopeful */
       
   455       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   456          xprintf("Branching on column %d, primal value is %.9e\n",
       
   457             j, beta);
       
   458       /* determine the reference number of the current subproblem */
       
   459       xassert(T->curr != NULL);
       
   460       p = T->curr->p;
       
   461       T->curr->br_var = j;
       
   462       T->curr->br_val = beta;
       
   463       /* freeze the current subproblem */
       
   464       ios_freeze_node(T);
       
   465       /* create two clones of the current subproblem; the first clone
       
   466          begins the down-branch, the second one begins the up-branch */
       
   467       ios_clone_node(T, p, 2, clone);
       
   468       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   469          xprintf("Node %d begins down branch, node %d begins up branch "
       
   470             "\n", clone[1], clone[2]);
       
   471       /* set new upper bound of j-th column in the down-branch */
       
   472       node = T->slot[clone[1]].node;
       
   473       xassert(node != NULL);
       
   474       xassert(node->up != NULL);
       
   475       xassert(node->b_ptr == NULL);
       
   476       node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND));
       
   477       node->b_ptr->k = m + j;
       
   478       node->b_ptr->type = (unsigned char)dn_type;
       
   479       node->b_ptr->lb = lb;
       
   480       node->b_ptr->ub = new_ub;
       
   481       node->b_ptr->next = NULL;
       
   482       node->lp_obj = dn_lp;
       
   483       if (mip->dir == GLP_MIN)
       
   484       {  if (node->bound < dn_bnd)
       
   485              node->bound = dn_bnd;
       
   486       }
       
   487       else if (mip->dir == GLP_MAX)
       
   488       {  if (node->bound > dn_bnd)
       
   489              node->bound = dn_bnd;
       
   490       }
       
   491       else
       
   492          xassert(mip != mip);
       
   493       /* set new lower bound of j-th column in the up-branch */
       
   494       node = T->slot[clone[2]].node;
       
   495       xassert(node != NULL);
       
   496       xassert(node->up != NULL);
       
   497       xassert(node->b_ptr == NULL);
       
   498       node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND));
       
   499       node->b_ptr->k = m + j;
       
   500       node->b_ptr->type = (unsigned char)up_type;
       
   501       node->b_ptr->lb = new_lb;
       
   502       node->b_ptr->ub = ub;
       
   503       node->b_ptr->next = NULL;
       
   504       node->lp_obj = up_lp;
       
   505       if (mip->dir == GLP_MIN)
       
   506       {  if (node->bound < up_bnd)
       
   507              node->bound = up_bnd;
       
   508       }
       
   509       else if (mip->dir == GLP_MAX)
       
   510       {  if (node->bound > up_bnd)
       
   511              node->bound = up_bnd;
       
   512       }
       
   513       else
       
   514          xassert(mip != mip);
       
   515       /* suggest the subproblem to be solved next */
       
   516       xassert(T->child == 0);
       
   517       if (next == GLP_NO_BRNCH)
       
   518          T->child = 0;
       
   519       else if (next == GLP_DN_BRNCH)
       
   520          T->child = clone[1];
       
   521       else if (next == GLP_UP_BRNCH)
       
   522          T->child = clone[2];
       
   523       else
       
   524          xassert(next != next);
       
   525       ret = 0;
       
   526 done: return ret;
       
   527 }
       
   528 
       
   529 /***********************************************************************
       
   530 *  cleanup_the_tree - prune hopeless branches from the tree
       
   531 *
       
   532 *  This routine walks through the active list and checks the local
       
   533 *  bound for every active subproblem. If the local bound indicates that
       
   534 *  the subproblem cannot have integer optimal solution better than the
       
   535 *  incumbent objective value, the routine deletes such subproblem that,
       
   536 *  in turn, involves pruning the corresponding branch of the tree. */
       
   537 
       
   538 static void cleanup_the_tree(glp_tree *T)
       
   539 {     IOSNPD *node, *next_node;
       
   540       int count = 0;
       
   541       /* the global bound must exist */
       
   542       xassert(T->mip->mip_stat == GLP_FEAS);
       
   543       /* walk through the list of active subproblems */
       
   544       for (node = T->head; node != NULL; node = next_node)
       
   545       {  /* deleting some active problem node may involve deleting its
       
   546             parents recursively; however, all its parents being created
       
   547             *before* it are always *precede* it in the node list, so
       
   548             the next problem node is never affected by such deletion */
       
   549          next_node = node->next;
       
   550          /* if the branch is hopeless, prune it */
       
   551          if (!is_branch_hopeful(T, node->p))
       
   552             ios_delete_node(T, node->p), count++;
       
   553       }
       
   554       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   555       {  if (count == 1)
       
   556             xprintf("One hopeless branch has been pruned\n");
       
   557          else if (count > 1)
       
   558             xprintf("%d hopeless branches have been pruned\n", count);
       
   559       }
       
   560       return;
       
   561 }
       
   562 
       
   563 /**********************************************************************/
       
   564 
       
   565 static void generate_cuts(glp_tree *T)
       
   566 {     /* generate generic cuts with built-in generators */
       
   567       if (!(T->parm->mir_cuts == GLP_ON ||
       
   568             T->parm->gmi_cuts == GLP_ON ||
       
   569             T->parm->cov_cuts == GLP_ON ||
       
   570             T->parm->clq_cuts == GLP_ON)) goto done;
       
   571 #if 1 /* 20/IX-2008 */
       
   572       {  int i, max_cuts, added_cuts;
       
   573          max_cuts = T->n;
       
   574          if (max_cuts < 1000) max_cuts = 1000;
       
   575          added_cuts = 0;
       
   576          for (i = T->orig_m+1; i <= T->mip->m; i++)
       
   577          {  if (T->mip->row[i]->origin == GLP_RF_CUT)
       
   578                added_cuts++;
       
   579          }
       
   580          /* xprintf("added_cuts = %d\n", added_cuts); */
       
   581          if (added_cuts >= max_cuts) goto done;
       
   582       }
       
   583 #endif
       
   584       /* generate and add to POOL all cuts violated by x* */
       
   585       if (T->parm->gmi_cuts == GLP_ON)
       
   586       {  if (T->curr->changed < 5)
       
   587             ios_gmi_gen(T);
       
   588       }
       
   589       if (T->parm->mir_cuts == GLP_ON)
       
   590       {  xassert(T->mir_gen != NULL);
       
   591          ios_mir_gen(T, T->mir_gen);
       
   592       }
       
   593       if (T->parm->cov_cuts == GLP_ON)
       
   594       {  /* cover cuts works well along with mir cuts */
       
   595          /*if (T->round <= 5)*/
       
   596             ios_cov_gen(T);
       
   597       }
       
   598       if (T->parm->clq_cuts == GLP_ON)
       
   599       {  if (T->clq_gen != NULL)
       
   600          {  if (T->curr->level == 0 && T->curr->changed < 50 ||
       
   601                 T->curr->level >  0 && T->curr->changed < 5)
       
   602                ios_clq_gen(T, T->clq_gen);
       
   603          }
       
   604       }
       
   605 done: return;
       
   606 }
       
   607 
       
   608 /**********************************************************************/
       
   609 
       
   610 static void remove_cuts(glp_tree *T)
       
   611 {     /* remove inactive cuts (some valueable globally valid cut might
       
   612          be saved in the global cut pool) */
       
   613       int i, cnt = 0, *num = NULL;
       
   614       xassert(T->curr != NULL);
       
   615       for (i = T->orig_m+1; i <= T->mip->m; i++)
       
   616       {  if (T->mip->row[i]->origin == GLP_RF_CUT &&
       
   617              T->mip->row[i]->level == T->curr->level &&
       
   618              T->mip->row[i]->stat == GLP_BS)
       
   619          {  if (num == NULL)
       
   620                num = xcalloc(1+T->mip->m, sizeof(int));
       
   621             num[++cnt] = i;
       
   622          }
       
   623       }
       
   624       if (cnt > 0)
       
   625       {  glp_del_rows(T->mip, cnt, num);
       
   626 #if 0
       
   627          xprintf("%d inactive cut(s) removed\n", cnt);
       
   628 #endif
       
   629          xfree(num);
       
   630          xassert(glp_factorize(T->mip) == 0);
       
   631       }
       
   632       return;
       
   633 }
       
   634 
       
   635 /**********************************************************************/
       
   636 
       
   637 static void display_cut_info(glp_tree *T)
       
   638 {     glp_prob *mip = T->mip;
       
   639       int i, gmi = 0, mir = 0, cov = 0, clq = 0, app = 0;
       
   640       for (i = mip->m; i > 0; i--)
       
   641       {  GLPROW *row;
       
   642          row = mip->row[i];
       
   643          /* if (row->level < T->curr->level) break; */
       
   644          if (row->origin == GLP_RF_CUT)
       
   645          {  if (row->klass == GLP_RF_GMI)
       
   646                gmi++;
       
   647             else if (row->klass == GLP_RF_MIR)
       
   648                mir++;
       
   649             else if (row->klass == GLP_RF_COV)
       
   650                cov++;
       
   651             else if (row->klass == GLP_RF_CLQ)
       
   652                clq++;
       
   653             else
       
   654                app++;
       
   655          }
       
   656       }
       
   657       xassert(T->curr != NULL);
       
   658       if (gmi + mir + cov + clq + app > 0)
       
   659       {  xprintf("Cuts on level %d:", T->curr->level);
       
   660          if (gmi > 0) xprintf(" gmi = %d;", gmi);
       
   661          if (mir > 0) xprintf(" mir = %d;", mir);
       
   662          if (cov > 0) xprintf(" cov = %d;", cov);
       
   663          if (clq > 0) xprintf(" clq = %d;", clq);
       
   664          if (app > 0) xprintf(" app = %d;", app);
       
   665          xprintf("\n");
       
   666       }
       
   667       return;
       
   668 }
       
   669 
       
   670 /***********************************************************************
       
   671 *  NAME
       
   672 *
       
   673 *  ios_driver - branch-and-cut driver
       
   674 *
       
   675 *  SYNOPSIS
       
   676 *
       
   677 *  #include "glpios.h"
       
   678 *  int ios_driver(glp_tree *T);
       
   679 *
       
   680 *  DESCRIPTION
       
   681 *
       
   682 *  The routine ios_driver is a branch-and-cut driver. It controls the
       
   683 *  MIP solution process.
       
   684 *
       
   685 *  RETURNS
       
   686 *
       
   687 *  0  The MIP problem instance has been successfully solved. This code
       
   688 *     does not necessarily mean that the solver has found optimal
       
   689 *     solution. It only means that the solution process was successful.
       
   690 *
       
   691 *  GLP_EFAIL
       
   692 *     The search was prematurely terminated due to the solver failure.
       
   693 *
       
   694 *  GLP_EMIPGAP
       
   695 *     The search was prematurely terminated, because the relative mip
       
   696 *     gap tolerance has been reached.
       
   697 *
       
   698 *  GLP_ETMLIM
       
   699 *     The search was prematurely terminated, because the time limit has
       
   700 *     been exceeded.
       
   701 *
       
   702 *  GLP_ESTOP
       
   703 *     The search was prematurely terminated by application. */
       
   704 
       
   705 int ios_driver(glp_tree *T)
       
   706 {     int p, curr_p, p_stat, d_stat, ret;
       
   707 #if 1 /* carry out to glp_tree */
       
   708       int pred_p = 0;
       
   709       /* if the current subproblem has been just created due to
       
   710          branching, pred_p is the reference number of its parent
       
   711          subproblem, otherwise pred_p is zero */
       
   712 #endif
       
   713       glp_long ttt = T->tm_beg;
       
   714 #if 0
       
   715       ((glp_iocp *)T->parm)->msg_lev = GLP_MSG_DBG;
       
   716 #endif
       
   717       /* on entry to the B&B driver it is assumed that the active list
       
   718          contains the only active (i.e. root) subproblem, which is the
       
   719          original MIP problem to be solved */
       
   720 loop: /* main loop starts here */
       
   721       /* at this point the current subproblem does not exist */
       
   722       xassert(T->curr == NULL);
       
   723       /* if the active list is empty, the search is finished */
       
   724       if (T->head == NULL)
       
   725       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   726             xprintf("Active list is empty!\n");
       
   727          xassert(dmp_in_use(T->pool).lo == 0);
       
   728          ret = 0;
       
   729          goto done;
       
   730       }
       
   731       /* select some active subproblem to continue the search */
       
   732       xassert(T->next_p == 0);
       
   733       /* let the application program select subproblem */
       
   734       if (T->parm->cb_func != NULL)
       
   735       {  xassert(T->reason == 0);
       
   736          T->reason = GLP_ISELECT;
       
   737          T->parm->cb_func(T, T->parm->cb_info);
       
   738          T->reason = 0;
       
   739          if (T->stop)
       
   740          {  ret = GLP_ESTOP;
       
   741             goto done;
       
   742          }
       
   743       }
       
   744       if (T->next_p != 0)
       
   745       {  /* the application program has selected something */
       
   746          ;
       
   747       }
       
   748       else if (T->a_cnt == 1)
       
   749       {  /* the only active subproblem exists, so select it */
       
   750          xassert(T->head->next == NULL);
       
   751          T->next_p = T->head->p;
       
   752       }
       
   753       else if (T->child != 0)
       
   754       {  /* select one of branching childs suggested by the branching
       
   755             heuristic */
       
   756          T->next_p = T->child;
       
   757       }
       
   758       else
       
   759       {  /* select active subproblem as specified by the backtracking
       
   760             technique option */
       
   761          T->next_p = ios_choose_node(T);
       
   762       }
       
   763       /* the active subproblem just selected becomes current */
       
   764       ios_revive_node(T, T->next_p);
       
   765       T->next_p = T->child = 0;
       
   766       /* invalidate pred_p, if it is not the reference number of the
       
   767          parent of the current subproblem */
       
   768       if (T->curr->up != NULL && T->curr->up->p != pred_p) pred_p = 0;
       
   769       /* determine the reference number of the current subproblem */
       
   770       p = T->curr->p;
       
   771       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   772       {  xprintf("-----------------------------------------------------"
       
   773             "-------------------\n");
       
   774          xprintf("Processing node %d at level %d\n", p, T->curr->level);
       
   775       }
       
   776       /* if it is the root subproblem, initialize cut generators */
       
   777       if (p == 1)
       
   778       {  if (T->parm->gmi_cuts == GLP_ON)
       
   779          {  if (T->parm->msg_lev >= GLP_MSG_ALL)
       
   780                xprintf("Gomory's cuts enabled\n");
       
   781          }
       
   782          if (T->parm->mir_cuts == GLP_ON)
       
   783          {  if (T->parm->msg_lev >= GLP_MSG_ALL)
       
   784                xprintf("MIR cuts enabled\n");
       
   785             xassert(T->mir_gen == NULL);
       
   786             T->mir_gen = ios_mir_init(T);
       
   787          }
       
   788          if (T->parm->cov_cuts == GLP_ON)
       
   789          {  if (T->parm->msg_lev >= GLP_MSG_ALL)
       
   790                xprintf("Cover cuts enabled\n");
       
   791          }
       
   792          if (T->parm->clq_cuts == GLP_ON)
       
   793          {  xassert(T->clq_gen == NULL);
       
   794             if (T->parm->msg_lev >= GLP_MSG_ALL)
       
   795                xprintf("Clique cuts enabled\n");
       
   796             T->clq_gen = ios_clq_init(T);
       
   797          }
       
   798       }
       
   799 more: /* minor loop starts here */
       
   800       /* at this point the current subproblem needs either to be solved
       
   801          for the first time or re-optimized due to reformulation */
       
   802       /* display current progress of the search */
       
   803       if (T->parm->msg_lev >= GLP_MSG_DBG ||
       
   804           T->parm->msg_lev >= GLP_MSG_ON &&
       
   805         (double)(T->parm->out_frq - 1) <=
       
   806             1000.0 * xdifftime(xtime(), T->tm_lag))
       
   807          show_progress(T, 0);
       
   808       if (T->parm->msg_lev >= GLP_MSG_ALL &&
       
   809             xdifftime(xtime(), ttt) >= 60.0)
       
   810       {  glp_long total;
       
   811          glp_mem_usage(NULL, NULL, &total, NULL);
       
   812          xprintf("Time used: %.1f secs.  Memory used: %.1f Mb.\n",
       
   813             xdifftime(xtime(), T->tm_beg), xltod(total) / 1048576.0);
       
   814          ttt = xtime();
       
   815       }
       
   816       /* check the mip gap */
       
   817       if (T->parm->mip_gap > 0.0 &&
       
   818           ios_relative_gap(T) <= T->parm->mip_gap)
       
   819       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   820             xprintf("Relative gap tolerance reached; search terminated "
       
   821                "\n");
       
   822          ret = GLP_EMIPGAP;
       
   823          goto done;
       
   824       }
       
   825       /* check if the time limit has been exhausted */
       
   826       if (T->parm->tm_lim < INT_MAX &&
       
   827          (double)(T->parm->tm_lim - 1) <=
       
   828          1000.0 * xdifftime(xtime(), T->tm_beg))
       
   829       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   830             xprintf("Time limit exhausted; search terminated\n");
       
   831          ret = GLP_ETMLIM;
       
   832          goto done;
       
   833       }
       
   834       /* let the application program preprocess the subproblem */
       
   835       if (T->parm->cb_func != NULL)
       
   836       {  xassert(T->reason == 0);
       
   837          T->reason = GLP_IPREPRO;
       
   838          T->parm->cb_func(T, T->parm->cb_info);
       
   839          T->reason = 0;
       
   840          if (T->stop)
       
   841          {  ret = GLP_ESTOP;
       
   842             goto done;
       
   843          }
       
   844       }
       
   845       /* perform basic preprocessing */
       
   846       if (T->parm->pp_tech == GLP_PP_NONE)
       
   847          ;
       
   848       else if (T->parm->pp_tech == GLP_PP_ROOT)
       
   849       {  if (T->curr->level == 0)
       
   850          {  if (ios_preprocess_node(T, 100))
       
   851                goto fath;
       
   852          }
       
   853       }
       
   854       else if (T->parm->pp_tech == GLP_PP_ALL)
       
   855       {  if (ios_preprocess_node(T, T->curr->level == 0 ? 100 : 10))
       
   856             goto fath;
       
   857       }
       
   858       else
       
   859          xassert(T != T);
       
   860       /* preprocessing may improve the global bound */
       
   861       if (!is_branch_hopeful(T, p))
       
   862       {  xprintf("*** not tested yet ***\n");
       
   863          goto fath;
       
   864       }
       
   865       /* solve LP relaxation of the current subproblem */
       
   866       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   867          xprintf("Solving LP relaxation...\n");
       
   868       ret = ios_solve_node(T);
       
   869       if (!(ret == 0 || ret == GLP_EOBJLL || ret == GLP_EOBJUL))
       
   870       {  if (T->parm->msg_lev >= GLP_MSG_ERR)
       
   871             xprintf("ios_driver: unable to solve current LP relaxation;"
       
   872                " glp_simplex returned %d\n", ret);
       
   873          ret = GLP_EFAIL;
       
   874          goto done;
       
   875       }
       
   876       /* analyze status of the basic solution to LP relaxation found */
       
   877       p_stat = T->mip->pbs_stat;
       
   878       d_stat = T->mip->dbs_stat;
       
   879       if (p_stat == GLP_FEAS && d_stat == GLP_FEAS)
       
   880       {  /* LP relaxation has optimal solution */
       
   881          if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   882             xprintf("Found optimal solution to LP relaxation\n");
       
   883       }
       
   884       else if (d_stat == GLP_NOFEAS)
       
   885       {  /* LP relaxation has no dual feasible solution */
       
   886          /* since the current subproblem cannot have a larger feasible
       
   887             region than its parent, there is something wrong */
       
   888          if (T->parm->msg_lev >= GLP_MSG_ERR)
       
   889             xprintf("ios_driver: current LP relaxation has no dual feas"
       
   890                "ible solution\n");
       
   891          ret = GLP_EFAIL;
       
   892          goto done;
       
   893       }
       
   894       else if (p_stat == GLP_INFEAS && d_stat == GLP_FEAS)
       
   895       {  /* LP relaxation has no primal solution which is better than
       
   896             the incumbent objective value */
       
   897          xassert(T->mip->mip_stat == GLP_FEAS);
       
   898          if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   899             xprintf("LP relaxation has no solution better than incumben"
       
   900                "t objective value\n");
       
   901          /* prune the branch */
       
   902          goto fath;
       
   903       }
       
   904       else if (p_stat == GLP_NOFEAS)
       
   905       {  /* LP relaxation has no primal feasible solution */
       
   906          if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   907             xprintf("LP relaxation has no feasible solution\n");
       
   908          /* prune the branch */
       
   909          goto fath;
       
   910       }
       
   911       else
       
   912       {  /* other cases cannot appear */
       
   913          xassert(T->mip != T->mip);
       
   914       }
       
   915       /* at this point basic solution to LP relaxation of the current
       
   916          subproblem is optimal */
       
   917       xassert(p_stat == GLP_FEAS && d_stat == GLP_FEAS);
       
   918       xassert(T->curr != NULL);
       
   919       T->curr->lp_obj = T->mip->obj_val;
       
   920       /* thus, it defines a local bound to integer optimal solution of
       
   921          the current subproblem */
       
   922       {  double bound = T->mip->obj_val;
       
   923          /* some local bound to the current subproblem could be already
       
   924             set before, so we should only improve it */
       
   925          bound = ios_round_bound(T, bound);
       
   926          if (T->mip->dir == GLP_MIN)
       
   927          {  if (T->curr->bound < bound)
       
   928                T->curr->bound = bound;
       
   929          }
       
   930          else if (T->mip->dir == GLP_MAX)
       
   931          {  if (T->curr->bound > bound)
       
   932                T->curr->bound = bound;
       
   933          }
       
   934          else
       
   935             xassert(T->mip != T->mip);
       
   936          if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   937             xprintf("Local bound is %.9e\n", bound);
       
   938       }
       
   939       /* if the local bound indicates that integer optimal solution of
       
   940          the current subproblem cannot be better than the global bound,
       
   941          prune the branch */
       
   942       if (!is_branch_hopeful(T, p))
       
   943       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   944             xprintf("Current branch is hopeless and can be pruned\n");
       
   945          goto fath;
       
   946       }
       
   947       /* let the application program generate additional rows ("lazy"
       
   948          constraints) */
       
   949       xassert(T->reopt == 0);
       
   950       xassert(T->reinv == 0);
       
   951       if (T->parm->cb_func != NULL)
       
   952       {  xassert(T->reason == 0);
       
   953          T->reason = GLP_IROWGEN;
       
   954          T->parm->cb_func(T, T->parm->cb_info);
       
   955          T->reason = 0;
       
   956          if (T->stop)
       
   957          {  ret = GLP_ESTOP;
       
   958             goto done;
       
   959          }
       
   960          if (T->reopt)
       
   961          {  /* some rows were added; re-optimization is needed */
       
   962             T->reopt = T->reinv = 0;
       
   963             goto more;
       
   964          }
       
   965          if (T->reinv)
       
   966          {  /* no rows were added, however, some inactive rows were
       
   967                removed */
       
   968             T->reinv = 0;
       
   969             xassert(glp_factorize(T->mip) == 0);
       
   970          }
       
   971       }
       
   972       /* check if the basic solution is integer feasible */
       
   973       check_integrality(T);
       
   974       /* if the basic solution satisfies to all integrality conditions,
       
   975          it is a new, better integer feasible solution */
       
   976       if (T->curr->ii_cnt == 0)
       
   977       {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
   978             xprintf("New integer feasible solution found\n");
       
   979          if (T->parm->msg_lev >= GLP_MSG_ALL)
       
   980             display_cut_info(T);
       
   981          record_solution(T);
       
   982          if (T->parm->msg_lev >= GLP_MSG_ON)
       
   983             show_progress(T, 1);
       
   984          /* make the application program happy */
       
   985          if (T->parm->cb_func != NULL)
       
   986          {  xassert(T->reason == 0);
       
   987             T->reason = GLP_IBINGO;
       
   988             T->parm->cb_func(T, T->parm->cb_info);
       
   989             T->reason = 0;
       
   990             if (T->stop)
       
   991             {  ret = GLP_ESTOP;
       
   992                goto done;
       
   993             }
       
   994          }
       
   995          /* since the current subproblem has been fathomed, prune its
       
   996             branch */
       
   997          goto fath;
       
   998       }
       
   999       /* at this point basic solution to LP relaxation of the current
       
  1000          subproblem is optimal, but integer infeasible */
       
  1001       /* try to fix some non-basic structural variables of integer kind
       
  1002          on their current bounds due to reduced costs */
       
  1003       if (T->mip->mip_stat == GLP_FEAS)
       
  1004          fix_by_red_cost(T);
       
  1005       /* let the application program try to find some solution to the
       
  1006          original MIP with a primal heuristic */
       
  1007       if (T->parm->cb_func != NULL)
       
  1008       {  xassert(T->reason == 0);
       
  1009          T->reason = GLP_IHEUR;
       
  1010          T->parm->cb_func(T, T->parm->cb_info);
       
  1011          T->reason = 0;
       
  1012          if (T->stop)
       
  1013          {  ret = GLP_ESTOP;
       
  1014             goto done;
       
  1015          }
       
  1016          /* check if the current branch became hopeless */
       
  1017          if (!is_branch_hopeful(T, p))
       
  1018          {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
  1019                xprintf("Current branch became hopeless and can be prune"
       
  1020                   "d\n");
       
  1021             goto fath;
       
  1022          }
       
  1023       }
       
  1024       /* try to find solution with the feasibility pump heuristic */
       
  1025       if (T->parm->fp_heur)
       
  1026       {  xassert(T->reason == 0);
       
  1027          T->reason = GLP_IHEUR;
       
  1028          ios_feas_pump(T);
       
  1029          T->reason = 0;
       
  1030          /* check if the current branch became hopeless */
       
  1031          if (!is_branch_hopeful(T, p))
       
  1032          {  if (T->parm->msg_lev >= GLP_MSG_DBG)
       
  1033                xprintf("Current branch became hopeless and can be prune"
       
  1034                   "d\n");
       
  1035             goto fath;
       
  1036          }
       
  1037       }
       
  1038       /* it's time to generate cutting planes */
       
  1039       xassert(T->local != NULL);
       
  1040       xassert(T->local->size == 0);
       
  1041       /* let the application program generate some cuts; note that it
       
  1042          can add cuts either to the local cut pool or directly to the
       
  1043          current subproblem */
       
  1044       if (T->parm->cb_func != NULL)
       
  1045       {  xassert(T->reason == 0);
       
  1046          T->reason = GLP_ICUTGEN;
       
  1047          T->parm->cb_func(T, T->parm->cb_info);
       
  1048          T->reason = 0;
       
  1049          if (T->stop)
       
  1050          {  ret = GLP_ESTOP;
       
  1051             goto done;
       
  1052          }
       
  1053       }
       
  1054       /* try to generate generic cuts with built-in generators
       
  1055          (as suggested by Matteo Fischetti et al. the built-in cuts
       
  1056          are not generated at each branching node; an intense attempt
       
  1057          of generating new cuts is only made at the root node, and then
       
  1058          a moderate effort is spent after each backtracking step) */
       
  1059       if (T->curr->level == 0 || pred_p == 0)
       
  1060       {  xassert(T->reason == 0);
       
  1061          T->reason = GLP_ICUTGEN;
       
  1062          generate_cuts(T);
       
  1063          T->reason = 0;
       
  1064       }
       
  1065       /* if the local cut pool is not empty, select useful cuts and add
       
  1066          them to the current subproblem */
       
  1067       if (T->local->size > 0)
       
  1068       {  xassert(T->reason == 0);
       
  1069          T->reason = GLP_ICUTGEN;
       
  1070          ios_process_cuts(T);
       
  1071          T->reason = 0;
       
  1072       }
       
  1073       /* clear the local cut pool */
       
  1074       ios_clear_pool(T, T->local);
       
  1075       /* perform re-optimization, if necessary */
       
  1076       if (T->reopt)
       
  1077       {  T->reopt = 0;
       
  1078          T->curr->changed++;
       
  1079          goto more;
       
  1080       }
       
  1081       /* no cuts were generated; remove inactive cuts */
       
  1082       remove_cuts(T);
       
  1083       if (T->parm->msg_lev >= GLP_MSG_ALL && T->curr->level == 0)
       
  1084          display_cut_info(T);
       
  1085       /* update history information used on pseudocost branching */
       
  1086       if (T->pcost != NULL) ios_pcost_update(T);
       
  1087       /* it's time to perform branching */
       
  1088       xassert(T->br_var == 0);
       
  1089       xassert(T->br_sel == 0);
       
  1090       /* let the application program choose variable to branch on */
       
  1091       if (T->parm->cb_func != NULL)
       
  1092       {  xassert(T->reason == 0);
       
  1093          xassert(T->br_var == 0);
       
  1094          xassert(T->br_sel == 0);
       
  1095          T->reason = GLP_IBRANCH;
       
  1096          T->parm->cb_func(T, T->parm->cb_info);
       
  1097          T->reason = 0;
       
  1098          if (T->stop)
       
  1099          {  ret = GLP_ESTOP;
       
  1100             goto done;
       
  1101          }
       
  1102       }
       
  1103       /* if nothing has been chosen, choose some variable as specified
       
  1104          by the branching technique option */
       
  1105       if (T->br_var == 0)
       
  1106          T->br_var = ios_choose_var(T, &T->br_sel);
       
  1107       /* perform actual branching */
       
  1108       curr_p = T->curr->p;
       
  1109       ret = branch_on(T, T->br_var, T->br_sel);
       
  1110       T->br_var = T->br_sel = 0;
       
  1111       if (ret == 0)
       
  1112       {  /* both branches have been created */
       
  1113          pred_p = curr_p;
       
  1114          goto loop;
       
  1115       }
       
  1116       else if (ret == 1)
       
  1117       {  /* one branch is hopeless and has been pruned, so now the
       
  1118             current subproblem is other branch */
       
  1119          /* the current subproblem should be considered as a new one,
       
  1120             since one bound of the branching variable was changed */
       
  1121          T->curr->solved = T->curr->changed = 0;
       
  1122          goto more;
       
  1123       }
       
  1124       else if (ret == 2)
       
  1125       {  /* both branches are hopeless and have been pruned; new
       
  1126             subproblem selection is needed to continue the search */
       
  1127          goto fath;
       
  1128       }
       
  1129       else
       
  1130          xassert(ret != ret);
       
  1131 fath: /* the current subproblem has been fathomed */
       
  1132       if (T->parm->msg_lev >= GLP_MSG_DBG)
       
  1133          xprintf("Node %d fathomed\n", p);
       
  1134       /* freeze the current subproblem */
       
  1135       ios_freeze_node(T);
       
  1136       /* and prune the corresponding branch of the tree */
       
  1137       ios_delete_node(T, p);
       
  1138       /* if a new integer feasible solution has just been found, other
       
  1139          branches may become hopeless and therefore must be pruned */
       
  1140       if (T->mip->mip_stat == GLP_FEAS) cleanup_the_tree(T);
       
  1141       /* new subproblem selection is needed due to backtracking */
       
  1142       pred_p = 0;
       
  1143       goto loop;
       
  1144 done: /* display progress of the search on exit from the solver */
       
  1145       if (T->parm->msg_lev >= GLP_MSG_ON)
       
  1146          show_progress(T, 0);
       
  1147       if (T->mir_gen != NULL)
       
  1148          ios_mir_term(T->mir_gen), T->mir_gen = NULL;
       
  1149       if (T->clq_gen != NULL)
       
  1150          ios_clq_term(T->clq_gen), T->clq_gen = NULL;
       
  1151       /* return to the calling program */
       
  1152       return ret;
       
  1153 }
       
  1154 
       
  1155 /* eof */