177 lines
5.7 KiB

  1. /* glpios12.c (node selection 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, 2011, 2013 Andrew Makhorin, Department for Applied
  7. * Informatics, Moscow Aviation Institute, Moscow, Russia. All rights
  8. * reserved. 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 "env.h"
  24. #include "glpios.h"
  25. /***********************************************************************
  26. * NAME
  27. *
  28. * ios_choose_node - select subproblem to continue the search
  29. *
  30. * SYNOPSIS
  31. *
  32. * #include "glpios.h"
  33. * int ios_choose_node(glp_tree *T);
  34. *
  35. * DESCRIPTION
  36. *
  37. * The routine ios_choose_node selects a subproblem from the active
  38. * list to continue the search. The choice depends on the backtracking
  39. * technique option.
  40. *
  41. * RETURNS
  42. *
  43. * The routine ios_choose_node return the reference number of the
  44. * subproblem selected. */
  45. static int most_feas(glp_tree *T);
  46. static int best_proj(glp_tree *T);
  47. static int best_node(glp_tree *T);
  48. int ios_choose_node(glp_tree *T)
  49. { int p;
  50. if (T->parm->bt_tech == GLP_BT_DFS)
  51. { /* depth first search */
  52. xassert(T->tail != NULL);
  53. p = T->tail->p;
  54. }
  55. else if (T->parm->bt_tech == GLP_BT_BFS)
  56. { /* breadth first search */
  57. xassert(T->head != NULL);
  58. p = T->head->p;
  59. }
  60. else if (T->parm->bt_tech == GLP_BT_BLB)
  61. { /* select node with best local bound */
  62. p = best_node(T);
  63. }
  64. else if (T->parm->bt_tech == GLP_BT_BPH)
  65. { if (T->mip->mip_stat == GLP_UNDEF)
  66. { /* "most integer feasible" subproblem */
  67. p = most_feas(T);
  68. }
  69. else
  70. { /* best projection heuristic */
  71. p = best_proj(T);
  72. }
  73. }
  74. else
  75. xassert(T != T);
  76. return p;
  77. }
  78. static int most_feas(glp_tree *T)
  79. { /* select subproblem whose parent has minimal sum of integer
  80. infeasibilities */
  81. IOSNPD *node;
  82. int p;
  83. double best;
  84. p = 0, best = DBL_MAX;
  85. for (node = T->head; node != NULL; node = node->next)
  86. { xassert(node->up != NULL);
  87. if (best > node->up->ii_sum)
  88. p = node->p, best = node->up->ii_sum;
  89. }
  90. return p;
  91. }
  92. static int best_proj(glp_tree *T)
  93. { /* select subproblem using the best projection heuristic */
  94. IOSNPD *root, *node;
  95. int p;
  96. double best, deg, obj;
  97. /* the global bound must exist */
  98. xassert(T->mip->mip_stat == GLP_FEAS);
  99. /* obtain pointer to the root node, which must exist */
  100. root = T->slot[1].node;
  101. xassert(root != NULL);
  102. /* deg estimates degradation of the objective function per unit
  103. of the sum of integer infeasibilities */
  104. xassert(root->ii_sum > 0.0);
  105. deg = (T->mip->mip_obj - root->bound) / root->ii_sum;
  106. /* nothing has been selected so far */
  107. p = 0, best = DBL_MAX;
  108. /* walk through the list of active subproblems */
  109. for (node = T->head; node != NULL; node = node->next)
  110. { xassert(node->up != NULL);
  111. /* obj estimates optimal objective value if the sum of integer
  112. infeasibilities were zero */
  113. obj = node->up->bound + deg * node->up->ii_sum;
  114. if (T->mip->dir == GLP_MAX) obj = - obj;
  115. /* select the subproblem which has the best estimated optimal
  116. objective value */
  117. if (best > obj) p = node->p, best = obj;
  118. }
  119. return p;
  120. }
  121. static int best_node(glp_tree *T)
  122. { /* select subproblem with best local bound */
  123. IOSNPD *node, *best = NULL;
  124. double bound, eps;
  125. switch (T->mip->dir)
  126. { case GLP_MIN:
  127. bound = +DBL_MAX;
  128. for (node = T->head; node != NULL; node = node->next)
  129. if (bound > node->bound) bound = node->bound;
  130. xassert(bound != +DBL_MAX);
  131. eps = 1e-10 * (1.0 + fabs(bound));
  132. for (node = T->head; node != NULL; node = node->next)
  133. { if (node->bound <= bound + eps)
  134. { xassert(node->up != NULL);
  135. if (best == NULL ||
  136. #if 1
  137. best->up->ii_sum > node->up->ii_sum) best = node;
  138. #else
  139. best->lp_obj > node->lp_obj) best = node;
  140. #endif
  141. }
  142. }
  143. break;
  144. case GLP_MAX:
  145. bound = -DBL_MAX;
  146. for (node = T->head; node != NULL; node = node->next)
  147. if (bound < node->bound) bound = node->bound;
  148. xassert(bound != -DBL_MAX);
  149. eps = 1e-10 * (1.0 + fabs(bound));
  150. for (node = T->head; node != NULL; node = node->next)
  151. { if (node->bound >= bound - eps)
  152. { xassert(node->up != NULL);
  153. if (best == NULL ||
  154. #if 1
  155. best->up->ii_sum > node->up->ii_sum) best = node;
  156. #else
  157. best->lp_obj < node->lp_obj) best = node;
  158. #endif
  159. }
  160. }
  161. break;
  162. default:
  163. xassert(T != T);
  164. }
  165. xassert(best != NULL);
  166. return best->p;
  167. }
  168. /* eof */