lemon-project-template-glpk
comparison deps/glpk/src/glpios03.c @ 11:4fc6ad2fb8a6
Test GLPK in src/main.cc
author | Alpar Juttner <alpar@cs.elte.hu> |
---|---|
date | Sun, 06 Nov 2011 21:43:29 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cb5946c6d1db |
---|---|
1 /* glpios03.c (branch-and-cut driver) */ | |
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, 2011 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 /*********************************************************************** | |
28 * show_progress - display current progress of the search | |
29 * | |
30 * This routine displays some information about current progress of the | |
31 * search. | |
32 * | |
33 * The information includes: | |
34 * | |
35 * the current number of iterations performed by the simplex solver; | |
36 * | |
37 * the objective value for the best known integer feasible solution, | |
38 * which is upper (minimization) or lower (maximization) global bound | |
39 * for optimal solution of the original mip problem; | |
40 * | |
41 * the best local bound for active nodes, which is lower (minimization) | |
42 * or upper (maximization) global bound for optimal solution of the | |
43 * original mip problem; | |
44 * | |
45 * the relative mip gap, in percents; | |
46 * | |
47 * the number of open (active) subproblems; | |
48 * | |
49 * the number of completely explored subproblems, i.e. whose nodes have | |
50 * been removed from the tree. */ | |
51 | |
52 static void show_progress(glp_tree *T, int bingo) | |
53 { int p; | |
54 double temp; | |
55 char best_mip[50], best_bound[50], *rho, rel_gap[50]; | |
56 /* format the best known integer feasible solution */ | |
57 if (T->mip->mip_stat == GLP_FEAS) | |
58 sprintf(best_mip, "%17.9e", T->mip->mip_obj); | |
59 else | |
60 sprintf(best_mip, "%17s", "not found yet"); | |
61 /* determine reference number of an active subproblem whose local | |
62 bound is best */ | |
63 p = ios_best_node(T); | |
64 /* format the best bound */ | |
65 if (p == 0) | |
66 sprintf(best_bound, "%17s", "tree is empty"); | |
67 else | |
68 { temp = T->slot[p].node->bound; | |
69 if (temp == -DBL_MAX) | |
70 sprintf(best_bound, "%17s", "-inf"); | |
71 else if (temp == +DBL_MAX) | |
72 sprintf(best_bound, "%17s", "+inf"); | |
73 else | |
74 sprintf(best_bound, "%17.9e", temp); | |
75 } | |
76 /* choose the relation sign between global bounds */ | |
77 if (T->mip->dir == GLP_MIN) | |
78 rho = ">="; | |
79 else if (T->mip->dir == GLP_MAX) | |
80 rho = "<="; | |
81 else | |
82 xassert(T != T); | |
83 /* format the relative mip gap */ | |
84 temp = ios_relative_gap(T); | |
85 if (temp == 0.0) | |
86 sprintf(rel_gap, " 0.0%%"); | |
87 else if (temp < 0.001) | |
88 sprintf(rel_gap, "< 0.1%%"); | |
89 else if (temp <= 9.999) | |
90 sprintf(rel_gap, "%5.1f%%", 100.0 * temp); | |
91 else | |
92 sprintf(rel_gap, "%6s", ""); | |
93 /* display progress of the search */ | |
94 xprintf("+%6d: %s %s %s %s %s (%d; %d)\n", | |
95 T->mip->it_cnt, bingo ? ">>>>>" : "mip =", best_mip, rho, | |
96 best_bound, rel_gap, T->a_cnt, T->t_cnt - T->n_cnt); | |
97 T->tm_lag = xtime(); | |
98 return; | |
99 } | |
100 | |
101 /*********************************************************************** | |
102 * is_branch_hopeful - check if specified branch is hopeful | |
103 * | |
104 * This routine checks if the specified subproblem can have an integer | |
105 * optimal solution which is better than the best known one. | |
106 * | |
107 * The check is based on comparison of the local objective bound stored | |
108 * in the subproblem descriptor and the incumbent objective value which | |
109 * is the global objective bound. | |
110 * | |
111 * If there is a chance that the specified subproblem can have a better | |
112 * integer optimal solution, the routine returns non-zero. Otherwise, if | |
113 * the corresponding branch can pruned, zero is returned. */ | |
114 | |
115 static int is_branch_hopeful(glp_tree *T, int p) | |
116 { xassert(1 <= p && p <= T->nslots); | |
117 xassert(T->slot[p].node != NULL); | |
118 return ios_is_hopeful(T, T->slot[p].node->bound); | |
119 } | |
120 | |
121 /*********************************************************************** | |
122 * check_integrality - check integrality of basic solution | |
123 * | |
124 * This routine checks if the basic solution of LP relaxation of the | |
125 * current subproblem satisfies to integrality conditions, i.e. that all | |
126 * variables of integer kind have integral primal values. (The solution | |
127 * is assumed to be optimal.) | |
128 * | |
129 * For each variable of integer kind the routine computes the following | |
130 * quantity: | |
131 * | |
132 * ii(x[j]) = min(x[j] - floor(x[j]), ceil(x[j]) - x[j]), (1) | |
133 * | |
134 * which is a measure of the integer infeasibility (non-integrality) of | |
135 * x[j] (for example, ii(2.1) = 0.1, ii(3.7) = 0.3, ii(5.0) = 0). It is | |
136 * understood that 0 <= ii(x[j]) <= 0.5, and variable x[j] is integer | |
137 * feasible if ii(x[j]) = 0. However, due to floating-point arithmetic | |
138 * the routine checks less restrictive condition: | |
139 * | |
140 * ii(x[j]) <= tol_int, (2) | |
141 * | |
142 * where tol_int is a given tolerance (small positive number) and marks | |
143 * each variable which does not satisfy to (2) as integer infeasible by | |
144 * setting its fractionality flag. | |
145 * | |
146 * In order to characterize integer infeasibility of the basic solution | |
147 * in the whole the routine computes two parameters: ii_cnt, which is | |
148 * the number of variables with the fractionality flag set, and ii_sum, | |
149 * which is the sum of integer infeasibilities (1). */ | |
150 | |
151 static void check_integrality(glp_tree *T) | |
152 { glp_prob *mip = T->mip; | |
153 int j, type, ii_cnt = 0; | |
154 double lb, ub, x, temp1, temp2, ii_sum = 0.0; | |
155 /* walk through the set of columns (structural variables) */ | |
156 for (j = 1; j <= mip->n; j++) | |
157 { GLPCOL *col = mip->col[j]; | |
158 T->non_int[j] = 0; | |
159 /* if the column is not integer, skip it */ | |
160 if (col->kind != GLP_IV) continue; | |
161 /* if the column is non-basic, it is integer feasible */ | |
162 if (col->stat != GLP_BS) continue; | |
163 /* obtain the type and bounds of the column */ | |
164 type = col->type, lb = col->lb, ub = col->ub; | |
165 /* obtain value of the column in optimal basic solution */ | |
166 x = col->prim; | |
167 /* if the column's primal value is close to the lower bound, | |
168 the column is integer feasible within given tolerance */ | |
169 if (type == GLP_LO || type == GLP_DB || type == GLP_FX) | |
170 { temp1 = lb - T->parm->tol_int; | |
171 temp2 = lb + T->parm->tol_int; | |
172 if (temp1 <= x && x <= temp2) continue; | |
173 #if 0 | |
174 /* the lower bound must not be violated */ | |
175 xassert(x >= lb); | |
176 #else | |
177 if (x < lb) continue; | |
178 #endif | |
179 } | |
180 /* if the column's primal value is close to the upper bound, | |
181 the column is integer feasible within given tolerance */ | |
182 if (type == GLP_UP || type == GLP_DB || type == GLP_FX) | |
183 { temp1 = ub - T->parm->tol_int; | |
184 temp2 = ub + T->parm->tol_int; | |
185 if (temp1 <= x && x <= temp2) continue; | |
186 #if 0 | |
187 /* the upper bound must not be violated */ | |
188 xassert(x <= ub); | |
189 #else | |
190 if (x > ub) continue; | |
191 #endif | |
192 } | |
193 /* if the column's primal value is close to nearest integer, | |
194 the column is integer feasible within given tolerance */ | |
195 temp1 = floor(x + 0.5) - T->parm->tol_int; | |
196 temp2 = floor(x + 0.5) + T->parm->tol_int; | |
197 if (temp1 <= x && x <= temp2) continue; | |
198 /* otherwise the column is integer infeasible */ | |
199 T->non_int[j] = 1; | |
200 /* increase the number of fractional-valued columns */ | |
201 ii_cnt++; | |
202 /* compute the sum of integer infeasibilities */ | |
203 temp1 = x - floor(x); | |
204 temp2 = ceil(x) - x; | |
205 xassert(temp1 > 0.0 && temp2 > 0.0); | |
206 ii_sum += (temp1 <= temp2 ? temp1 : temp2); | |
207 } | |
208 /* store ii_cnt and ii_sum to the current problem descriptor */ | |
209 xassert(T->curr != NULL); | |
210 T->curr->ii_cnt = ii_cnt; | |
211 T->curr->ii_sum = ii_sum; | |
212 /* and also display these parameters */ | |
213 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
214 { if (ii_cnt == 0) | |
215 xprintf("There are no fractional columns\n"); | |
216 else if (ii_cnt == 1) | |
217 xprintf("There is one fractional column, integer infeasibil" | |
218 "ity is %.3e\n", ii_sum); | |
219 else | |
220 xprintf("There are %d fractional columns, integer infeasibi" | |
221 "lity is %.3e\n", ii_cnt, ii_sum); | |
222 } | |
223 return; | |
224 } | |
225 | |
226 /*********************************************************************** | |
227 * record_solution - record better integer feasible solution | |
228 * | |
229 * This routine records optimal basic solution of LP relaxation of the | |
230 * current subproblem, which being integer feasible is better than the | |
231 * best known integer feasible solution. */ | |
232 | |
233 static void record_solution(glp_tree *T) | |
234 { glp_prob *mip = T->mip; | |
235 int i, j; | |
236 mip->mip_stat = GLP_FEAS; | |
237 mip->mip_obj = mip->obj_val; | |
238 for (i = 1; i <= mip->m; i++) | |
239 { GLPROW *row = mip->row[i]; | |
240 row->mipx = row->prim; | |
241 } | |
242 for (j = 1; j <= mip->n; j++) | |
243 { GLPCOL *col = mip->col[j]; | |
244 if (col->kind == GLP_CV) | |
245 col->mipx = col->prim; | |
246 else if (col->kind == GLP_IV) | |
247 { /* value of the integer column must be integral */ | |
248 col->mipx = floor(col->prim + 0.5); | |
249 } | |
250 else | |
251 xassert(col != col); | |
252 } | |
253 T->sol_cnt++; | |
254 return; | |
255 } | |
256 | |
257 /*********************************************************************** | |
258 * fix_by_red_cost - fix non-basic integer columns by reduced costs | |
259 * | |
260 * This routine fixes some non-basic integer columns if their reduced | |
261 * costs indicate that increasing (decreasing) the column at least by | |
262 * one involves the objective value becoming worse than the incumbent | |
263 * objective value. */ | |
264 | |
265 static void fix_by_red_cost(glp_tree *T) | |
266 { glp_prob *mip = T->mip; | |
267 int j, stat, fixed = 0; | |
268 double obj, lb, ub, dj; | |
269 /* the global bound must exist */ | |
270 xassert(T->mip->mip_stat == GLP_FEAS); | |
271 /* basic solution of LP relaxation must be optimal */ | |
272 xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); | |
273 /* determine the objective function value */ | |
274 obj = mip->obj_val; | |
275 /* walk through the column list */ | |
276 for (j = 1; j <= mip->n; j++) | |
277 { GLPCOL *col = mip->col[j]; | |
278 /* if the column is not integer, skip it */ | |
279 if (col->kind != GLP_IV) continue; | |
280 /* obtain bounds of j-th column */ | |
281 lb = col->lb, ub = col->ub; | |
282 /* and determine its status and reduced cost */ | |
283 stat = col->stat, dj = col->dual; | |
284 /* analyze the reduced cost */ | |
285 switch (mip->dir) | |
286 { case GLP_MIN: | |
287 /* minimization */ | |
288 if (stat == GLP_NL) | |
289 { /* j-th column is non-basic on its lower bound */ | |
290 if (dj < 0.0) dj = 0.0; | |
291 if (obj + dj >= mip->mip_obj) | |
292 glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; | |
293 } | |
294 else if (stat == GLP_NU) | |
295 { /* j-th column is non-basic on its upper bound */ | |
296 if (dj > 0.0) dj = 0.0; | |
297 if (obj - dj >= mip->mip_obj) | |
298 glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; | |
299 } | |
300 break; | |
301 case GLP_MAX: | |
302 /* maximization */ | |
303 if (stat == GLP_NL) | |
304 { /* j-th column is non-basic on its lower bound */ | |
305 if (dj > 0.0) dj = 0.0; | |
306 if (obj + dj <= mip->mip_obj) | |
307 glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; | |
308 } | |
309 else if (stat == GLP_NU) | |
310 { /* j-th column is non-basic on its upper bound */ | |
311 if (dj < 0.0) dj = 0.0; | |
312 if (obj - dj <= mip->mip_obj) | |
313 glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; | |
314 } | |
315 break; | |
316 default: | |
317 xassert(T != T); | |
318 } | |
319 } | |
320 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
321 { if (fixed == 0) | |
322 /* nothing to say */; | |
323 else if (fixed == 1) | |
324 xprintf("One column has been fixed by reduced cost\n"); | |
325 else | |
326 xprintf("%d columns have been fixed by reduced costs\n", | |
327 fixed); | |
328 } | |
329 /* fixing non-basic columns on their current bounds does not | |
330 change the basic solution */ | |
331 xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); | |
332 return; | |
333 } | |
334 | |
335 /*********************************************************************** | |
336 * branch_on - perform branching on specified variable | |
337 * | |
338 * This routine performs branching on j-th column (structural variable) | |
339 * of the current subproblem. The specified column must be of integer | |
340 * kind and must have a fractional value in optimal basic solution of | |
341 * LP relaxation of the current subproblem (i.e. only columns for which | |
342 * the flag non_int[j] is set are valid candidates to branch on). | |
343 * | |
344 * Let x be j-th structural variable, and beta be its primal fractional | |
345 * value in the current basic solution. Branching on j-th variable is | |
346 * dividing the current subproblem into two new subproblems, which are | |
347 * identical to the current subproblem with the following exception: in | |
348 * the first subproblem that begins the down-branch x has a new upper | |
349 * bound x <= floor(beta), and in the second subproblem that begins the | |
350 * up-branch x has a new lower bound x >= ceil(beta). | |
351 * | |
352 * Depending on estimation of local bounds for down- and up-branches | |
353 * this routine returns the following: | |
354 * | |
355 * 0 - both branches have been created; | |
356 * 1 - one branch is hopeless and has been pruned, so now the current | |
357 * subproblem is other branch; | |
358 * 2 - both branches are hopeless and have been pruned; new subproblem | |
359 * selection is needed to continue the search. */ | |
360 | |
361 static int branch_on(glp_tree *T, int j, int next) | |
362 { glp_prob *mip = T->mip; | |
363 IOSNPD *node; | |
364 int m = mip->m; | |
365 int n = mip->n; | |
366 int type, dn_type, up_type, dn_bad, up_bad, p, ret, clone[1+2]; | |
367 double lb, ub, beta, new_ub, new_lb, dn_lp, up_lp, dn_bnd, up_bnd; | |
368 /* determine bounds and value of x[j] in optimal solution to LP | |
369 relaxation of the current subproblem */ | |
370 xassert(1 <= j && j <= n); | |
371 type = mip->col[j]->type; | |
372 lb = mip->col[j]->lb; | |
373 ub = mip->col[j]->ub; | |
374 beta = mip->col[j]->prim; | |
375 /* determine new bounds of x[j] for down- and up-branches */ | |
376 new_ub = floor(beta); | |
377 new_lb = ceil(beta); | |
378 switch (type) | |
379 { case GLP_FR: | |
380 dn_type = GLP_UP; | |
381 up_type = GLP_LO; | |
382 break; | |
383 case GLP_LO: | |
384 xassert(lb <= new_ub); | |
385 dn_type = (lb == new_ub ? GLP_FX : GLP_DB); | |
386 xassert(lb + 1.0 <= new_lb); | |
387 up_type = GLP_LO; | |
388 break; | |
389 case GLP_UP: | |
390 xassert(new_ub <= ub - 1.0); | |
391 dn_type = GLP_UP; | |
392 xassert(new_lb <= ub); | |
393 up_type = (new_lb == ub ? GLP_FX : GLP_DB); | |
394 break; | |
395 case GLP_DB: | |
396 xassert(lb <= new_ub && new_ub <= ub - 1.0); | |
397 dn_type = (lb == new_ub ? GLP_FX : GLP_DB); | |
398 xassert(lb + 1.0 <= new_lb && new_lb <= ub); | |
399 up_type = (new_lb == ub ? GLP_FX : GLP_DB); | |
400 break; | |
401 default: | |
402 xassert(type != type); | |
403 } | |
404 /* compute local bounds to LP relaxation for both branches */ | |
405 ios_eval_degrad(T, j, &dn_lp, &up_lp); | |
406 /* and improve them by rounding */ | |
407 dn_bnd = ios_round_bound(T, dn_lp); | |
408 up_bnd = ios_round_bound(T, up_lp); | |
409 /* check local bounds for down- and up-branches */ | |
410 dn_bad = !ios_is_hopeful(T, dn_bnd); | |
411 up_bad = !ios_is_hopeful(T, up_bnd); | |
412 if (dn_bad && up_bad) | |
413 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
414 xprintf("Both down- and up-branches are hopeless\n"); | |
415 ret = 2; | |
416 goto done; | |
417 } | |
418 else if (up_bad) | |
419 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
420 xprintf("Up-branch is hopeless\n"); | |
421 glp_set_col_bnds(mip, j, dn_type, lb, new_ub); | |
422 T->curr->lp_obj = dn_lp; | |
423 if (mip->dir == GLP_MIN) | |
424 { if (T->curr->bound < dn_bnd) | |
425 T->curr->bound = dn_bnd; | |
426 } | |
427 else if (mip->dir == GLP_MAX) | |
428 { if (T->curr->bound > dn_bnd) | |
429 T->curr->bound = dn_bnd; | |
430 } | |
431 else | |
432 xassert(mip != mip); | |
433 ret = 1; | |
434 goto done; | |
435 } | |
436 else if (dn_bad) | |
437 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
438 xprintf("Down-branch is hopeless\n"); | |
439 glp_set_col_bnds(mip, j, up_type, new_lb, ub); | |
440 T->curr->lp_obj = up_lp; | |
441 if (mip->dir == GLP_MIN) | |
442 { if (T->curr->bound < up_bnd) | |
443 T->curr->bound = up_bnd; | |
444 } | |
445 else if (mip->dir == GLP_MAX) | |
446 { if (T->curr->bound > up_bnd) | |
447 T->curr->bound = up_bnd; | |
448 } | |
449 else | |
450 xassert(mip != mip); | |
451 ret = 1; | |
452 goto done; | |
453 } | |
454 /* both down- and up-branches seem to be hopeful */ | |
455 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
456 xprintf("Branching on column %d, primal value is %.9e\n", | |
457 j, beta); | |
458 /* determine the reference number of the current subproblem */ | |
459 xassert(T->curr != NULL); | |
460 p = T->curr->p; | |
461 T->curr->br_var = j; | |
462 T->curr->br_val = beta; | |
463 /* freeze the current subproblem */ | |
464 ios_freeze_node(T); | |
465 /* create two clones of the current subproblem; the first clone | |
466 begins the down-branch, the second one begins the up-branch */ | |
467 ios_clone_node(T, p, 2, clone); | |
468 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
469 xprintf("Node %d begins down branch, node %d begins up branch " | |
470 "\n", clone[1], clone[2]); | |
471 /* set new upper bound of j-th column in the down-branch */ | |
472 node = T->slot[clone[1]].node; | |
473 xassert(node != NULL); | |
474 xassert(node->up != NULL); | |
475 xassert(node->b_ptr == NULL); | |
476 node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); | |
477 node->b_ptr->k = m + j; | |
478 node->b_ptr->type = (unsigned char)dn_type; | |
479 node->b_ptr->lb = lb; | |
480 node->b_ptr->ub = new_ub; | |
481 node->b_ptr->next = NULL; | |
482 node->lp_obj = dn_lp; | |
483 if (mip->dir == GLP_MIN) | |
484 { if (node->bound < dn_bnd) | |
485 node->bound = dn_bnd; | |
486 } | |
487 else if (mip->dir == GLP_MAX) | |
488 { if (node->bound > dn_bnd) | |
489 node->bound = dn_bnd; | |
490 } | |
491 else | |
492 xassert(mip != mip); | |
493 /* set new lower bound of j-th column in the up-branch */ | |
494 node = T->slot[clone[2]].node; | |
495 xassert(node != NULL); | |
496 xassert(node->up != NULL); | |
497 xassert(node->b_ptr == NULL); | |
498 node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); | |
499 node->b_ptr->k = m + j; | |
500 node->b_ptr->type = (unsigned char)up_type; | |
501 node->b_ptr->lb = new_lb; | |
502 node->b_ptr->ub = ub; | |
503 node->b_ptr->next = NULL; | |
504 node->lp_obj = up_lp; | |
505 if (mip->dir == GLP_MIN) | |
506 { if (node->bound < up_bnd) | |
507 node->bound = up_bnd; | |
508 } | |
509 else if (mip->dir == GLP_MAX) | |
510 { if (node->bound > up_bnd) | |
511 node->bound = up_bnd; | |
512 } | |
513 else | |
514 xassert(mip != mip); | |
515 /* suggest the subproblem to be solved next */ | |
516 xassert(T->child == 0); | |
517 if (next == GLP_NO_BRNCH) | |
518 T->child = 0; | |
519 else if (next == GLP_DN_BRNCH) | |
520 T->child = clone[1]; | |
521 else if (next == GLP_UP_BRNCH) | |
522 T->child = clone[2]; | |
523 else | |
524 xassert(next != next); | |
525 ret = 0; | |
526 done: return ret; | |
527 } | |
528 | |
529 /*********************************************************************** | |
530 * cleanup_the_tree - prune hopeless branches from the tree | |
531 * | |
532 * This routine walks through the active list and checks the local | |
533 * bound for every active subproblem. If the local bound indicates that | |
534 * the subproblem cannot have integer optimal solution better than the | |
535 * incumbent objective value, the routine deletes such subproblem that, | |
536 * in turn, involves pruning the corresponding branch of the tree. */ | |
537 | |
538 static void cleanup_the_tree(glp_tree *T) | |
539 { IOSNPD *node, *next_node; | |
540 int count = 0; | |
541 /* the global bound must exist */ | |
542 xassert(T->mip->mip_stat == GLP_FEAS); | |
543 /* walk through the list of active subproblems */ | |
544 for (node = T->head; node != NULL; node = next_node) | |
545 { /* deleting some active problem node may involve deleting its | |
546 parents recursively; however, all its parents being created | |
547 *before* it are always *precede* it in the node list, so | |
548 the next problem node is never affected by such deletion */ | |
549 next_node = node->next; | |
550 /* if the branch is hopeless, prune it */ | |
551 if (!is_branch_hopeful(T, node->p)) | |
552 ios_delete_node(T, node->p), count++; | |
553 } | |
554 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
555 { if (count == 1) | |
556 xprintf("One hopeless branch has been pruned\n"); | |
557 else if (count > 1) | |
558 xprintf("%d hopeless branches have been pruned\n", count); | |
559 } | |
560 return; | |
561 } | |
562 | |
563 /**********************************************************************/ | |
564 | |
565 static void generate_cuts(glp_tree *T) | |
566 { /* generate generic cuts with built-in generators */ | |
567 if (!(T->parm->mir_cuts == GLP_ON || | |
568 T->parm->gmi_cuts == GLP_ON || | |
569 T->parm->cov_cuts == GLP_ON || | |
570 T->parm->clq_cuts == GLP_ON)) goto done; | |
571 #if 1 /* 20/IX-2008 */ | |
572 { int i, max_cuts, added_cuts; | |
573 max_cuts = T->n; | |
574 if (max_cuts < 1000) max_cuts = 1000; | |
575 added_cuts = 0; | |
576 for (i = T->orig_m+1; i <= T->mip->m; i++) | |
577 { if (T->mip->row[i]->origin == GLP_RF_CUT) | |
578 added_cuts++; | |
579 } | |
580 /* xprintf("added_cuts = %d\n", added_cuts); */ | |
581 if (added_cuts >= max_cuts) goto done; | |
582 } | |
583 #endif | |
584 /* generate and add to POOL all cuts violated by x* */ | |
585 if (T->parm->gmi_cuts == GLP_ON) | |
586 { if (T->curr->changed < 5) | |
587 ios_gmi_gen(T); | |
588 } | |
589 if (T->parm->mir_cuts == GLP_ON) | |
590 { xassert(T->mir_gen != NULL); | |
591 ios_mir_gen(T, T->mir_gen); | |
592 } | |
593 if (T->parm->cov_cuts == GLP_ON) | |
594 { /* cover cuts works well along with mir cuts */ | |
595 /*if (T->round <= 5)*/ | |
596 ios_cov_gen(T); | |
597 } | |
598 if (T->parm->clq_cuts == GLP_ON) | |
599 { if (T->clq_gen != NULL) | |
600 { if (T->curr->level == 0 && T->curr->changed < 50 || | |
601 T->curr->level > 0 && T->curr->changed < 5) | |
602 ios_clq_gen(T, T->clq_gen); | |
603 } | |
604 } | |
605 done: return; | |
606 } | |
607 | |
608 /**********************************************************************/ | |
609 | |
610 static void remove_cuts(glp_tree *T) | |
611 { /* remove inactive cuts (some valueable globally valid cut might | |
612 be saved in the global cut pool) */ | |
613 int i, cnt = 0, *num = NULL; | |
614 xassert(T->curr != NULL); | |
615 for (i = T->orig_m+1; i <= T->mip->m; i++) | |
616 { if (T->mip->row[i]->origin == GLP_RF_CUT && | |
617 T->mip->row[i]->level == T->curr->level && | |
618 T->mip->row[i]->stat == GLP_BS) | |
619 { if (num == NULL) | |
620 num = xcalloc(1+T->mip->m, sizeof(int)); | |
621 num[++cnt] = i; | |
622 } | |
623 } | |
624 if (cnt > 0) | |
625 { glp_del_rows(T->mip, cnt, num); | |
626 #if 0 | |
627 xprintf("%d inactive cut(s) removed\n", cnt); | |
628 #endif | |
629 xfree(num); | |
630 xassert(glp_factorize(T->mip) == 0); | |
631 } | |
632 return; | |
633 } | |
634 | |
635 /**********************************************************************/ | |
636 | |
637 static void display_cut_info(glp_tree *T) | |
638 { glp_prob *mip = T->mip; | |
639 int i, gmi = 0, mir = 0, cov = 0, clq = 0, app = 0; | |
640 for (i = mip->m; i > 0; i--) | |
641 { GLPROW *row; | |
642 row = mip->row[i]; | |
643 /* if (row->level < T->curr->level) break; */ | |
644 if (row->origin == GLP_RF_CUT) | |
645 { if (row->klass == GLP_RF_GMI) | |
646 gmi++; | |
647 else if (row->klass == GLP_RF_MIR) | |
648 mir++; | |
649 else if (row->klass == GLP_RF_COV) | |
650 cov++; | |
651 else if (row->klass == GLP_RF_CLQ) | |
652 clq++; | |
653 else | |
654 app++; | |
655 } | |
656 } | |
657 xassert(T->curr != NULL); | |
658 if (gmi + mir + cov + clq + app > 0) | |
659 { xprintf("Cuts on level %d:", T->curr->level); | |
660 if (gmi > 0) xprintf(" gmi = %d;", gmi); | |
661 if (mir > 0) xprintf(" mir = %d;", mir); | |
662 if (cov > 0) xprintf(" cov = %d;", cov); | |
663 if (clq > 0) xprintf(" clq = %d;", clq); | |
664 if (app > 0) xprintf(" app = %d;", app); | |
665 xprintf("\n"); | |
666 } | |
667 return; | |
668 } | |
669 | |
670 /*********************************************************************** | |
671 * NAME | |
672 * | |
673 * ios_driver - branch-and-cut driver | |
674 * | |
675 * SYNOPSIS | |
676 * | |
677 * #include "glpios.h" | |
678 * int ios_driver(glp_tree *T); | |
679 * | |
680 * DESCRIPTION | |
681 * | |
682 * The routine ios_driver is a branch-and-cut driver. It controls the | |
683 * MIP solution process. | |
684 * | |
685 * RETURNS | |
686 * | |
687 * 0 The MIP problem instance has been successfully solved. This code | |
688 * does not necessarily mean that the solver has found optimal | |
689 * solution. It only means that the solution process was successful. | |
690 * | |
691 * GLP_EFAIL | |
692 * The search was prematurely terminated due to the solver failure. | |
693 * | |
694 * GLP_EMIPGAP | |
695 * The search was prematurely terminated, because the relative mip | |
696 * gap tolerance has been reached. | |
697 * | |
698 * GLP_ETMLIM | |
699 * The search was prematurely terminated, because the time limit has | |
700 * been exceeded. | |
701 * | |
702 * GLP_ESTOP | |
703 * The search was prematurely terminated by application. */ | |
704 | |
705 int ios_driver(glp_tree *T) | |
706 { int p, curr_p, p_stat, d_stat, ret; | |
707 #if 1 /* carry out to glp_tree */ | |
708 int pred_p = 0; | |
709 /* if the current subproblem has been just created due to | |
710 branching, pred_p is the reference number of its parent | |
711 subproblem, otherwise pred_p is zero */ | |
712 #endif | |
713 glp_long ttt = T->tm_beg; | |
714 #if 0 | |
715 ((glp_iocp *)T->parm)->msg_lev = GLP_MSG_DBG; | |
716 #endif | |
717 /* on entry to the B&B driver it is assumed that the active list | |
718 contains the only active (i.e. root) subproblem, which is the | |
719 original MIP problem to be solved */ | |
720 loop: /* main loop starts here */ | |
721 /* at this point the current subproblem does not exist */ | |
722 xassert(T->curr == NULL); | |
723 /* if the active list is empty, the search is finished */ | |
724 if (T->head == NULL) | |
725 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
726 xprintf("Active list is empty!\n"); | |
727 xassert(dmp_in_use(T->pool).lo == 0); | |
728 ret = 0; | |
729 goto done; | |
730 } | |
731 /* select some active subproblem to continue the search */ | |
732 xassert(T->next_p == 0); | |
733 /* let the application program select subproblem */ | |
734 if (T->parm->cb_func != NULL) | |
735 { xassert(T->reason == 0); | |
736 T->reason = GLP_ISELECT; | |
737 T->parm->cb_func(T, T->parm->cb_info); | |
738 T->reason = 0; | |
739 if (T->stop) | |
740 { ret = GLP_ESTOP; | |
741 goto done; | |
742 } | |
743 } | |
744 if (T->next_p != 0) | |
745 { /* the application program has selected something */ | |
746 ; | |
747 } | |
748 else if (T->a_cnt == 1) | |
749 { /* the only active subproblem exists, so select it */ | |
750 xassert(T->head->next == NULL); | |
751 T->next_p = T->head->p; | |
752 } | |
753 else if (T->child != 0) | |
754 { /* select one of branching childs suggested by the branching | |
755 heuristic */ | |
756 T->next_p = T->child; | |
757 } | |
758 else | |
759 { /* select active subproblem as specified by the backtracking | |
760 technique option */ | |
761 T->next_p = ios_choose_node(T); | |
762 } | |
763 /* the active subproblem just selected becomes current */ | |
764 ios_revive_node(T, T->next_p); | |
765 T->next_p = T->child = 0; | |
766 /* invalidate pred_p, if it is not the reference number of the | |
767 parent of the current subproblem */ | |
768 if (T->curr->up != NULL && T->curr->up->p != pred_p) pred_p = 0; | |
769 /* determine the reference number of the current subproblem */ | |
770 p = T->curr->p; | |
771 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
772 { xprintf("-----------------------------------------------------" | |
773 "-------------------\n"); | |
774 xprintf("Processing node %d at level %d\n", p, T->curr->level); | |
775 } | |
776 /* if it is the root subproblem, initialize cut generators */ | |
777 if (p == 1) | |
778 { if (T->parm->gmi_cuts == GLP_ON) | |
779 { if (T->parm->msg_lev >= GLP_MSG_ALL) | |
780 xprintf("Gomory's cuts enabled\n"); | |
781 } | |
782 if (T->parm->mir_cuts == GLP_ON) | |
783 { if (T->parm->msg_lev >= GLP_MSG_ALL) | |
784 xprintf("MIR cuts enabled\n"); | |
785 xassert(T->mir_gen == NULL); | |
786 T->mir_gen = ios_mir_init(T); | |
787 } | |
788 if (T->parm->cov_cuts == GLP_ON) | |
789 { if (T->parm->msg_lev >= GLP_MSG_ALL) | |
790 xprintf("Cover cuts enabled\n"); | |
791 } | |
792 if (T->parm->clq_cuts == GLP_ON) | |
793 { xassert(T->clq_gen == NULL); | |
794 if (T->parm->msg_lev >= GLP_MSG_ALL) | |
795 xprintf("Clique cuts enabled\n"); | |
796 T->clq_gen = ios_clq_init(T); | |
797 } | |
798 } | |
799 more: /* minor loop starts here */ | |
800 /* at this point the current subproblem needs either to be solved | |
801 for the first time or re-optimized due to reformulation */ | |
802 /* display current progress of the search */ | |
803 if (T->parm->msg_lev >= GLP_MSG_DBG || | |
804 T->parm->msg_lev >= GLP_MSG_ON && | |
805 (double)(T->parm->out_frq - 1) <= | |
806 1000.0 * xdifftime(xtime(), T->tm_lag)) | |
807 show_progress(T, 0); | |
808 if (T->parm->msg_lev >= GLP_MSG_ALL && | |
809 xdifftime(xtime(), ttt) >= 60.0) | |
810 { glp_long total; | |
811 glp_mem_usage(NULL, NULL, &total, NULL); | |
812 xprintf("Time used: %.1f secs. Memory used: %.1f Mb.\n", | |
813 xdifftime(xtime(), T->tm_beg), xltod(total) / 1048576.0); | |
814 ttt = xtime(); | |
815 } | |
816 /* check the mip gap */ | |
817 if (T->parm->mip_gap > 0.0 && | |
818 ios_relative_gap(T) <= T->parm->mip_gap) | |
819 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
820 xprintf("Relative gap tolerance reached; search terminated " | |
821 "\n"); | |
822 ret = GLP_EMIPGAP; | |
823 goto done; | |
824 } | |
825 /* check if the time limit has been exhausted */ | |
826 if (T->parm->tm_lim < INT_MAX && | |
827 (double)(T->parm->tm_lim - 1) <= | |
828 1000.0 * xdifftime(xtime(), T->tm_beg)) | |
829 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
830 xprintf("Time limit exhausted; search terminated\n"); | |
831 ret = GLP_ETMLIM; | |
832 goto done; | |
833 } | |
834 /* let the application program preprocess the subproblem */ | |
835 if (T->parm->cb_func != NULL) | |
836 { xassert(T->reason == 0); | |
837 T->reason = GLP_IPREPRO; | |
838 T->parm->cb_func(T, T->parm->cb_info); | |
839 T->reason = 0; | |
840 if (T->stop) | |
841 { ret = GLP_ESTOP; | |
842 goto done; | |
843 } | |
844 } | |
845 /* perform basic preprocessing */ | |
846 if (T->parm->pp_tech == GLP_PP_NONE) | |
847 ; | |
848 else if (T->parm->pp_tech == GLP_PP_ROOT) | |
849 { if (T->curr->level == 0) | |
850 { if (ios_preprocess_node(T, 100)) | |
851 goto fath; | |
852 } | |
853 } | |
854 else if (T->parm->pp_tech == GLP_PP_ALL) | |
855 { if (ios_preprocess_node(T, T->curr->level == 0 ? 100 : 10)) | |
856 goto fath; | |
857 } | |
858 else | |
859 xassert(T != T); | |
860 /* preprocessing may improve the global bound */ | |
861 if (!is_branch_hopeful(T, p)) | |
862 { xprintf("*** not tested yet ***\n"); | |
863 goto fath; | |
864 } | |
865 /* solve LP relaxation of the current subproblem */ | |
866 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
867 xprintf("Solving LP relaxation...\n"); | |
868 ret = ios_solve_node(T); | |
869 if (!(ret == 0 || ret == GLP_EOBJLL || ret == GLP_EOBJUL)) | |
870 { if (T->parm->msg_lev >= GLP_MSG_ERR) | |
871 xprintf("ios_driver: unable to solve current LP relaxation;" | |
872 " glp_simplex returned %d\n", ret); | |
873 ret = GLP_EFAIL; | |
874 goto done; | |
875 } | |
876 /* analyze status of the basic solution to LP relaxation found */ | |
877 p_stat = T->mip->pbs_stat; | |
878 d_stat = T->mip->dbs_stat; | |
879 if (p_stat == GLP_FEAS && d_stat == GLP_FEAS) | |
880 { /* LP relaxation has optimal solution */ | |
881 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
882 xprintf("Found optimal solution to LP relaxation\n"); | |
883 } | |
884 else if (d_stat == GLP_NOFEAS) | |
885 { /* LP relaxation has no dual feasible solution */ | |
886 /* since the current subproblem cannot have a larger feasible | |
887 region than its parent, there is something wrong */ | |
888 if (T->parm->msg_lev >= GLP_MSG_ERR) | |
889 xprintf("ios_driver: current LP relaxation has no dual feas" | |
890 "ible solution\n"); | |
891 ret = GLP_EFAIL; | |
892 goto done; | |
893 } | |
894 else if (p_stat == GLP_INFEAS && d_stat == GLP_FEAS) | |
895 { /* LP relaxation has no primal solution which is better than | |
896 the incumbent objective value */ | |
897 xassert(T->mip->mip_stat == GLP_FEAS); | |
898 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
899 xprintf("LP relaxation has no solution better than incumben" | |
900 "t objective value\n"); | |
901 /* prune the branch */ | |
902 goto fath; | |
903 } | |
904 else if (p_stat == GLP_NOFEAS) | |
905 { /* LP relaxation has no primal feasible solution */ | |
906 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
907 xprintf("LP relaxation has no feasible solution\n"); | |
908 /* prune the branch */ | |
909 goto fath; | |
910 } | |
911 else | |
912 { /* other cases cannot appear */ | |
913 xassert(T->mip != T->mip); | |
914 } | |
915 /* at this point basic solution to LP relaxation of the current | |
916 subproblem is optimal */ | |
917 xassert(p_stat == GLP_FEAS && d_stat == GLP_FEAS); | |
918 xassert(T->curr != NULL); | |
919 T->curr->lp_obj = T->mip->obj_val; | |
920 /* thus, it defines a local bound to integer optimal solution of | |
921 the current subproblem */ | |
922 { double bound = T->mip->obj_val; | |
923 /* some local bound to the current subproblem could be already | |
924 set before, so we should only improve it */ | |
925 bound = ios_round_bound(T, bound); | |
926 if (T->mip->dir == GLP_MIN) | |
927 { if (T->curr->bound < bound) | |
928 T->curr->bound = bound; | |
929 } | |
930 else if (T->mip->dir == GLP_MAX) | |
931 { if (T->curr->bound > bound) | |
932 T->curr->bound = bound; | |
933 } | |
934 else | |
935 xassert(T->mip != T->mip); | |
936 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
937 xprintf("Local bound is %.9e\n", bound); | |
938 } | |
939 /* if the local bound indicates that integer optimal solution of | |
940 the current subproblem cannot be better than the global bound, | |
941 prune the branch */ | |
942 if (!is_branch_hopeful(T, p)) | |
943 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
944 xprintf("Current branch is hopeless and can be pruned\n"); | |
945 goto fath; | |
946 } | |
947 /* let the application program generate additional rows ("lazy" | |
948 constraints) */ | |
949 xassert(T->reopt == 0); | |
950 xassert(T->reinv == 0); | |
951 if (T->parm->cb_func != NULL) | |
952 { xassert(T->reason == 0); | |
953 T->reason = GLP_IROWGEN; | |
954 T->parm->cb_func(T, T->parm->cb_info); | |
955 T->reason = 0; | |
956 if (T->stop) | |
957 { ret = GLP_ESTOP; | |
958 goto done; | |
959 } | |
960 if (T->reopt) | |
961 { /* some rows were added; re-optimization is needed */ | |
962 T->reopt = T->reinv = 0; | |
963 goto more; | |
964 } | |
965 if (T->reinv) | |
966 { /* no rows were added, however, some inactive rows were | |
967 removed */ | |
968 T->reinv = 0; | |
969 xassert(glp_factorize(T->mip) == 0); | |
970 } | |
971 } | |
972 /* check if the basic solution is integer feasible */ | |
973 check_integrality(T); | |
974 /* if the basic solution satisfies to all integrality conditions, | |
975 it is a new, better integer feasible solution */ | |
976 if (T->curr->ii_cnt == 0) | |
977 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
978 xprintf("New integer feasible solution found\n"); | |
979 if (T->parm->msg_lev >= GLP_MSG_ALL) | |
980 display_cut_info(T); | |
981 record_solution(T); | |
982 if (T->parm->msg_lev >= GLP_MSG_ON) | |
983 show_progress(T, 1); | |
984 /* make the application program happy */ | |
985 if (T->parm->cb_func != NULL) | |
986 { xassert(T->reason == 0); | |
987 T->reason = GLP_IBINGO; | |
988 T->parm->cb_func(T, T->parm->cb_info); | |
989 T->reason = 0; | |
990 if (T->stop) | |
991 { ret = GLP_ESTOP; | |
992 goto done; | |
993 } | |
994 } | |
995 /* since the current subproblem has been fathomed, prune its | |
996 branch */ | |
997 goto fath; | |
998 } | |
999 /* at this point basic solution to LP relaxation of the current | |
1000 subproblem is optimal, but integer infeasible */ | |
1001 /* try to fix some non-basic structural variables of integer kind | |
1002 on their current bounds due to reduced costs */ | |
1003 if (T->mip->mip_stat == GLP_FEAS) | |
1004 fix_by_red_cost(T); | |
1005 /* let the application program try to find some solution to the | |
1006 original MIP with a primal heuristic */ | |
1007 if (T->parm->cb_func != NULL) | |
1008 { xassert(T->reason == 0); | |
1009 T->reason = GLP_IHEUR; | |
1010 T->parm->cb_func(T, T->parm->cb_info); | |
1011 T->reason = 0; | |
1012 if (T->stop) | |
1013 { ret = GLP_ESTOP; | |
1014 goto done; | |
1015 } | |
1016 /* check if the current branch became hopeless */ | |
1017 if (!is_branch_hopeful(T, p)) | |
1018 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
1019 xprintf("Current branch became hopeless and can be prune" | |
1020 "d\n"); | |
1021 goto fath; | |
1022 } | |
1023 } | |
1024 /* try to find solution with the feasibility pump heuristic */ | |
1025 if (T->parm->fp_heur) | |
1026 { xassert(T->reason == 0); | |
1027 T->reason = GLP_IHEUR; | |
1028 ios_feas_pump(T); | |
1029 T->reason = 0; | |
1030 /* check if the current branch became hopeless */ | |
1031 if (!is_branch_hopeful(T, p)) | |
1032 { if (T->parm->msg_lev >= GLP_MSG_DBG) | |
1033 xprintf("Current branch became hopeless and can be prune" | |
1034 "d\n"); | |
1035 goto fath; | |
1036 } | |
1037 } | |
1038 /* it's time to generate cutting planes */ | |
1039 xassert(T->local != NULL); | |
1040 xassert(T->local->size == 0); | |
1041 /* let the application program generate some cuts; note that it | |
1042 can add cuts either to the local cut pool or directly to the | |
1043 current subproblem */ | |
1044 if (T->parm->cb_func != NULL) | |
1045 { xassert(T->reason == 0); | |
1046 T->reason = GLP_ICUTGEN; | |
1047 T->parm->cb_func(T, T->parm->cb_info); | |
1048 T->reason = 0; | |
1049 if (T->stop) | |
1050 { ret = GLP_ESTOP; | |
1051 goto done; | |
1052 } | |
1053 } | |
1054 /* try to generate generic cuts with built-in generators | |
1055 (as suggested by Matteo Fischetti et al. the built-in cuts | |
1056 are not generated at each branching node; an intense attempt | |
1057 of generating new cuts is only made at the root node, and then | |
1058 a moderate effort is spent after each backtracking step) */ | |
1059 if (T->curr->level == 0 || pred_p == 0) | |
1060 { xassert(T->reason == 0); | |
1061 T->reason = GLP_ICUTGEN; | |
1062 generate_cuts(T); | |
1063 T->reason = 0; | |
1064 } | |
1065 /* if the local cut pool is not empty, select useful cuts and add | |
1066 them to the current subproblem */ | |
1067 if (T->local->size > 0) | |
1068 { xassert(T->reason == 0); | |
1069 T->reason = GLP_ICUTGEN; | |
1070 ios_process_cuts(T); | |
1071 T->reason = 0; | |
1072 } | |
1073 /* clear the local cut pool */ | |
1074 ios_clear_pool(T, T->local); | |
1075 /* perform re-optimization, if necessary */ | |
1076 if (T->reopt) | |
1077 { T->reopt = 0; | |
1078 T->curr->changed++; | |
1079 goto more; | |
1080 } | |
1081 /* no cuts were generated; remove inactive cuts */ | |
1082 remove_cuts(T); | |
1083 if (T->parm->msg_lev >= GLP_MSG_ALL && T->curr->level == 0) | |
1084 display_cut_info(T); | |
1085 /* update history information used on pseudocost branching */ | |
1086 if (T->pcost != NULL) ios_pcost_update(T); | |
1087 /* it's time to perform branching */ | |
1088 xassert(T->br_var == 0); | |
1089 xassert(T->br_sel == 0); | |
1090 /* let the application program choose variable to branch on */ | |
1091 if (T->parm->cb_func != NULL) | |
1092 { xassert(T->reason == 0); | |
1093 xassert(T->br_var == 0); | |
1094 xassert(T->br_sel == 0); | |
1095 T->reason = GLP_IBRANCH; | |
1096 T->parm->cb_func(T, T->parm->cb_info); | |
1097 T->reason = 0; | |
1098 if (T->stop) | |
1099 { ret = GLP_ESTOP; | |
1100 goto done; | |
1101 } | |
1102 } | |
1103 /* if nothing has been chosen, choose some variable as specified | |
1104 by the branching technique option */ | |
1105 if (T->br_var == 0) | |
1106 T->br_var = ios_choose_var(T, &T->br_sel); | |
1107 /* perform actual branching */ | |
1108 curr_p = T->curr->p; | |
1109 ret = branch_on(T, T->br_var, T->br_sel); | |
1110 T->br_var = T->br_sel = 0; | |
1111 if (ret == 0) | |
1112 { /* both branches have been created */ | |
1113 pred_p = curr_p; | |
1114 goto loop; | |
1115 } | |
1116 else if (ret == 1) | |
1117 { /* one branch is hopeless and has been pruned, so now the | |
1118 current subproblem is other branch */ | |
1119 /* the current subproblem should be considered as a new one, | |
1120 since one bound of the branching variable was changed */ | |
1121 T->curr->solved = T->curr->changed = 0; | |
1122 goto more; | |
1123 } | |
1124 else if (ret == 2) | |
1125 { /* both branches are hopeless and have been pruned; new | |
1126 subproblem selection is needed to continue the search */ | |
1127 goto fath; | |
1128 } | |
1129 else | |
1130 xassert(ret != ret); | |
1131 fath: /* the current subproblem has been fathomed */ | |
1132 if (T->parm->msg_lev >= GLP_MSG_DBG) | |
1133 xprintf("Node %d fathomed\n", p); | |
1134 /* freeze the current subproblem */ | |
1135 ios_freeze_node(T); | |
1136 /* and prune the corresponding branch of the tree */ | |
1137 ios_delete_node(T, p); | |
1138 /* if a new integer feasible solution has just been found, other | |
1139 branches may become hopeless and therefore must be pruned */ | |
1140 if (T->mip->mip_stat == GLP_FEAS) cleanup_the_tree(T); | |
1141 /* new subproblem selection is needed due to backtracking */ | |
1142 pred_p = 0; | |
1143 goto loop; | |
1144 done: /* display progress of the search on exit from the solver */ | |
1145 if (T->parm->msg_lev >= GLP_MSG_ON) | |
1146 show_progress(T, 0); | |
1147 if (T->mir_gen != NULL) | |
1148 ios_mir_term(T->mir_gen), T->mir_gen = NULL; | |
1149 if (T->clq_gen != NULL) | |
1150 ios_clq_term(T->clq_gen), T->clq_gen = NULL; | |
1151 /* return to the calling program */ | |
1152 return ret; | |
1153 } | |
1154 | |
1155 /* eof */ |