1 /* glpios09.c (branching heuristics) */
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 /***********************************************************************
GetUTF8SizeForUCS2(IN CHAR8 * Utf8Buffer)28 *  NAME
29 *
30 *  ios_choose_var - select variable to branch on
31 *
32 *  SYNOPSIS
33 *
34 *  #include "glpios.h"
35 *  int ios_choose_var(glp_tree *T, int *next);
36 *
37 *  The routine ios_choose_var chooses a variable from the candidate
38 *  list to branch on. Additionally the routine provides a flag stored
39 *  in the location next to suggests which of the child subproblems
40 *  should be solved next.
41 *
42 *  RETURNS
43 *
44 *  The routine ios_choose_var returns the ordinal number of the column
45 *  choosen. */
46 
47 static int branch_first(glp_tree *T, int *next);
48 static int branch_last(glp_tree *T, int *next);
49 static int branch_mostf(glp_tree *T, int *next);
50 static int branch_drtom(glp_tree *T, int *next);
51 
52 int ios_choose_var(glp_tree *T, int *next)
53 {     int j;
54       if (T->parm->br_tech == GLP_BR_FFV)
55       {  /* branch on first fractional variable */
56          j = branch_first(T, next);
57       }
58       else if (T->parm->br_tech == GLP_BR_LFV)
59       {  /* branch on last fractional variable */
60          j = branch_last(T, next);
61       }
62       else if (T->parm->br_tech == GLP_BR_MFV)
63       {  /* branch on most fractional variable */
64          j = branch_mostf(T, next);
65       }
66       else if (T->parm->br_tech == GLP_BR_DTH)
67       {  /* branch using the heuristic by Dreebeck and Tomlin */
68          j = branch_drtom(T, next);
69       }
70       else if (T->parm->br_tech == GLP_BR_PCH)
71       {  /* hybrid pseudocost heuristic */
72          j = ios_pcost_branch(T, next);
73       }
74       else
75          xassert(T != T);
GetUCS2CharByFormat(IN CHAR8 * Utf8Buffer,OUT CHAR16 * Ucs2Char)76       return j;
77 }
78 
79 /***********************************************************************
80 *  branch_first - choose first branching variable
81 *
82 *  This routine looks up the list of structural variables and chooses
83 *  the first one, which is of integer kind and has fractional value in
84 *  optimal solution to the current LP relaxation.
85 *
86 *  This routine also selects the branch to be solved next where integer
87 *  infeasibility of the chosen variable is less than in other one. */
88 
89 static int branch_first(glp_tree *T, int *_next)
90 {     int j, next;
91       double beta;
92       /* choose the column to branch on */
93       for (j = 1; j <= T->n; j++)
94          if (T->non_int[j]) break;
95       xassert(1 <= j && j <= T->n);
96       /* select the branch to be solved next */
97       beta = glp_get_col_prim(T->mip, j);
98       if (beta - floor(beta) < ceil(beta) - beta)
99          next = GLP_DN_BRNCH;
100       else
101          next = GLP_UP_BRNCH;
102       *_next = next;
103       return j;
104 }
105 
106 /***********************************************************************
107 *  branch_last - choose last branching variable
108 *
109 *  This routine looks up the list of structural variables and chooses
110 *  the last one, which is of integer kind and has fractional value in
111 *  optimal solution to the current LP relaxation.
112 *
113 *  This routine also selects the branch to be solved next where integer
114 *  infeasibility of the chosen variable is less than in other one. */
115 
116 static int branch_last(glp_tree *T, int *_next)
117 {     int j, next;
118       double beta;
119       /* choose the column to branch on */
120       for (j = T->n; j >= 1; j--)
121          if (T->non_int[j]) break;
122       xassert(1 <= j && j <= T->n);
123       /* select the branch to be solved next */
124       beta = glp_get_col_prim(T->mip, j);
UCS2CharToUTF8(IN CHAR16 Ucs2Char,OUT CHAR8 * Utf8Buffer)125       if (beta - floor(beta) < ceil(beta) - beta)
126          next = GLP_DN_BRNCH;
127       else
128          next = GLP_UP_BRNCH;
129       *_next = next;
130       return j;
131 }
132 
133 /***********************************************************************
134 *  branch_mostf - choose most fractional branching variable
135 *
136 *  This routine looks up the list of structural variables and chooses
137 *  that one, which is of integer kind and has most fractional value in
138 *  optimal solution to the current LP relaxation.
139 *
140 *  This routine also selects the branch to be solved next where integer
141 *  infeasibility of the chosen variable is less than in other one.
142 *
143 *  (Alexander Martin notices that "...most infeasible is as good as
144 *  random...".) */
145 
146 static int branch_mostf(glp_tree *T, int *_next)
147 {     int j, jj, next;
148       double beta, most, temp;
149       /* choose the column to branch on */
150       jj = 0, most = DBL_MAX;
151       for (j = 1; j <= T->n; j++)
152       {  if (T->non_int[j])
153          {  beta = glp_get_col_prim(T->mip, j);
154             temp = floor(beta) + 0.5;
155             if (most > fabs(beta - temp))
156             {  jj = j, most = fabs(beta - temp);
157                if (beta < temp)
158                   next = GLP_DN_BRNCH;
159                else
160                   next = GLP_UP_BRNCH;
161             }
162          }
163       }
164       *_next = next;
165       return jj;
166 }
167 
168 /***********************************************************************
169 *  branch_drtom - choose branching var using Driebeck-Tomlin heuristic
170 *
171 *  This routine chooses a structural variable, which is required to be
172 *  integral and has fractional value in optimal solution of the current
173 *  LP relaxation, using a heuristic proposed by Driebeck and Tomlin.
174 *
175 *  The routine also selects the branch to be solved next, again due to
UTF8ToUCS2Char(IN CHAR8 * Utf8Buffer,OUT CHAR16 * Ucs2Char)176 *  Driebeck and Tomlin.
177 *
178 *  This routine is based on the heuristic proposed in:
179 *
180 *  Driebeck N.J. An algorithm for the solution of mixed-integer
181 *  programming problems, Management Science, 12: 576-87 (1966);
182 *
183 *  and improved in:
184 *
185 *  Tomlin J.A. Branch and bound methods for integer and non-convex
186 *  programming, in J.Abadie (ed.), Integer and Nonlinear Programming,
187 *  North-Holland, Amsterdam, pp. 437-50 (1970).
188 *
189 *  Must note that this heuristic is time-expensive, because computing
190 *  one-step degradation (see the routine below) requires one BTRAN for
191 *  each fractional-valued structural variable. */
192 
193 static int branch_drtom(glp_tree *T, int *_next)
194 {     glp_prob *mip = T->mip;
195       int m = mip->m;
196       int n = mip->n;
197       unsigned char *non_int = T->non_int;
198       int j, jj, k, t, next, kase, len, stat, *ind;
199       double x, dk, alfa, delta_j, delta_k, delta_z, dz_dn, dz_up,
200          dd_dn, dd_up, degrad, *val;
201       /* basic solution of LP relaxation must be optimal */
202       xassert(glp_get_status(mip) == GLP_OPT);
203       /* allocate working arrays */
204       ind = xcalloc(1+n, sizeof(int));
205       val = xcalloc(1+n, sizeof(double));
206       /* nothing has been chosen so far */
207       jj = 0, degrad = -1.0;
208       /* walk through the list of columns (structural variables) */
209       for (j = 1; j <= n; j++)
210       {  /* if j-th column is not marked as fractional, skip it */
211          if (!non_int[j]) continue;
212          /* obtain (fractional) value of j-th column in basic solution
213             of LP relaxation */
214          x = glp_get_col_prim(mip, j);
215          /* since the value of j-th column is fractional, the column is
216             basic; compute corresponding row of the simplex table */
217          len = glp_eval_tab_row(mip, m+j, ind, val);
218          /* the following fragment computes a change in the objective
219             function: delta Z = new Z - old Z, where old Z is the
220             objective value in the current optimal basis, and new Z is
221             the objective value in the adjacent basis, for two cases:
222             1) if new upper bound ub' = floor(x[j]) is introduced for
223                j-th column (down branch);
224             2) if new lower bound lb' = ceil(x[j]) is introduced for
225                j-th column (up branch);
226             since in both cases the solution remaining dual feasible
227             becomes primal infeasible, one implicit simplex iteration
228             is performed to determine the change delta Z;
229             it is obvious that new Z, which is never better than old Z,
230             is a lower (minimization) or upper (maximization) bound of
231             the objective function for down- and up-branches. */
232          for (kase = -1; kase <= +1; kase += 2)
233          {  /* if kase < 0, the new upper bound of x[j] is introduced;
234                in this case x[j] should decrease in order to leave the
235                basis and go to its new upper bound */
236             /* if kase > 0, the new lower bound of x[j] is introduced;
237                in this case x[j] should increase in order to leave the
238                basis and go to its new lower bound */
239             /* apply the dual ratio test in order to determine which
240                auxiliary or structural variable should enter the basis
241                to keep dual feasibility */
242             k = glp_dual_rtest(mip, len, ind, val, kase, 1e-9);
243             if (k != 0) k = ind[k];
244             /* if no non-basic variable has been chosen, LP relaxation
245                of corresponding branch being primal infeasible and dual
246                unbounded has no primal feasible solution; in this case
247                the change delta Z is formally set to infinity */
248             if (k == 0)
249             {  delta_z =
250                   (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX);
251                goto skip;
252             }
253             /* row of the simplex table that corresponds to non-basic
254                variable x[k] choosen by the dual ratio test is:
255                   x[j] = ... + alfa * x[k] + ...
256                where alfa is the influence coefficient (an element of
257                the simplex table row) */
258             /* determine the coefficient alfa */
259             for (t = 1; t <= len; t++) if (ind[t] == k) break;
260             xassert(1 <= t && t <= len);
261             alfa = val[t];
262             /* since in the adjacent basis the variable x[j] becomes
263                non-basic, knowing its value in the current basis we can
264                determine its change delta x[j] = new x[j] - old x[j] */
265             delta_j = (kase < 0 ? floor(x) : ceil(x)) - x;
266             /* and knowing the coefficient alfa we can determine the
267                corresponding change delta x[k] = new x[k] - old x[k],
268                where old x[k] is a value of x[k] in the current basis,
269                and new x[k] is a value of x[k] in the adjacent basis */
270             delta_k = delta_j / alfa;
271             /* Tomlin noticed that if the variable x[k] is of integer
272                kind, its change cannot be less (eventually) than one in
273                the magnitude */
274             if (k > m && glp_get_col_kind(mip, k-m) != GLP_CV)
275             {  /* x[k] is structural integer variable */
276                if (fabs(delta_k - floor(delta_k + 0.5)) > 1e-3)
277                {  if (delta_k > 0.0)
278                      delta_k = ceil(delta_k);  /* +3.14 -> +4 */
279                   else
280                      delta_k = floor(delta_k); /* -3.14 -> -4 */
281                }
282             }
283             /* now determine the status and reduced cost of x[k] in the
284                current basis */
285             if (k <= m)
286             {  stat = glp_get_row_stat(mip, k);
287                dk = glp_get_row_dual(mip, k);
288             }
289             else
290             {  stat = glp_get_col_stat(mip, k-m);
291                dk = glp_get_col_dual(mip, k-m);
292             }
293             /* if the current basis is dual degenerate, some reduced
294                costs which are close to zero may have wrong sign due to
295                round-off errors, so correct the sign of d[k] */
296             switch (T->mip->dir)
297             {  case GLP_MIN:
298                   if (stat == GLP_NL && dk < 0.0 ||
299                       stat == GLP_NU && dk > 0.0 ||
300                       stat == GLP_NF) dk = 0.0;
301                   break;
302                case GLP_MAX:
303                   if (stat == GLP_NL && dk > 0.0 ||
304                       stat == GLP_NU && dk < 0.0 ||
305                       stat == GLP_NF) dk = 0.0;
306                   break;
307                default:
308                   xassert(T != T);
309             }
310             /* now knowing the change of x[k] and its reduced cost d[k]
311                we can compute the corresponding change in the objective
312                function delta Z = new Z - old Z = d[k] * delta x[k];
313                note that due to Tomlin's modification new Z can be even
314                worse than in the adjacent basis */
315             delta_z = dk * delta_k;
316 skip:       /* new Z is never better than old Z, therefore the change
317                delta Z is always non-negative (in case of minimization)
318                or non-positive (in case of maximization) */
319             switch (T->mip->dir)
320             {  case GLP_MIN: xassert(delta_z >= 0.0); break;
321                case GLP_MAX: xassert(delta_z <= 0.0); break;
322                default: xassert(T != T);
323             }
324             /* save the change in the objective fnction for down- and
325                up-branches, respectively */
326             if (kase < 0) dz_dn = delta_z; else dz_up = delta_z;
327          }
328          /* thus, in down-branch no integer feasible solution can be
329             better than Z + dz_dn, and in up-branch no integer feasible
330             solution can be better than Z + dz_up, where Z is value of
331             the objective function in the current basis */
332          /* following the heuristic by Driebeck and Tomlin we choose a
333             column (i.e. structural variable) which provides largest
334             degradation of the objective function in some of branches;
335             besides, we select the branch with smaller degradation to
336             be solved next and keep other branch with larger degradation
337             in the active list hoping to minimize the number of further
338             backtrackings */
339          if (degrad < fabs(dz_dn) || degrad < fabs(dz_up))
340          {  jj = j;
341             if (fabs(dz_dn) < fabs(dz_up))
342             {  /* select down branch to be solved next */
343                next = GLP_DN_BRNCH;
344                degrad = fabs(dz_up);
345             }
346             else
347             {  /* select up branch to be solved next */
348                next = GLP_UP_BRNCH;
349                degrad = fabs(dz_dn);
350             }
351             /* save the objective changes for printing */
352             dd_dn = dz_dn, dd_up = dz_up;
353             /* if down- or up-branch has no feasible solution, we does
354                not need to consider other candidates (in principle, the
355                corresponding branch could be pruned right now) */
356             if (degrad == DBL_MAX) break;
357          }
358       }
359       /* free working arrays */
360       xfree(ind);
361       xfree(val);
362       /* something must be chosen */
363       xassert(1 <= jj && jj <= n);
364 #if 1 /* 02/XI-2009 */
365       if (degrad < 1e-6 * (1.0 + 0.001 * fabs(mip->obj_val)))
366       {  jj = branch_mostf(T, &next);
367          goto done;
368       }
369 #endif
370       if (T->parm->msg_lev >= GLP_MSG_DBG)
371       {  xprintf("branch_drtom: column %d chosen to branch on\n", jj);
372          if (fabs(dd_dn) == DBL_MAX)
373             xprintf("branch_drtom: down-branch is infeasible\n");
374          else
375             xprintf("branch_drtom: down-branch bound is %.9e\n",
376                lpx_get_obj_val(mip) + dd_dn);
377          if (fabs(dd_up) == DBL_MAX)
378             xprintf("branch_drtom: up-branch   is infeasible\n");
379          else
380             xprintf("branch_drtom: up-branch   bound is %.9e\n",
381                lpx_get_obj_val(mip) + dd_up);
382       }
383 done: *_next = next;
384       return jj;
385 }
386 
387 /**********************************************************************/
388 
389 struct csa
390 {     /* common storage area */
391       int *dn_cnt; /* int dn_cnt[1+n]; */
392       /* dn_cnt[j] is the number of subproblems, whose LP relaxations
393          have been solved and which are down-branches for variable x[j];
394          dn_cnt[j] = 0 means the down pseudocost is uninitialized */
395       double *dn_sum; /* double dn_sum[1+n]; */
396       /* dn_sum[j] is the sum of per unit degradations of the objective
397          over all dn_cnt[j] subproblems */
398       int *up_cnt; /* int up_cnt[1+n]; */
399       /* up_cnt[j] is the number of subproblems, whose LP relaxations
400          have been solved and which are up-branches for variable x[j];
401          up_cnt[j] = 0 means the up pseudocost is uninitialized */
402       double *up_sum; /* double up_sum[1+n]; */
403       /* up_sum[j] is the sum of per unit degradations of the objective
404          over all up_cnt[j] subproblems */
405 };
406 
407 void *ios_pcost_init(glp_tree *tree)
408 {     /* initialize working data used on pseudocost branching */
409       struct csa *csa;
410       int n = tree->n, j;
411       csa = xmalloc(sizeof(struct csa));
412       csa->dn_cnt = xcalloc(1+n, sizeof(int));
413       csa->dn_sum = xcalloc(1+n, sizeof(double));
414       csa->up_cnt = xcalloc(1+n, sizeof(int));
415       csa->up_sum = xcalloc(1+n, sizeof(double));
416       for (j = 1; j <= n; j++)
417       {  csa->dn_cnt[j] = csa->up_cnt[j] = 0;
418          csa->dn_sum[j] = csa->up_sum[j] = 0.0;
419       }
420       return csa;
421 }
422 
423 static double eval_degrad(glp_prob *P, int j, double bnd)
424 {     /* compute degradation of the objective on fixing x[j] at given
425          value with a limited number of dual simplex iterations */
426       /* this routine fixes column x[j] at specified value bnd,
427          solves resulting LP, and returns a lower bound to degradation
428          of the objective, degrad >= 0 */
429       glp_prob *lp;
430       glp_smcp parm;
431       int ret;
432       double degrad;
433       /* the current basis must be optimal */
434       xassert(glp_get_status(P) == GLP_OPT);
435       /* create a copy of P */
436       lp = glp_create_prob();
437       glp_copy_prob(lp, P, 0);
438       /* fix column x[j] at specified value */
439       glp_set_col_bnds(lp, j, GLP_FX, bnd, bnd);
440       /* try to solve resulting LP */
441       glp_init_smcp(&parm);
442       parm.msg_lev = GLP_MSG_OFF;
443       parm.meth = GLP_DUAL;
444       parm.it_lim = 30;
445       parm.out_dly = 1000;
446       parm.meth = GLP_DUAL;
447       ret = glp_simplex(lp, &parm);
448       if (ret == 0 || ret == GLP_EITLIM)
449       {  if (glp_get_prim_stat(lp) == GLP_NOFEAS)
450          {  /* resulting LP has no primal feasible solution */
451             degrad = DBL_MAX;
452          }
453          else if (glp_get_dual_stat(lp) == GLP_FEAS)
454          {  /* resulting basis is optimal or at least dual feasible,
455                so we have the correct lower bound to degradation */
456             if (P->dir == GLP_MIN)
457                degrad = lp->obj_val - P->obj_val;
458             else if (P->dir == GLP_MAX)
459                degrad = P->obj_val - lp->obj_val;
460             else
461                xassert(P != P);
462             /* degradation cannot be negative by definition */
463             /* note that the lower bound to degradation may be close
464                to zero even if its exact value is zero due to round-off
465                errors on computing the objective value */
466             if (degrad < 1e-6 * (1.0 + 0.001 * fabs(P->obj_val)))
467                degrad = 0.0;
468          }
469          else
470          {  /* the final basis reported by the simplex solver is dual
471                infeasible, so we cannot determine a non-trivial lower
472                bound to degradation */
473             degrad = 0.0;
474          }
475       }
476       else
477       {  /* the simplex solver failed */
478          degrad = 0.0;
479       }
480       /* delete the copy of P */
481       glp_delete_prob(lp);
482       return degrad;
483 }
484 
485 void ios_pcost_update(glp_tree *tree)
486 {     /* update history information for pseudocost branching */
487       /* this routine is called every time when LP relaxation of the
488          current subproblem has been solved to optimality with all lazy
489          and cutting plane constraints included */
490       int j;
491       double dx, dz, psi;
492       struct csa *csa = tree->pcost;
493       xassert(csa != NULL);
494       xassert(tree->curr != NULL);
495       /* if the current subproblem is the root, skip updating */
496       if (tree->curr->up == NULL) goto skip;
497       /* determine branching variable x[j], which was used in the
498          parent subproblem to create the current subproblem */
499       j = tree->curr->up->br_var;
500       xassert(1 <= j && j <= tree->n);
501       /* determine the change dx[j] = new x[j] - old x[j],
502          where new x[j] is a value of x[j] in optimal solution to LP
503          relaxation of the current subproblem, old x[j] is a value of
504          x[j] in optimal solution to LP relaxation of the parent
505          subproblem */
506       dx = tree->mip->col[j]->prim - tree->curr->up->br_val;
507       xassert(dx != 0.0);
508       /* determine corresponding change dz = new dz - old dz in the
509          objective function value */
510       dz = tree->mip->obj_val - tree->curr->up->lp_obj;
511       /* determine per unit degradation of the objective function */
512       psi = fabs(dz / dx);
513       /* update history information */
514       if (dx < 0.0)
515       {  /* the current subproblem is down-branch */
516          csa->dn_cnt[j]++;
517          csa->dn_sum[j] += psi;
518       }
519       else /* dx > 0.0 */
520       {  /* the current subproblem is up-branch */
521          csa->up_cnt[j]++;
522          csa->up_sum[j] += psi;
523       }
524 skip: return;
525 }
526 
527 void ios_pcost_free(glp_tree *tree)
528 {     /* free working area used on pseudocost branching */
529       struct csa *csa = tree->pcost;
530       xassert(csa != NULL);
531       xfree(csa->dn_cnt);
532       xfree(csa->dn_sum);
533       xfree(csa->up_cnt);
534       xfree(csa->up_sum);
535       xfree(csa);
536       tree->pcost = NULL;
537       return;
538 }
539 
540 static double eval_psi(glp_tree *T, int j, int brnch)
541 {     /* compute estimation of pseudocost of variable x[j] for down-
542          or up-branch */
543       struct csa *csa = T->pcost;
544       double beta, degrad, psi;
545       xassert(csa != NULL);
546       xassert(1 <= j && j <= T->n);
547       if (brnch == GLP_DN_BRNCH)
548       {  /* down-branch */
549          if (csa->dn_cnt[j] == 0)
550          {  /* initialize down pseudocost */
551             beta = T->mip->col[j]->prim;
552             degrad = eval_degrad(T->mip, j, floor(beta));
553             if (degrad == DBL_MAX)
554             {  psi = DBL_MAX;
555                goto done;
556             }
557             csa->dn_cnt[j] = 1;
558             csa->dn_sum[j] = degrad / (beta - floor(beta));
559          }
560          psi = csa->dn_sum[j] / (double)csa->dn_cnt[j];
561       }
562       else if (brnch == GLP_UP_BRNCH)
563       {  /* up-branch */
564          if (csa->up_cnt[j] == 0)
565          {  /* initialize up pseudocost */
566             beta = T->mip->col[j]->prim;
567             degrad = eval_degrad(T->mip, j, ceil(beta));
568             if (degrad == DBL_MAX)
569             {  psi = DBL_MAX;
570                goto done;
571             }
572             csa->up_cnt[j] = 1;
573             csa->up_sum[j] = degrad / (ceil(beta) - beta);
574          }
575          psi = csa->up_sum[j] / (double)csa->up_cnt[j];
576       }
577       else
578          xassert(brnch != brnch);
579 done: return psi;
580 }
581 
582 static void progress(glp_tree *T)
583 {     /* display progress of pseudocost initialization */
584       struct csa *csa = T->pcost;
585       int j, nv = 0, ni = 0;
586       for (j = 1; j <= T->n; j++)
587       {  if (glp_ios_can_branch(T, j))
588          {  nv++;
589             if (csa->dn_cnt[j] > 0 && csa->up_cnt[j] > 0) ni++;
590          }
591       }
592       xprintf("Pseudocosts initialized for %d of %d variables\n",
593          ni, nv);
594       return;
595 }
596 
597 int ios_pcost_branch(glp_tree *T, int *_next)
598 {     /* choose branching variable with pseudocost branching */
599       glp_long t = xtime();
600       int j, jjj, sel;
601       double beta, psi, d1, d2, d, dmax;
602       /* initialize the working arrays */
603       if (T->pcost == NULL)
604          T->pcost = ios_pcost_init(T);
605       /* nothing has been chosen so far */
606       jjj = 0, dmax = -1.0;
607       /* go through the list of branching candidates */
608       for (j = 1; j <= T->n; j++)
609       {  if (!glp_ios_can_branch(T, j)) continue;
610          /* determine primal value of x[j] in optimal solution to LP
611             relaxation of the current subproblem */
612          beta = T->mip->col[j]->prim;
613          /* estimate pseudocost of x[j] for down-branch */
614          psi = eval_psi(T, j, GLP_DN_BRNCH);
615          if (psi == DBL_MAX)
616          {  /* down-branch has no primal feasible solution */
617             jjj = j, sel = GLP_DN_BRNCH;
618             goto done;
619          }
620          /* estimate degradation of the objective for down-branch */
621          d1 = psi * (beta - floor(beta));
622          /* estimate pseudocost of x[j] for up-branch */
623          psi = eval_psi(T, j, GLP_UP_BRNCH);
624          if (psi == DBL_MAX)
625          {  /* up-branch has no primal feasible solution */
626             jjj = j, sel = GLP_UP_BRNCH;
627             goto done;
628          }
629          /* estimate degradation of the objective for up-branch */
630          d2 = psi * (ceil(beta) - beta);
631          /* determine d = max(d1, d2) */
632          d = (d1 > d2 ? d1 : d2);
633          /* choose x[j] which provides maximal estimated degradation of
634             the objective either in down- or up-branch */
635          if (dmax < d)
636          {  dmax = d;
637             jjj = j;
638             /* continue the search from a subproblem, where degradation
639                is less than in other one */
640             sel = (d1 <= d2 ? GLP_DN_BRNCH : GLP_UP_BRNCH);
641          }
642          /* display progress of pseudocost initialization */
643          if (T->parm->msg_lev >= GLP_ON)
644          {  if (xdifftime(xtime(), t) >= 10.0)
645             {  progress(T);
646                t = xtime();
647             }
648          }
649       }
650       if (dmax == 0.0)
651       {  /* no degradation is indicated; choose a variable having most
652             fractional value */
653          jjj = branch_mostf(T, &sel);
654       }
655 done: *_next = sel;
656       return jjj;
657 }
658 
659 /* eof */
660