glpios09.c 26 KB

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