lemon-project-template-glpk

comparison deps/glpk/src/glpapi09.c @ 9:33de93886c88

Import GLPK 4.47
author Alpar Juttner <alpar@cs.elte.hu>
date Sun, 06 Nov 2011 20:59:10 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5efdec4628
1 /* glpapi09.c (mixed integer programming routines) */
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 #include "glpnpp.h"
27
28 /***********************************************************************
29 * NAME
30 *
31 * glp_set_col_kind - set (change) column kind
32 *
33 * SYNOPSIS
34 *
35 * void glp_set_col_kind(glp_prob *mip, int j, int kind);
36 *
37 * DESCRIPTION
38 *
39 * The routine glp_set_col_kind sets (changes) the kind of j-th column
40 * (structural variable) as specified by the parameter kind:
41 *
42 * GLP_CV - continuous variable;
43 * GLP_IV - integer variable;
44 * GLP_BV - binary variable. */
45
46 void glp_set_col_kind(glp_prob *mip, int j, int kind)
47 { GLPCOL *col;
48 if (!(1 <= j && j <= mip->n))
49 xerror("glp_set_col_kind: j = %d; column number out of range\n"
50 , j);
51 col = mip->col[j];
52 switch (kind)
53 { case GLP_CV:
54 col->kind = GLP_CV;
55 break;
56 case GLP_IV:
57 col->kind = GLP_IV;
58 break;
59 case GLP_BV:
60 col->kind = GLP_IV;
61 if (!(col->type == GLP_DB && col->lb == 0.0 && col->ub ==
62 1.0)) glp_set_col_bnds(mip, j, GLP_DB, 0.0, 1.0);
63 break;
64 default:
65 xerror("glp_set_col_kind: j = %d; kind = %d; invalid column"
66 " kind\n", j, kind);
67 }
68 return;
69 }
70
71 /***********************************************************************
72 * NAME
73 *
74 * glp_get_col_kind - retrieve column kind
75 *
76 * SYNOPSIS
77 *
78 * int glp_get_col_kind(glp_prob *mip, int j);
79 *
80 * RETURNS
81 *
82 * The routine glp_get_col_kind returns the kind of j-th column, i.e.
83 * the kind of corresponding structural variable, as follows:
84 *
85 * GLP_CV - continuous variable;
86 * GLP_IV - integer variable;
87 * GLP_BV - binary variable */
88
89 int glp_get_col_kind(glp_prob *mip, int j)
90 { GLPCOL *col;
91 int kind;
92 if (!(1 <= j && j <= mip->n))
93 xerror("glp_get_col_kind: j = %d; column number out of range\n"
94 , j);
95 col = mip->col[j];
96 kind = col->kind;
97 switch (kind)
98 { case GLP_CV:
99 break;
100 case GLP_IV:
101 if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0)
102 kind = GLP_BV;
103 break;
104 default:
105 xassert(kind != kind);
106 }
107 return kind;
108 }
109
110 /***********************************************************************
111 * NAME
112 *
113 * glp_get_num_int - retrieve number of integer columns
114 *
115 * SYNOPSIS
116 *
117 * int glp_get_num_int(glp_prob *mip);
118 *
119 * RETURNS
120 *
121 * The routine glp_get_num_int returns the current number of columns,
122 * which are marked as integer. */
123
124 int glp_get_num_int(glp_prob *mip)
125 { GLPCOL *col;
126 int j, count = 0;
127 for (j = 1; j <= mip->n; j++)
128 { col = mip->col[j];
129 if (col->kind == GLP_IV) count++;
130 }
131 return count;
132 }
133
134 /***********************************************************************
135 * NAME
136 *
137 * glp_get_num_bin - retrieve number of binary columns
138 *
139 * SYNOPSIS
140 *
141 * int glp_get_num_bin(glp_prob *mip);
142 *
143 * RETURNS
144 *
145 * The routine glp_get_num_bin returns the current number of columns,
146 * which are marked as binary. */
147
148 int glp_get_num_bin(glp_prob *mip)
149 { GLPCOL *col;
150 int j, count = 0;
151 for (j = 1; j <= mip->n; j++)
152 { col = mip->col[j];
153 if (col->kind == GLP_IV && col->type == GLP_DB && col->lb ==
154 0.0 && col->ub == 1.0) count++;
155 }
156 return count;
157 }
158
159 /***********************************************************************
160 * NAME
161 *
162 * glp_intopt - solve MIP problem with the branch-and-bound method
163 *
164 * SYNOPSIS
165 *
166 * int glp_intopt(glp_prob *P, const glp_iocp *parm);
167 *
168 * DESCRIPTION
169 *
170 * The routine glp_intopt is a driver to the MIP solver based on the
171 * branch-and-bound method.
172 *
173 * On entry the problem object should contain optimal solution to LP
174 * relaxation (which can be obtained with the routine glp_simplex).
175 *
176 * The MIP solver has a set of control parameters. Values of the control
177 * parameters can be passed in a structure glp_iocp, which the parameter
178 * parm points to.
179 *
180 * The parameter parm can be specified as NULL, in which case the MIP
181 * solver uses default settings.
182 *
183 * RETURNS
184 *
185 * 0 The MIP problem instance has been successfully solved. This code
186 * does not necessarily mean that the solver has found optimal
187 * solution. It only means that the solution process was successful.
188 *
189 * GLP_EBOUND
190 * Unable to start the search, because some double-bounded variables
191 * have incorrect bounds or some integer variables have non-integer
192 * (fractional) bounds.
193 *
194 * GLP_EROOT
195 * Unable to start the search, because optimal basis for initial LP
196 * relaxation is not provided.
197 *
198 * GLP_EFAIL
199 * The search was prematurely terminated due to the solver failure.
200 *
201 * GLP_EMIPGAP
202 * The search was prematurely terminated, because the relative mip
203 * gap tolerance has been reached.
204 *
205 * GLP_ETMLIM
206 * The search was prematurely terminated, because the time limit has
207 * been exceeded.
208 *
209 * GLP_ENOPFS
210 * The MIP problem instance has no primal feasible solution (only if
211 * the MIP presolver is used).
212 *
213 * GLP_ENODFS
214 * LP relaxation of the MIP problem instance has no dual feasible
215 * solution (only if the MIP presolver is used).
216 *
217 * GLP_ESTOP
218 * The search was prematurely terminated by application. */
219
220 static int solve_mip(glp_prob *P, const glp_iocp *parm)
221 { /* solve MIP directly without using the preprocessor */
222 glp_tree *T;
223 int ret;
224 /* optimal basis to LP relaxation must be provided */
225 if (glp_get_status(P) != GLP_OPT)
226 { if (parm->msg_lev >= GLP_MSG_ERR)
227 xprintf("glp_intopt: optimal basis to initial LP relaxation"
228 " not provided\n");
229 ret = GLP_EROOT;
230 goto done;
231 }
232 /* it seems all is ok */
233 if (parm->msg_lev >= GLP_MSG_ALL)
234 xprintf("Integer optimization begins...\n");
235 /* create the branch-and-bound tree */
236 T = ios_create_tree(P, parm);
237 /* solve the problem instance */
238 ret = ios_driver(T);
239 /* delete the branch-and-bound tree */
240 ios_delete_tree(T);
241 /* analyze exit code reported by the mip driver */
242 if (ret == 0)
243 { if (P->mip_stat == GLP_FEAS)
244 { if (parm->msg_lev >= GLP_MSG_ALL)
245 xprintf("INTEGER OPTIMAL SOLUTION FOUND\n");
246 P->mip_stat = GLP_OPT;
247 }
248 else
249 { if (parm->msg_lev >= GLP_MSG_ALL)
250 xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n");
251 P->mip_stat = GLP_NOFEAS;
252 }
253 }
254 else if (ret == GLP_EMIPGAP)
255 { if (parm->msg_lev >= GLP_MSG_ALL)
256 xprintf("RELATIVE MIP GAP TOLERANCE REACHED; SEARCH TERMINA"
257 "TED\n");
258 }
259 else if (ret == GLP_ETMLIM)
260 { if (parm->msg_lev >= GLP_MSG_ALL)
261 xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n");
262 }
263 else if (ret == GLP_EFAIL)
264 { if (parm->msg_lev >= GLP_MSG_ERR)
265 xprintf("glp_intopt: cannot solve current LP relaxation\n");
266 }
267 else if (ret == GLP_ESTOP)
268 { if (parm->msg_lev >= GLP_MSG_ALL)
269 xprintf("SEARCH TERMINATED BY APPLICATION\n");
270 }
271 else
272 xassert(ret != ret);
273 done: return ret;
274 }
275
276 static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm)
277 { /* solve MIP using the preprocessor */
278 ENV *env = get_env_ptr();
279 int term_out = env->term_out;
280 NPP *npp;
281 glp_prob *mip = NULL;
282 glp_bfcp bfcp;
283 glp_smcp smcp;
284 int ret;
285 if (parm->msg_lev >= GLP_MSG_ALL)
286 xprintf("Preprocessing...\n");
287 /* create preprocessor workspace */
288 npp = npp_create_wksp();
289 /* load original problem into the preprocessor workspace */
290 npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF);
291 /* process MIP prior to applying the branch-and-bound method */
292 if (!term_out || parm->msg_lev < GLP_MSG_ALL)
293 env->term_out = GLP_OFF;
294 else
295 env->term_out = GLP_ON;
296 ret = npp_integer(npp, parm);
297 env->term_out = term_out;
298 if (ret == 0)
299 ;
300 else if (ret == GLP_ENOPFS)
301 { if (parm->msg_lev >= GLP_MSG_ALL)
302 xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n");
303 }
304 else if (ret == GLP_ENODFS)
305 { if (parm->msg_lev >= GLP_MSG_ALL)
306 xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n");
307 }
308 else
309 xassert(ret != ret);
310 if (ret != 0) goto done;
311 /* build transformed MIP */
312 mip = glp_create_prob();
313 npp_build_prob(npp, mip);
314 /* if the transformed MIP is empty, it has empty solution, which
315 is optimal */
316 if (mip->m == 0 && mip->n == 0)
317 { mip->mip_stat = GLP_OPT;
318 mip->mip_obj = mip->c0;
319 if (parm->msg_lev >= GLP_MSG_ALL)
320 { xprintf("Objective value = %17.9e\n", mip->mip_obj);
321 xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR"
322 "\n");
323 }
324 goto post;
325 }
326 /* display some statistics */
327 if (parm->msg_lev >= GLP_MSG_ALL)
328 { int ni = glp_get_num_int(mip);
329 int nb = glp_get_num_bin(mip);
330 char s[50];
331 xprintf("%d row%s, %d column%s, %d non-zero%s\n",
332 mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" :
333 "s", mip->nnz, mip->nnz == 1 ? "" : "s");
334 if (nb == 0)
335 strcpy(s, "none of");
336 else if (ni == 1 && nb == 1)
337 strcpy(s, "");
338 else if (nb == 1)
339 strcpy(s, "one of");
340 else if (nb == ni)
341 strcpy(s, "all of");
342 else
343 sprintf(s, "%d of", nb);
344 xprintf("%d integer variable%s, %s which %s binary\n",
345 ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are");
346 }
347 /* inherit basis factorization control parameters */
348 glp_get_bfcp(P, &bfcp);
349 glp_set_bfcp(mip, &bfcp);
350 /* scale the transformed problem */
351 if (!term_out || parm->msg_lev < GLP_MSG_ALL)
352 env->term_out = GLP_OFF;
353 else
354 env->term_out = GLP_ON;
355 glp_scale_prob(mip,
356 GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP);
357 env->term_out = term_out;
358 /* build advanced initial basis */
359 if (!term_out || parm->msg_lev < GLP_MSG_ALL)
360 env->term_out = GLP_OFF;
361 else
362 env->term_out = GLP_ON;
363 glp_adv_basis(mip, 0);
364 env->term_out = term_out;
365 /* solve initial LP relaxation */
366 if (parm->msg_lev >= GLP_MSG_ALL)
367 xprintf("Solving LP relaxation...\n");
368 glp_init_smcp(&smcp);
369 smcp.msg_lev = parm->msg_lev;
370 mip->it_cnt = P->it_cnt;
371 ret = glp_simplex(mip, &smcp);
372 P->it_cnt = mip->it_cnt;
373 if (ret != 0)
374 { if (parm->msg_lev >= GLP_MSG_ERR)
375 xprintf("glp_intopt: cannot solve LP relaxation\n");
376 ret = GLP_EFAIL;
377 goto done;
378 }
379 /* check status of the basic solution */
380 ret = glp_get_status(mip);
381 if (ret == GLP_OPT)
382 ret = 0;
383 else if (ret == GLP_NOFEAS)
384 ret = GLP_ENOPFS;
385 else if (ret == GLP_UNBND)
386 ret = GLP_ENODFS;
387 else
388 xassert(ret != ret);
389 if (ret != 0) goto done;
390 /* solve the transformed MIP */
391 mip->it_cnt = P->it_cnt;
392 ret = solve_mip(mip, parm);
393 P->it_cnt = mip->it_cnt;
394 /* only integer feasible solution can be postprocessed */
395 if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS))
396 { P->mip_stat = mip->mip_stat;
397 goto done;
398 }
399 /* postprocess solution from the transformed MIP */
400 post: npp_postprocess(npp, mip);
401 /* the transformed MIP is no longer needed */
402 glp_delete_prob(mip), mip = NULL;
403 /* store solution to the original problem */
404 npp_unload_sol(npp, P);
405 done: /* delete the transformed MIP, if it exists */
406 if (mip != NULL) glp_delete_prob(mip);
407 /* delete preprocessor workspace */
408 npp_delete_wksp(npp);
409 return ret;
410 }
411
412 #ifndef HAVE_ALIEN_SOLVER /* 28/V-2010 */
413 int _glp_intopt1(glp_prob *P, const glp_iocp *parm)
414 { xassert(P == P);
415 xassert(parm == parm);
416 xprintf("glp_intopt: no alien solver is available\n");
417 return GLP_EFAIL;
418 }
419 #endif
420
421 int glp_intopt(glp_prob *P, const glp_iocp *parm)
422 { /* solve MIP problem with the branch-and-bound method */
423 glp_iocp _parm;
424 int i, j, ret;
425 /* check problem object */
426 if (P == NULL || P->magic != GLP_PROB_MAGIC)
427 xerror("glp_intopt: P = %p; invalid problem object\n", P);
428 if (P->tree != NULL)
429 xerror("glp_intopt: operation not allowed\n");
430 /* check control parameters */
431 if (parm == NULL)
432 parm = &_parm, glp_init_iocp((glp_iocp *)parm);
433 if (!(parm->msg_lev == GLP_MSG_OFF ||
434 parm->msg_lev == GLP_MSG_ERR ||
435 parm->msg_lev == GLP_MSG_ON ||
436 parm->msg_lev == GLP_MSG_ALL ||
437 parm->msg_lev == GLP_MSG_DBG))
438 xerror("glp_intopt: msg_lev = %d; invalid parameter\n",
439 parm->msg_lev);
440 if (!(parm->br_tech == GLP_BR_FFV ||
441 parm->br_tech == GLP_BR_LFV ||
442 parm->br_tech == GLP_BR_MFV ||
443 parm->br_tech == GLP_BR_DTH ||
444 parm->br_tech == GLP_BR_PCH))
445 xerror("glp_intopt: br_tech = %d; invalid parameter\n",
446 parm->br_tech);
447 if (!(parm->bt_tech == GLP_BT_DFS ||
448 parm->bt_tech == GLP_BT_BFS ||
449 parm->bt_tech == GLP_BT_BLB ||
450 parm->bt_tech == GLP_BT_BPH))
451 xerror("glp_intopt: bt_tech = %d; invalid parameter\n",
452 parm->bt_tech);
453 if (!(0.0 < parm->tol_int && parm->tol_int < 1.0))
454 xerror("glp_intopt: tol_int = %g; invalid parameter\n",
455 parm->tol_int);
456 if (!(0.0 < parm->tol_obj && parm->tol_obj < 1.0))
457 xerror("glp_intopt: tol_obj = %g; invalid parameter\n",
458 parm->tol_obj);
459 if (parm->tm_lim < 0)
460 xerror("glp_intopt: tm_lim = %d; invalid parameter\n",
461 parm->tm_lim);
462 if (parm->out_frq < 0)
463 xerror("glp_intopt: out_frq = %d; invalid parameter\n",
464 parm->out_frq);
465 if (parm->out_dly < 0)
466 xerror("glp_intopt: out_dly = %d; invalid parameter\n",
467 parm->out_dly);
468 if (!(0 <= parm->cb_size && parm->cb_size <= 256))
469 xerror("glp_intopt: cb_size = %d; invalid parameter\n",
470 parm->cb_size);
471 if (!(parm->pp_tech == GLP_PP_NONE ||
472 parm->pp_tech == GLP_PP_ROOT ||
473 parm->pp_tech == GLP_PP_ALL))
474 xerror("glp_intopt: pp_tech = %d; invalid parameter\n",
475 parm->pp_tech);
476 if (parm->mip_gap < 0.0)
477 xerror("glp_intopt: mip_gap = %g; invalid parameter\n",
478 parm->mip_gap);
479 if (!(parm->mir_cuts == GLP_ON || parm->mir_cuts == GLP_OFF))
480 xerror("glp_intopt: mir_cuts = %d; invalid parameter\n",
481 parm->mir_cuts);
482 if (!(parm->gmi_cuts == GLP_ON || parm->gmi_cuts == GLP_OFF))
483 xerror("glp_intopt: gmi_cuts = %d; invalid parameter\n",
484 parm->gmi_cuts);
485 if (!(parm->cov_cuts == GLP_ON || parm->cov_cuts == GLP_OFF))
486 xerror("glp_intopt: cov_cuts = %d; invalid parameter\n",
487 parm->cov_cuts);
488 if (!(parm->clq_cuts == GLP_ON || parm->clq_cuts == GLP_OFF))
489 xerror("glp_intopt: clq_cuts = %d; invalid parameter\n",
490 parm->clq_cuts);
491 if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF))
492 xerror("glp_intopt: presolve = %d; invalid parameter\n",
493 parm->presolve);
494 if (!(parm->binarize == GLP_ON || parm->binarize == GLP_OFF))
495 xerror("glp_intopt: binarize = %d; invalid parameter\n",
496 parm->binarize);
497 if (!(parm->fp_heur == GLP_ON || parm->fp_heur == GLP_OFF))
498 xerror("glp_intopt: fp_heur = %d; invalid parameter\n",
499 parm->fp_heur);
500 #if 1 /* 28/V-2010 */
501 if (!(parm->alien == GLP_ON || parm->alien == GLP_OFF))
502 xerror("glp_intopt: alien = %d; invalid parameter\n",
503 parm->alien);
504 #endif
505 /* integer solution is currently undefined */
506 P->mip_stat = GLP_UNDEF;
507 P->mip_obj = 0.0;
508 /* check bounds of double-bounded variables */
509 for (i = 1; i <= P->m; i++)
510 { GLPROW *row = P->row[i];
511 if (row->type == GLP_DB && row->lb >= row->ub)
512 { if (parm->msg_lev >= GLP_MSG_ERR)
513 xprintf("glp_intopt: row %d: lb = %g, ub = %g; incorrect"
514 " bounds\n", i, row->lb, row->ub);
515 ret = GLP_EBOUND;
516 goto done;
517 }
518 }
519 for (j = 1; j <= P->n; j++)
520 { GLPCOL *col = P->col[j];
521 if (col->type == GLP_DB && col->lb >= col->ub)
522 { if (parm->msg_lev >= GLP_MSG_ERR)
523 xprintf("glp_intopt: column %d: lb = %g, ub = %g; incorr"
524 "ect bounds\n", j, col->lb, col->ub);
525 ret = GLP_EBOUND;
526 goto done;
527 }
528 }
529 /* bounds of all integer variables must be integral */
530 for (j = 1; j <= P->n; j++)
531 { GLPCOL *col = P->col[j];
532 if (col->kind != GLP_IV) continue;
533 if (col->type == GLP_LO || col->type == GLP_DB)
534 { if (col->lb != floor(col->lb))
535 { if (parm->msg_lev >= GLP_MSG_ERR)
536 xprintf("glp_intopt: integer column %d has non-intege"
537 "r lower bound %g\n", j, col->lb);
538 ret = GLP_EBOUND;
539 goto done;
540 }
541 }
542 if (col->type == GLP_UP || col->type == GLP_DB)
543 { if (col->ub != floor(col->ub))
544 { if (parm->msg_lev >= GLP_MSG_ERR)
545 xprintf("glp_intopt: integer column %d has non-intege"
546 "r upper bound %g\n", j, col->ub);
547 ret = GLP_EBOUND;
548 goto done;
549 }
550 }
551 if (col->type == GLP_FX)
552 { if (col->lb != floor(col->lb))
553 { if (parm->msg_lev >= GLP_MSG_ERR)
554 xprintf("glp_intopt: integer column %d has non-intege"
555 "r fixed value %g\n", j, col->lb);
556 ret = GLP_EBOUND;
557 goto done;
558 }
559 }
560 }
561 /* solve MIP problem */
562 if (parm->msg_lev >= GLP_MSG_ALL)
563 { int ni = glp_get_num_int(P);
564 int nb = glp_get_num_bin(P);
565 char s[50];
566 xprintf("GLPK Integer Optimizer, v%s\n", glp_version());
567 xprintf("%d row%s, %d column%s, %d non-zero%s\n",
568 P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s",
569 P->nnz, P->nnz == 1 ? "" : "s");
570 if (nb == 0)
571 strcpy(s, "none of");
572 else if (ni == 1 && nb == 1)
573 strcpy(s, "");
574 else if (nb == 1)
575 strcpy(s, "one of");
576 else if (nb == ni)
577 strcpy(s, "all of");
578 else
579 sprintf(s, "%d of", nb);
580 xprintf("%d integer variable%s, %s which %s binary\n",
581 ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are");
582 }
583 #if 1 /* 28/V-2010 */
584 if (parm->alien)
585 { /* use alien integer optimizer */
586 ret = _glp_intopt1(P, parm);
587 goto done;
588 }
589 #endif
590 if (!parm->presolve)
591 ret = solve_mip(P, parm);
592 else
593 ret = preprocess_and_solve_mip(P, parm);
594 done: /* return to the application program */
595 return ret;
596 }
597
598 /***********************************************************************
599 * NAME
600 *
601 * glp_init_iocp - initialize integer optimizer control parameters
602 *
603 * SYNOPSIS
604 *
605 * void glp_init_iocp(glp_iocp *parm);
606 *
607 * DESCRIPTION
608 *
609 * The routine glp_init_iocp initializes control parameters, which are
610 * used by the integer optimizer, with default values.
611 *
612 * Default values of the control parameters are stored in a glp_iocp
613 * structure, which the parameter parm points to. */
614
615 void glp_init_iocp(glp_iocp *parm)
616 { parm->msg_lev = GLP_MSG_ALL;
617 parm->br_tech = GLP_BR_DTH;
618 parm->bt_tech = GLP_BT_BLB;
619 parm->tol_int = 1e-5;
620 parm->tol_obj = 1e-7;
621 parm->tm_lim = INT_MAX;
622 parm->out_frq = 5000;
623 parm->out_dly = 10000;
624 parm->cb_func = NULL;
625 parm->cb_info = NULL;
626 parm->cb_size = 0;
627 parm->pp_tech = GLP_PP_ALL;
628 parm->mip_gap = 0.0;
629 parm->mir_cuts = GLP_OFF;
630 parm->gmi_cuts = GLP_OFF;
631 parm->cov_cuts = GLP_OFF;
632 parm->clq_cuts = GLP_OFF;
633 parm->presolve = GLP_OFF;
634 parm->binarize = GLP_OFF;
635 parm->fp_heur = GLP_OFF;
636 #if 1 /* 28/V-2010 */
637 parm->alien = GLP_OFF;
638 #endif
639 return;
640 }
641
642 /***********************************************************************
643 * NAME
644 *
645 * glp_mip_status - retrieve status of MIP solution
646 *
647 * SYNOPSIS
648 *
649 * int glp_mip_status(glp_prob *mip);
650 *
651 * RETURNS
652 *
653 * The routine lpx_mip_status reports the status of MIP solution found
654 * by the branch-and-bound solver as follows:
655 *
656 * GLP_UNDEF - MIP solution is undefined;
657 * GLP_OPT - MIP solution is integer optimal;
658 * GLP_FEAS - MIP solution is integer feasible but its optimality
659 * (or non-optimality) has not been proven, perhaps due to
660 * premature termination of the search;
661 * GLP_NOFEAS - problem has no integer feasible solution (proven by the
662 * solver). */
663
664 int glp_mip_status(glp_prob *mip)
665 { int mip_stat = mip->mip_stat;
666 return mip_stat;
667 }
668
669 /***********************************************************************
670 * NAME
671 *
672 * glp_mip_obj_val - retrieve objective value (MIP solution)
673 *
674 * SYNOPSIS
675 *
676 * double glp_mip_obj_val(glp_prob *mip);
677 *
678 * RETURNS
679 *
680 * The routine glp_mip_obj_val returns value of the objective function
681 * for MIP solution. */
682
683 double glp_mip_obj_val(glp_prob *mip)
684 { /*struct LPXCPS *cps = mip->cps;*/
685 double z;
686 z = mip->mip_obj;
687 /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/
688 return z;
689 }
690
691 /***********************************************************************
692 * NAME
693 *
694 * glp_mip_row_val - retrieve row value (MIP solution)
695 *
696 * SYNOPSIS
697 *
698 * double glp_mip_row_val(glp_prob *mip, int i);
699 *
700 * RETURNS
701 *
702 * The routine glp_mip_row_val returns value of the auxiliary variable
703 * associated with i-th row. */
704
705 double glp_mip_row_val(glp_prob *mip, int i)
706 { /*struct LPXCPS *cps = mip->cps;*/
707 double mipx;
708 if (!(1 <= i && i <= mip->m))
709 xerror("glp_mip_row_val: i = %d; row number out of range\n", i)
710 ;
711 mipx = mip->row[i]->mipx;
712 /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/
713 return mipx;
714 }
715
716 /***********************************************************************
717 * NAME
718 *
719 * glp_mip_col_val - retrieve column value (MIP solution)
720 *
721 * SYNOPSIS
722 *
723 * double glp_mip_col_val(glp_prob *mip, int j);
724 *
725 * RETURNS
726 *
727 * The routine glp_mip_col_val returns value of the structural variable
728 * associated with j-th column. */
729
730 double glp_mip_col_val(glp_prob *mip, int j)
731 { /*struct LPXCPS *cps = mip->cps;*/
732 double mipx;
733 if (!(1 <= j && j <= mip->n))
734 xerror("glp_mip_col_val: j = %d; column number out of range\n",
735 j);
736 mipx = mip->col[j]->mipx;
737 /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/
738 return mipx;
739 }
740
741 /* eof */