1 /* glpios09.c (branching heuristics) */
3 /***********************************************************************
4 * This code is part of GLPK (GNU Linear Programming Kit).
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>.
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.
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.
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 ***********************************************************************/
27 /***********************************************************************
30 * ios_choose_var - select variable to branch on
35 * int ios_choose_var(glp_tree *T, int *next);
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.
44 * The routine ios_choose_var returns the ordinal number of the column
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);
52 int ios_choose_var(glp_tree *T, int *next)
54 if (T->parm->br_tech == GLP_BR_FFV)
55 { /* branch on first fractional variable */
56 j = branch_first(T, next);
58 else if (T->parm->br_tech == GLP_BR_LFV)
59 { /* branch on last fractional variable */
60 j = branch_last(T, next);
62 else if (T->parm->br_tech == GLP_BR_MFV)
63 { /* branch on most fractional variable */
64 j = branch_mostf(T, next);
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);
70 else if (T->parm->br_tech == GLP_BR_PCH)
71 { /* hybrid pseudocost heuristic */
72 j = ios_pcost_branch(T, next);
79 /***********************************************************************
80 * branch_first - choose first branching variable
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.
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. */
89 static int branch_first(glp_tree *T, int *_next)
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)
106 /***********************************************************************
107 * branch_last - choose last branching variable
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.
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. */
116 static int branch_last(glp_tree *T, int *_next)
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);
125 if (beta - floor(beta) < ceil(beta) - beta)
133 /***********************************************************************
134 * branch_mostf - choose most fractional branching variable
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.
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.
143 * (Alexander Martin notices that "...most infeasible is as good as
146 static int branch_mostf(glp_tree *T, int *_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++)
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);
168 /***********************************************************************
169 * branch_drtom - choose branching var using Driebeck-Tomlin heuristic
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.
175 * The routine also selects the branch to be solved next, again due to
176 * Driebeck and Tomlin.
178 * This routine is based on the heuristic proposed in:
180 * Driebeck N.J. An algorithm for the solution of mixed-integer
181 * programming problems, Management Science, 12: 576-87 (1966);
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).
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. */
193 static int branch_drtom(glp_tree *T, int *_next)
194 { glp_prob *mip = T->mip;
197 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
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 */
250 (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX);
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);
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
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)
278 delta_k = ceil(delta_k); /* +3.14 -> +4 */
280 delta_k = floor(delta_k); /* -3.14 -> -4 */
283 /* now determine the status and reduced cost of x[k] in the
286 { stat = glp_get_row_stat(mip, k);
287 dk = glp_get_row_dual(mip, k);
290 { stat = glp_get_col_stat(mip, k-m);
291 dk = glp_get_col_dual(mip, k-m);
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] */
298 if (stat == GLP_NL && dk < 0.0 ||
299 stat == GLP_NU && dk > 0.0 ||
300 stat == GLP_NF) dk = 0.0;
303 if (stat == GLP_NL && dk > 0.0 ||
304 stat == GLP_NU && dk < 0.0 ||
305 stat == GLP_NF) dk = 0.0;
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) */
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);
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;
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
339 if (degrad < fabs(dz_dn) || degrad < fabs(dz_up))
341 if (fabs(dz_dn) < fabs(dz_up))
342 { /* select down branch to be solved next */
344 degrad = fabs(dz_up);
347 { /* select up branch to be solved next */
349 degrad = fabs(dz_dn);
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;
359 /* free working arrays */
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);
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");
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");
380 xprintf("branch_drtom: up-branch bound is %.9e\n",
381 lpx_get_obj_val(mip) + dd_up);
387 /**********************************************************************/
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 */
407 void *ios_pcost_init(glp_tree *tree)
408 { /* initialize working data used on pseudocost branching */
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;
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 */
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;
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 */
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;
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)))
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 */
477 { /* the simplex solver failed */
480 /* delete the copy of P */
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 */
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
506 dx = tree->mip->col[j]->prim - tree->curr->up->br_val;
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 */
513 /* update history information */
515 { /* the current subproblem is down-branch */
517 csa->dn_sum[j] += psi;
520 { /* the current subproblem is up-branch */
522 csa->up_sum[j] += psi;
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);
540 static double eval_psi(glp_tree *T, int j, int brnch)
541 { /* compute estimation of pseudocost of variable x[j] for down-
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)
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)
558 csa->dn_sum[j] = degrad / (beta - floor(beta));
560 psi = csa->dn_sum[j] / (double)csa->dn_cnt[j];
562 else if (brnch == GLP_UP_BRNCH)
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)
573 csa->up_sum[j] = degrad / (ceil(beta) - beta);
575 psi = csa->up_sum[j] / (double)csa->up_cnt[j];
578 xassert(brnch != brnch);
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))
589 if (csa->dn_cnt[j] > 0 && csa->up_cnt[j] > 0) ni++;
592 xprintf("Pseudocosts initialized for %d of %d variables\n",
597 int ios_pcost_branch(glp_tree *T, int *_next)
598 { /* choose branching variable with pseudocost branching */
599 glp_long t = xtime();
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);
616 { /* down-branch has no primal feasible solution */
617 jjj = j, sel = GLP_DN_BRNCH;
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);
625 { /* up-branch has no primal feasible solution */
626 jjj = j, sel = GLP_UP_BRNCH;
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 */
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);
642 /* display progress of pseudocost initialization */
643 if (T->parm->msg_lev >= GLP_ON)
644 { if (xdifftime(xtime(), t) >= 10.0)
651 { /* no degradation is indicated; choose a variable having most
653 jjj = branch_mostf(T, &sel);