COIN-OR::LEMON - Graph Library

source: lemon-project-template-glpk/deps/glpk/src/glpapi09.c @ 10:5545663ca997

subpack-glpk
Last change on this file since 10:5545663ca997 was 9:33de93886c88, checked in by Alpar Juttner <alpar@…>, 13 years ago

Import GLPK 4.47

File size: 23.9 KB
Line 
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
46void 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
89int 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
124int 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
148int 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
220static 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);
273done: return ret;
274}
275
276static 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 */
400post: 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);
405done: /* 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 */
413int _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
421int 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);
594done: /* 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
615void 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
664int 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
683double 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
705double 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
730double 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 */
Note: See TracBrowser for help on using the repository browser.