lemon-project-template-glpk
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/deps/glpk/src/glpapi09.c Sun Nov 06 20:59:10 2011 +0100 1.3 @@ -0,0 +1,741 @@ 1.4 +/* glpapi09.c (mixed integer programming routines) */ 1.5 + 1.6 +/*********************************************************************** 1.7 +* This code is part of GLPK (GNU Linear Programming Kit). 1.8 +* 1.9 +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 1.10 +* 2009, 2010, 2011 Andrew Makhorin, Department for Applied Informatics, 1.11 +* Moscow Aviation Institute, Moscow, Russia. All rights reserved. 1.12 +* E-mail: <mao@gnu.org>. 1.13 +* 1.14 +* GLPK is free software: you can redistribute it and/or modify it 1.15 +* under the terms of the GNU General Public License as published by 1.16 +* the Free Software Foundation, either version 3 of the License, or 1.17 +* (at your option) any later version. 1.18 +* 1.19 +* GLPK is distributed in the hope that it will be useful, but WITHOUT 1.20 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1.21 +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 1.22 +* License for more details. 1.23 +* 1.24 +* You should have received a copy of the GNU General Public License 1.25 +* along with GLPK. If not, see <http://www.gnu.org/licenses/>. 1.26 +***********************************************************************/ 1.27 + 1.28 +#include "glpios.h" 1.29 +#include "glpnpp.h" 1.30 + 1.31 +/*********************************************************************** 1.32 +* NAME 1.33 +* 1.34 +* glp_set_col_kind - set (change) column kind 1.35 +* 1.36 +* SYNOPSIS 1.37 +* 1.38 +* void glp_set_col_kind(glp_prob *mip, int j, int kind); 1.39 +* 1.40 +* DESCRIPTION 1.41 +* 1.42 +* The routine glp_set_col_kind sets (changes) the kind of j-th column 1.43 +* (structural variable) as specified by the parameter kind: 1.44 +* 1.45 +* GLP_CV - continuous variable; 1.46 +* GLP_IV - integer variable; 1.47 +* GLP_BV - binary variable. */ 1.48 + 1.49 +void glp_set_col_kind(glp_prob *mip, int j, int kind) 1.50 +{ GLPCOL *col; 1.51 + if (!(1 <= j && j <= mip->n)) 1.52 + xerror("glp_set_col_kind: j = %d; column number out of range\n" 1.53 + , j); 1.54 + col = mip->col[j]; 1.55 + switch (kind) 1.56 + { case GLP_CV: 1.57 + col->kind = GLP_CV; 1.58 + break; 1.59 + case GLP_IV: 1.60 + col->kind = GLP_IV; 1.61 + break; 1.62 + case GLP_BV: 1.63 + col->kind = GLP_IV; 1.64 + if (!(col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.65 + 1.0)) glp_set_col_bnds(mip, j, GLP_DB, 0.0, 1.0); 1.66 + break; 1.67 + default: 1.68 + xerror("glp_set_col_kind: j = %d; kind = %d; invalid column" 1.69 + " kind\n", j, kind); 1.70 + } 1.71 + return; 1.72 +} 1.73 + 1.74 +/*********************************************************************** 1.75 +* NAME 1.76 +* 1.77 +* glp_get_col_kind - retrieve column kind 1.78 +* 1.79 +* SYNOPSIS 1.80 +* 1.81 +* int glp_get_col_kind(glp_prob *mip, int j); 1.82 +* 1.83 +* RETURNS 1.84 +* 1.85 +* The routine glp_get_col_kind returns the kind of j-th column, i.e. 1.86 +* the kind of corresponding structural variable, as follows: 1.87 +* 1.88 +* GLP_CV - continuous variable; 1.89 +* GLP_IV - integer variable; 1.90 +* GLP_BV - binary variable */ 1.91 + 1.92 +int glp_get_col_kind(glp_prob *mip, int j) 1.93 +{ GLPCOL *col; 1.94 + int kind; 1.95 + if (!(1 <= j && j <= mip->n)) 1.96 + xerror("glp_get_col_kind: j = %d; column number out of range\n" 1.97 + , j); 1.98 + col = mip->col[j]; 1.99 + kind = col->kind; 1.100 + switch (kind) 1.101 + { case GLP_CV: 1.102 + break; 1.103 + case GLP_IV: 1.104 + if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) 1.105 + kind = GLP_BV; 1.106 + break; 1.107 + default: 1.108 + xassert(kind != kind); 1.109 + } 1.110 + return kind; 1.111 +} 1.112 + 1.113 +/*********************************************************************** 1.114 +* NAME 1.115 +* 1.116 +* glp_get_num_int - retrieve number of integer columns 1.117 +* 1.118 +* SYNOPSIS 1.119 +* 1.120 +* int glp_get_num_int(glp_prob *mip); 1.121 +* 1.122 +* RETURNS 1.123 +* 1.124 +* The routine glp_get_num_int returns the current number of columns, 1.125 +* which are marked as integer. */ 1.126 + 1.127 +int glp_get_num_int(glp_prob *mip) 1.128 +{ GLPCOL *col; 1.129 + int j, count = 0; 1.130 + for (j = 1; j <= mip->n; j++) 1.131 + { col = mip->col[j]; 1.132 + if (col->kind == GLP_IV) count++; 1.133 + } 1.134 + return count; 1.135 +} 1.136 + 1.137 +/*********************************************************************** 1.138 +* NAME 1.139 +* 1.140 +* glp_get_num_bin - retrieve number of binary columns 1.141 +* 1.142 +* SYNOPSIS 1.143 +* 1.144 +* int glp_get_num_bin(glp_prob *mip); 1.145 +* 1.146 +* RETURNS 1.147 +* 1.148 +* The routine glp_get_num_bin returns the current number of columns, 1.149 +* which are marked as binary. */ 1.150 + 1.151 +int glp_get_num_bin(glp_prob *mip) 1.152 +{ GLPCOL *col; 1.153 + int j, count = 0; 1.154 + for (j = 1; j <= mip->n; j++) 1.155 + { col = mip->col[j]; 1.156 + if (col->kind == GLP_IV && col->type == GLP_DB && col->lb == 1.157 + 0.0 && col->ub == 1.0) count++; 1.158 + } 1.159 + return count; 1.160 +} 1.161 + 1.162 +/*********************************************************************** 1.163 +* NAME 1.164 +* 1.165 +* glp_intopt - solve MIP problem with the branch-and-bound method 1.166 +* 1.167 +* SYNOPSIS 1.168 +* 1.169 +* int glp_intopt(glp_prob *P, const glp_iocp *parm); 1.170 +* 1.171 +* DESCRIPTION 1.172 +* 1.173 +* The routine glp_intopt is a driver to the MIP solver based on the 1.174 +* branch-and-bound method. 1.175 +* 1.176 +* On entry the problem object should contain optimal solution to LP 1.177 +* relaxation (which can be obtained with the routine glp_simplex). 1.178 +* 1.179 +* The MIP solver has a set of control parameters. Values of the control 1.180 +* parameters can be passed in a structure glp_iocp, which the parameter 1.181 +* parm points to. 1.182 +* 1.183 +* The parameter parm can be specified as NULL, in which case the MIP 1.184 +* solver uses default settings. 1.185 +* 1.186 +* RETURNS 1.187 +* 1.188 +* 0 The MIP problem instance has been successfully solved. This code 1.189 +* does not necessarily mean that the solver has found optimal 1.190 +* solution. It only means that the solution process was successful. 1.191 +* 1.192 +* GLP_EBOUND 1.193 +* Unable to start the search, because some double-bounded variables 1.194 +* have incorrect bounds or some integer variables have non-integer 1.195 +* (fractional) bounds. 1.196 +* 1.197 +* GLP_EROOT 1.198 +* Unable to start the search, because optimal basis for initial LP 1.199 +* relaxation is not provided. 1.200 +* 1.201 +* GLP_EFAIL 1.202 +* The search was prematurely terminated due to the solver failure. 1.203 +* 1.204 +* GLP_EMIPGAP 1.205 +* The search was prematurely terminated, because the relative mip 1.206 +* gap tolerance has been reached. 1.207 +* 1.208 +* GLP_ETMLIM 1.209 +* The search was prematurely terminated, because the time limit has 1.210 +* been exceeded. 1.211 +* 1.212 +* GLP_ENOPFS 1.213 +* The MIP problem instance has no primal feasible solution (only if 1.214 +* the MIP presolver is used). 1.215 +* 1.216 +* GLP_ENODFS 1.217 +* LP relaxation of the MIP problem instance has no dual feasible 1.218 +* solution (only if the MIP presolver is used). 1.219 +* 1.220 +* GLP_ESTOP 1.221 +* The search was prematurely terminated by application. */ 1.222 + 1.223 +static int solve_mip(glp_prob *P, const glp_iocp *parm) 1.224 +{ /* solve MIP directly without using the preprocessor */ 1.225 + glp_tree *T; 1.226 + int ret; 1.227 + /* optimal basis to LP relaxation must be provided */ 1.228 + if (glp_get_status(P) != GLP_OPT) 1.229 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.230 + xprintf("glp_intopt: optimal basis to initial LP relaxation" 1.231 + " not provided\n"); 1.232 + ret = GLP_EROOT; 1.233 + goto done; 1.234 + } 1.235 + /* it seems all is ok */ 1.236 + if (parm->msg_lev >= GLP_MSG_ALL) 1.237 + xprintf("Integer optimization begins...\n"); 1.238 + /* create the branch-and-bound tree */ 1.239 + T = ios_create_tree(P, parm); 1.240 + /* solve the problem instance */ 1.241 + ret = ios_driver(T); 1.242 + /* delete the branch-and-bound tree */ 1.243 + ios_delete_tree(T); 1.244 + /* analyze exit code reported by the mip driver */ 1.245 + if (ret == 0) 1.246 + { if (P->mip_stat == GLP_FEAS) 1.247 + { if (parm->msg_lev >= GLP_MSG_ALL) 1.248 + xprintf("INTEGER OPTIMAL SOLUTION FOUND\n"); 1.249 + P->mip_stat = GLP_OPT; 1.250 + } 1.251 + else 1.252 + { if (parm->msg_lev >= GLP_MSG_ALL) 1.253 + xprintf("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION\n"); 1.254 + P->mip_stat = GLP_NOFEAS; 1.255 + } 1.256 + } 1.257 + else if (ret == GLP_EMIPGAP) 1.258 + { if (parm->msg_lev >= GLP_MSG_ALL) 1.259 + xprintf("RELATIVE MIP GAP TOLERANCE REACHED; SEARCH TERMINA" 1.260 + "TED\n"); 1.261 + } 1.262 + else if (ret == GLP_ETMLIM) 1.263 + { if (parm->msg_lev >= GLP_MSG_ALL) 1.264 + xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); 1.265 + } 1.266 + else if (ret == GLP_EFAIL) 1.267 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.268 + xprintf("glp_intopt: cannot solve current LP relaxation\n"); 1.269 + } 1.270 + else if (ret == GLP_ESTOP) 1.271 + { if (parm->msg_lev >= GLP_MSG_ALL) 1.272 + xprintf("SEARCH TERMINATED BY APPLICATION\n"); 1.273 + } 1.274 + else 1.275 + xassert(ret != ret); 1.276 +done: return ret; 1.277 +} 1.278 + 1.279 +static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm) 1.280 +{ /* solve MIP using the preprocessor */ 1.281 + ENV *env = get_env_ptr(); 1.282 + int term_out = env->term_out; 1.283 + NPP *npp; 1.284 + glp_prob *mip = NULL; 1.285 + glp_bfcp bfcp; 1.286 + glp_smcp smcp; 1.287 + int ret; 1.288 + if (parm->msg_lev >= GLP_MSG_ALL) 1.289 + xprintf("Preprocessing...\n"); 1.290 + /* create preprocessor workspace */ 1.291 + npp = npp_create_wksp(); 1.292 + /* load original problem into the preprocessor workspace */ 1.293 + npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); 1.294 + /* process MIP prior to applying the branch-and-bound method */ 1.295 + if (!term_out || parm->msg_lev < GLP_MSG_ALL) 1.296 + env->term_out = GLP_OFF; 1.297 + else 1.298 + env->term_out = GLP_ON; 1.299 + ret = npp_integer(npp, parm); 1.300 + env->term_out = term_out; 1.301 + if (ret == 0) 1.302 + ; 1.303 + else if (ret == GLP_ENOPFS) 1.304 + { if (parm->msg_lev >= GLP_MSG_ALL) 1.305 + xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); 1.306 + } 1.307 + else if (ret == GLP_ENODFS) 1.308 + { if (parm->msg_lev >= GLP_MSG_ALL) 1.309 + xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n"); 1.310 + } 1.311 + else 1.312 + xassert(ret != ret); 1.313 + if (ret != 0) goto done; 1.314 + /* build transformed MIP */ 1.315 + mip = glp_create_prob(); 1.316 + npp_build_prob(npp, mip); 1.317 + /* if the transformed MIP is empty, it has empty solution, which 1.318 + is optimal */ 1.319 + if (mip->m == 0 && mip->n == 0) 1.320 + { mip->mip_stat = GLP_OPT; 1.321 + mip->mip_obj = mip->c0; 1.322 + if (parm->msg_lev >= GLP_MSG_ALL) 1.323 + { xprintf("Objective value = %17.9e\n", mip->mip_obj); 1.324 + xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR" 1.325 + "\n"); 1.326 + } 1.327 + goto post; 1.328 + } 1.329 + /* display some statistics */ 1.330 + if (parm->msg_lev >= GLP_MSG_ALL) 1.331 + { int ni = glp_get_num_int(mip); 1.332 + int nb = glp_get_num_bin(mip); 1.333 + char s[50]; 1.334 + xprintf("%d row%s, %d column%s, %d non-zero%s\n", 1.335 + mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" : 1.336 + "s", mip->nnz, mip->nnz == 1 ? "" : "s"); 1.337 + if (nb == 0) 1.338 + strcpy(s, "none of"); 1.339 + else if (ni == 1 && nb == 1) 1.340 + strcpy(s, ""); 1.341 + else if (nb == 1) 1.342 + strcpy(s, "one of"); 1.343 + else if (nb == ni) 1.344 + strcpy(s, "all of"); 1.345 + else 1.346 + sprintf(s, "%d of", nb); 1.347 + xprintf("%d integer variable%s, %s which %s binary\n", 1.348 + ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); 1.349 + } 1.350 + /* inherit basis factorization control parameters */ 1.351 + glp_get_bfcp(P, &bfcp); 1.352 + glp_set_bfcp(mip, &bfcp); 1.353 + /* scale the transformed problem */ 1.354 + if (!term_out || parm->msg_lev < GLP_MSG_ALL) 1.355 + env->term_out = GLP_OFF; 1.356 + else 1.357 + env->term_out = GLP_ON; 1.358 + glp_scale_prob(mip, 1.359 + GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP); 1.360 + env->term_out = term_out; 1.361 + /* build advanced initial basis */ 1.362 + if (!term_out || parm->msg_lev < GLP_MSG_ALL) 1.363 + env->term_out = GLP_OFF; 1.364 + else 1.365 + env->term_out = GLP_ON; 1.366 + glp_adv_basis(mip, 0); 1.367 + env->term_out = term_out; 1.368 + /* solve initial LP relaxation */ 1.369 + if (parm->msg_lev >= GLP_MSG_ALL) 1.370 + xprintf("Solving LP relaxation...\n"); 1.371 + glp_init_smcp(&smcp); 1.372 + smcp.msg_lev = parm->msg_lev; 1.373 + mip->it_cnt = P->it_cnt; 1.374 + ret = glp_simplex(mip, &smcp); 1.375 + P->it_cnt = mip->it_cnt; 1.376 + if (ret != 0) 1.377 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.378 + xprintf("glp_intopt: cannot solve LP relaxation\n"); 1.379 + ret = GLP_EFAIL; 1.380 + goto done; 1.381 + } 1.382 + /* check status of the basic solution */ 1.383 + ret = glp_get_status(mip); 1.384 + if (ret == GLP_OPT) 1.385 + ret = 0; 1.386 + else if (ret == GLP_NOFEAS) 1.387 + ret = GLP_ENOPFS; 1.388 + else if (ret == GLP_UNBND) 1.389 + ret = GLP_ENODFS; 1.390 + else 1.391 + xassert(ret != ret); 1.392 + if (ret != 0) goto done; 1.393 + /* solve the transformed MIP */ 1.394 + mip->it_cnt = P->it_cnt; 1.395 + ret = solve_mip(mip, parm); 1.396 + P->it_cnt = mip->it_cnt; 1.397 + /* only integer feasible solution can be postprocessed */ 1.398 + if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) 1.399 + { P->mip_stat = mip->mip_stat; 1.400 + goto done; 1.401 + } 1.402 + /* postprocess solution from the transformed MIP */ 1.403 +post: npp_postprocess(npp, mip); 1.404 + /* the transformed MIP is no longer needed */ 1.405 + glp_delete_prob(mip), mip = NULL; 1.406 + /* store solution to the original problem */ 1.407 + npp_unload_sol(npp, P); 1.408 +done: /* delete the transformed MIP, if it exists */ 1.409 + if (mip != NULL) glp_delete_prob(mip); 1.410 + /* delete preprocessor workspace */ 1.411 + npp_delete_wksp(npp); 1.412 + return ret; 1.413 +} 1.414 + 1.415 +#ifndef HAVE_ALIEN_SOLVER /* 28/V-2010 */ 1.416 +int _glp_intopt1(glp_prob *P, const glp_iocp *parm) 1.417 +{ xassert(P == P); 1.418 + xassert(parm == parm); 1.419 + xprintf("glp_intopt: no alien solver is available\n"); 1.420 + return GLP_EFAIL; 1.421 +} 1.422 +#endif 1.423 + 1.424 +int glp_intopt(glp_prob *P, const glp_iocp *parm) 1.425 +{ /* solve MIP problem with the branch-and-bound method */ 1.426 + glp_iocp _parm; 1.427 + int i, j, ret; 1.428 + /* check problem object */ 1.429 + if (P == NULL || P->magic != GLP_PROB_MAGIC) 1.430 + xerror("glp_intopt: P = %p; invalid problem object\n", P); 1.431 + if (P->tree != NULL) 1.432 + xerror("glp_intopt: operation not allowed\n"); 1.433 + /* check control parameters */ 1.434 + if (parm == NULL) 1.435 + parm = &_parm, glp_init_iocp((glp_iocp *)parm); 1.436 + if (!(parm->msg_lev == GLP_MSG_OFF || 1.437 + parm->msg_lev == GLP_MSG_ERR || 1.438 + parm->msg_lev == GLP_MSG_ON || 1.439 + parm->msg_lev == GLP_MSG_ALL || 1.440 + parm->msg_lev == GLP_MSG_DBG)) 1.441 + xerror("glp_intopt: msg_lev = %d; invalid parameter\n", 1.442 + parm->msg_lev); 1.443 + if (!(parm->br_tech == GLP_BR_FFV || 1.444 + parm->br_tech == GLP_BR_LFV || 1.445 + parm->br_tech == GLP_BR_MFV || 1.446 + parm->br_tech == GLP_BR_DTH || 1.447 + parm->br_tech == GLP_BR_PCH)) 1.448 + xerror("glp_intopt: br_tech = %d; invalid parameter\n", 1.449 + parm->br_tech); 1.450 + if (!(parm->bt_tech == GLP_BT_DFS || 1.451 + parm->bt_tech == GLP_BT_BFS || 1.452 + parm->bt_tech == GLP_BT_BLB || 1.453 + parm->bt_tech == GLP_BT_BPH)) 1.454 + xerror("glp_intopt: bt_tech = %d; invalid parameter\n", 1.455 + parm->bt_tech); 1.456 + if (!(0.0 < parm->tol_int && parm->tol_int < 1.0)) 1.457 + xerror("glp_intopt: tol_int = %g; invalid parameter\n", 1.458 + parm->tol_int); 1.459 + if (!(0.0 < parm->tol_obj && parm->tol_obj < 1.0)) 1.460 + xerror("glp_intopt: tol_obj = %g; invalid parameter\n", 1.461 + parm->tol_obj); 1.462 + if (parm->tm_lim < 0) 1.463 + xerror("glp_intopt: tm_lim = %d; invalid parameter\n", 1.464 + parm->tm_lim); 1.465 + if (parm->out_frq < 0) 1.466 + xerror("glp_intopt: out_frq = %d; invalid parameter\n", 1.467 + parm->out_frq); 1.468 + if (parm->out_dly < 0) 1.469 + xerror("glp_intopt: out_dly = %d; invalid parameter\n", 1.470 + parm->out_dly); 1.471 + if (!(0 <= parm->cb_size && parm->cb_size <= 256)) 1.472 + xerror("glp_intopt: cb_size = %d; invalid parameter\n", 1.473 + parm->cb_size); 1.474 + if (!(parm->pp_tech == GLP_PP_NONE || 1.475 + parm->pp_tech == GLP_PP_ROOT || 1.476 + parm->pp_tech == GLP_PP_ALL)) 1.477 + xerror("glp_intopt: pp_tech = %d; invalid parameter\n", 1.478 + parm->pp_tech); 1.479 + if (parm->mip_gap < 0.0) 1.480 + xerror("glp_intopt: mip_gap = %g; invalid parameter\n", 1.481 + parm->mip_gap); 1.482 + if (!(parm->mir_cuts == GLP_ON || parm->mir_cuts == GLP_OFF)) 1.483 + xerror("glp_intopt: mir_cuts = %d; invalid parameter\n", 1.484 + parm->mir_cuts); 1.485 + if (!(parm->gmi_cuts == GLP_ON || parm->gmi_cuts == GLP_OFF)) 1.486 + xerror("glp_intopt: gmi_cuts = %d; invalid parameter\n", 1.487 + parm->gmi_cuts); 1.488 + if (!(parm->cov_cuts == GLP_ON || parm->cov_cuts == GLP_OFF)) 1.489 + xerror("glp_intopt: cov_cuts = %d; invalid parameter\n", 1.490 + parm->cov_cuts); 1.491 + if (!(parm->clq_cuts == GLP_ON || parm->clq_cuts == GLP_OFF)) 1.492 + xerror("glp_intopt: clq_cuts = %d; invalid parameter\n", 1.493 + parm->clq_cuts); 1.494 + if (!(parm->presolve == GLP_ON || parm->presolve == GLP_OFF)) 1.495 + xerror("glp_intopt: presolve = %d; invalid parameter\n", 1.496 + parm->presolve); 1.497 + if (!(parm->binarize == GLP_ON || parm->binarize == GLP_OFF)) 1.498 + xerror("glp_intopt: binarize = %d; invalid parameter\n", 1.499 + parm->binarize); 1.500 + if (!(parm->fp_heur == GLP_ON || parm->fp_heur == GLP_OFF)) 1.501 + xerror("glp_intopt: fp_heur = %d; invalid parameter\n", 1.502 + parm->fp_heur); 1.503 +#if 1 /* 28/V-2010 */ 1.504 + if (!(parm->alien == GLP_ON || parm->alien == GLP_OFF)) 1.505 + xerror("glp_intopt: alien = %d; invalid parameter\n", 1.506 + parm->alien); 1.507 +#endif 1.508 + /* integer solution is currently undefined */ 1.509 + P->mip_stat = GLP_UNDEF; 1.510 + P->mip_obj = 0.0; 1.511 + /* check bounds of double-bounded variables */ 1.512 + for (i = 1; i <= P->m; i++) 1.513 + { GLPROW *row = P->row[i]; 1.514 + if (row->type == GLP_DB && row->lb >= row->ub) 1.515 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.516 + xprintf("glp_intopt: row %d: lb = %g, ub = %g; incorrect" 1.517 + " bounds\n", i, row->lb, row->ub); 1.518 + ret = GLP_EBOUND; 1.519 + goto done; 1.520 + } 1.521 + } 1.522 + for (j = 1; j <= P->n; j++) 1.523 + { GLPCOL *col = P->col[j]; 1.524 + if (col->type == GLP_DB && col->lb >= col->ub) 1.525 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.526 + xprintf("glp_intopt: column %d: lb = %g, ub = %g; incorr" 1.527 + "ect bounds\n", j, col->lb, col->ub); 1.528 + ret = GLP_EBOUND; 1.529 + goto done; 1.530 + } 1.531 + } 1.532 + /* bounds of all integer variables must be integral */ 1.533 + for (j = 1; j <= P->n; j++) 1.534 + { GLPCOL *col = P->col[j]; 1.535 + if (col->kind != GLP_IV) continue; 1.536 + if (col->type == GLP_LO || col->type == GLP_DB) 1.537 + { if (col->lb != floor(col->lb)) 1.538 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.539 + xprintf("glp_intopt: integer column %d has non-intege" 1.540 + "r lower bound %g\n", j, col->lb); 1.541 + ret = GLP_EBOUND; 1.542 + goto done; 1.543 + } 1.544 + } 1.545 + if (col->type == GLP_UP || col->type == GLP_DB) 1.546 + { if (col->ub != floor(col->ub)) 1.547 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.548 + xprintf("glp_intopt: integer column %d has non-intege" 1.549 + "r upper bound %g\n", j, col->ub); 1.550 + ret = GLP_EBOUND; 1.551 + goto done; 1.552 + } 1.553 + } 1.554 + if (col->type == GLP_FX) 1.555 + { if (col->lb != floor(col->lb)) 1.556 + { if (parm->msg_lev >= GLP_MSG_ERR) 1.557 + xprintf("glp_intopt: integer column %d has non-intege" 1.558 + "r fixed value %g\n", j, col->lb); 1.559 + ret = GLP_EBOUND; 1.560 + goto done; 1.561 + } 1.562 + } 1.563 + } 1.564 + /* solve MIP problem */ 1.565 + if (parm->msg_lev >= GLP_MSG_ALL) 1.566 + { int ni = glp_get_num_int(P); 1.567 + int nb = glp_get_num_bin(P); 1.568 + char s[50]; 1.569 + xprintf("GLPK Integer Optimizer, v%s\n", glp_version()); 1.570 + xprintf("%d row%s, %d column%s, %d non-zero%s\n", 1.571 + P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", 1.572 + P->nnz, P->nnz == 1 ? "" : "s"); 1.573 + if (nb == 0) 1.574 + strcpy(s, "none of"); 1.575 + else if (ni == 1 && nb == 1) 1.576 + strcpy(s, ""); 1.577 + else if (nb == 1) 1.578 + strcpy(s, "one of"); 1.579 + else if (nb == ni) 1.580 + strcpy(s, "all of"); 1.581 + else 1.582 + sprintf(s, "%d of", nb); 1.583 + xprintf("%d integer variable%s, %s which %s binary\n", 1.584 + ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); 1.585 + } 1.586 +#if 1 /* 28/V-2010 */ 1.587 + if (parm->alien) 1.588 + { /* use alien integer optimizer */ 1.589 + ret = _glp_intopt1(P, parm); 1.590 + goto done; 1.591 + } 1.592 +#endif 1.593 + if (!parm->presolve) 1.594 + ret = solve_mip(P, parm); 1.595 + else 1.596 + ret = preprocess_and_solve_mip(P, parm); 1.597 +done: /* return to the application program */ 1.598 + return ret; 1.599 +} 1.600 + 1.601 +/*********************************************************************** 1.602 +* NAME 1.603 +* 1.604 +* glp_init_iocp - initialize integer optimizer control parameters 1.605 +* 1.606 +* SYNOPSIS 1.607 +* 1.608 +* void glp_init_iocp(glp_iocp *parm); 1.609 +* 1.610 +* DESCRIPTION 1.611 +* 1.612 +* The routine glp_init_iocp initializes control parameters, which are 1.613 +* used by the integer optimizer, with default values. 1.614 +* 1.615 +* Default values of the control parameters are stored in a glp_iocp 1.616 +* structure, which the parameter parm points to. */ 1.617 + 1.618 +void glp_init_iocp(glp_iocp *parm) 1.619 +{ parm->msg_lev = GLP_MSG_ALL; 1.620 + parm->br_tech = GLP_BR_DTH; 1.621 + parm->bt_tech = GLP_BT_BLB; 1.622 + parm->tol_int = 1e-5; 1.623 + parm->tol_obj = 1e-7; 1.624 + parm->tm_lim = INT_MAX; 1.625 + parm->out_frq = 5000; 1.626 + parm->out_dly = 10000; 1.627 + parm->cb_func = NULL; 1.628 + parm->cb_info = NULL; 1.629 + parm->cb_size = 0; 1.630 + parm->pp_tech = GLP_PP_ALL; 1.631 + parm->mip_gap = 0.0; 1.632 + parm->mir_cuts = GLP_OFF; 1.633 + parm->gmi_cuts = GLP_OFF; 1.634 + parm->cov_cuts = GLP_OFF; 1.635 + parm->clq_cuts = GLP_OFF; 1.636 + parm->presolve = GLP_OFF; 1.637 + parm->binarize = GLP_OFF; 1.638 + parm->fp_heur = GLP_OFF; 1.639 +#if 1 /* 28/V-2010 */ 1.640 + parm->alien = GLP_OFF; 1.641 +#endif 1.642 + return; 1.643 +} 1.644 + 1.645 +/*********************************************************************** 1.646 +* NAME 1.647 +* 1.648 +* glp_mip_status - retrieve status of MIP solution 1.649 +* 1.650 +* SYNOPSIS 1.651 +* 1.652 +* int glp_mip_status(glp_prob *mip); 1.653 +* 1.654 +* RETURNS 1.655 +* 1.656 +* The routine lpx_mip_status reports the status of MIP solution found 1.657 +* by the branch-and-bound solver as follows: 1.658 +* 1.659 +* GLP_UNDEF - MIP solution is undefined; 1.660 +* GLP_OPT - MIP solution is integer optimal; 1.661 +* GLP_FEAS - MIP solution is integer feasible but its optimality 1.662 +* (or non-optimality) has not been proven, perhaps due to 1.663 +* premature termination of the search; 1.664 +* GLP_NOFEAS - problem has no integer feasible solution (proven by the 1.665 +* solver). */ 1.666 + 1.667 +int glp_mip_status(glp_prob *mip) 1.668 +{ int mip_stat = mip->mip_stat; 1.669 + return mip_stat; 1.670 +} 1.671 + 1.672 +/*********************************************************************** 1.673 +* NAME 1.674 +* 1.675 +* glp_mip_obj_val - retrieve objective value (MIP solution) 1.676 +* 1.677 +* SYNOPSIS 1.678 +* 1.679 +* double glp_mip_obj_val(glp_prob *mip); 1.680 +* 1.681 +* RETURNS 1.682 +* 1.683 +* The routine glp_mip_obj_val returns value of the objective function 1.684 +* for MIP solution. */ 1.685 + 1.686 +double glp_mip_obj_val(glp_prob *mip) 1.687 +{ /*struct LPXCPS *cps = mip->cps;*/ 1.688 + double z; 1.689 + z = mip->mip_obj; 1.690 + /*if (cps->round && fabs(z) < 1e-9) z = 0.0;*/ 1.691 + return z; 1.692 +} 1.693 + 1.694 +/*********************************************************************** 1.695 +* NAME 1.696 +* 1.697 +* glp_mip_row_val - retrieve row value (MIP solution) 1.698 +* 1.699 +* SYNOPSIS 1.700 +* 1.701 +* double glp_mip_row_val(glp_prob *mip, int i); 1.702 +* 1.703 +* RETURNS 1.704 +* 1.705 +* The routine glp_mip_row_val returns value of the auxiliary variable 1.706 +* associated with i-th row. */ 1.707 + 1.708 +double glp_mip_row_val(glp_prob *mip, int i) 1.709 +{ /*struct LPXCPS *cps = mip->cps;*/ 1.710 + double mipx; 1.711 + if (!(1 <= i && i <= mip->m)) 1.712 + xerror("glp_mip_row_val: i = %d; row number out of range\n", i) 1.713 + ; 1.714 + mipx = mip->row[i]->mipx; 1.715 + /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/ 1.716 + return mipx; 1.717 +} 1.718 + 1.719 +/*********************************************************************** 1.720 +* NAME 1.721 +* 1.722 +* glp_mip_col_val - retrieve column value (MIP solution) 1.723 +* 1.724 +* SYNOPSIS 1.725 +* 1.726 +* double glp_mip_col_val(glp_prob *mip, int j); 1.727 +* 1.728 +* RETURNS 1.729 +* 1.730 +* The routine glp_mip_col_val returns value of the structural variable 1.731 +* associated with j-th column. */ 1.732 + 1.733 +double glp_mip_col_val(glp_prob *mip, int j) 1.734 +{ /*struct LPXCPS *cps = mip->cps;*/ 1.735 + double mipx; 1.736 + if (!(1 <= j && j <= mip->n)) 1.737 + xerror("glp_mip_col_val: j = %d; column number out of range\n", 1.738 + j); 1.739 + mipx = mip->col[j]->mipx; 1.740 + /*if (cps->round && fabs(mipx) < 1e-9) mipx = 0.0;*/ 1.741 + return mipx; 1.742 +} 1.743 + 1.744 +/* eof */