glpios12.c 5.7 KB

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