int lpx_write_pb(LPX *lp, const char *fname, int normalized, int binarize) { FILE* fp; int m,n,i,j,k,o,nonfree=0, obj_dir, dbl, *ndx, row_type, emptylhs=0; double coeff, *val, bound, constant/*=0.0*/; char* objconstname = "dummy_one"; char* emptylhsname = "dummy_zero"; /* Variables needed for possible binarization */ /*LPX* tlp;*/ IPP *ipp = NULL; /*tlp=lp;*/ if(binarize) /* Transform integer variables to binary ones */ { ipp = ipp_create_wksp(); ipp_load_orig(ipp, lp); ipp_binarize(ipp); lp = ipp_build_prob(ipp); } fp = fopen(fname, "w"); if(fp!= NULL) { xprintf( "lpx_write_pb: writing problem in %sOPB format to `%s'...\n", (normalized?"normalized ":""), fname); m = glp_get_num_rows(lp); n = glp_get_num_cols(lp); for(i=1;i<=m;i++) { switch(glp_get_row_type(lp,i)) { case GLP_LO: case GLP_UP: case GLP_FX: { nonfree += 1; break; } case GLP_DB: { nonfree += 2; break; } } } constant=glp_get_obj_coef(lp,0); fprintf(fp,"* #variables = %d #constraints = %d\n", n + (constant == 0?1:0), nonfree + (constant == 0?1:0)); /* Objective function */ obj_dir = glp_get_obj_dir(lp); fprintf(fp,"min: "); for(i=1;i<=n;i++) { coeff = glp_get_obj_coef(lp,i); if(coeff != 0.0) { if(obj_dir == GLP_MAX) coeff=-coeff; if(normalized) fprintf(fp, " %d x%d", (int)coeff, i); else fprintf(fp, " %d*%s", (int)coeff, glp_get_col_name(lp,i)); } } if(constant) { if(normalized) fprintf(fp, " %d x%d", (int)constant, n+1); else fprintf(fp, " %d*%s", (int)constant, objconstname); } fprintf(fp,";\n"); if(normalized && !binarize) /* Name substitution */ { fprintf(fp,"* Variable name substitution:\n"); for(j=1;j<=n;j++) { fprintf(fp, "* x%d = %s\n", j, glp_get_col_name(lp,j)); } if(constant) fprintf(fp, "* x%d = %s\n", n+1, objconstname); } ndx = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); /* Constraints */ for(j=1;j<=m;j++) { row_type=glp_get_row_type(lp,j); if(row_type!=GLP_FR) { if(row_type == GLP_DB) { dbl=2; row_type = GLP_UP; } else { dbl=1; } k=glp_get_mat_row(lp, j, ndx, val); for(o=1;o<=dbl;o++) { if(o==2) { row_type = GLP_LO; } if(k==0) /* Empty LHS */ { emptylhs = 1; if(normalized) { fprintf(fp, "0 x%d ", n+2); } else { fprintf(fp, "0*%s ", emptylhsname); } } for(i=1;i<=k;i++) { if(val[i] != 0.0) { if(normalized) { fprintf(fp, "%d x%d ", (row_type==GLP_UP)?(-(int)val[i]):((int)val[i]), ndx[i]); } else { fprintf(fp, "%d*%s ", (int)val[i], glp_get_col_name(lp,ndx[i])); } } } switch(row_type) { case GLP_LO: { fprintf(fp, ">="); bound = glp_get_row_lb(lp,j); break; } case GLP_UP: { if(normalized) { fprintf(fp, ">="); bound = -glp_get_row_ub(lp,j); } else { fprintf(fp, "<="); bound = glp_get_row_ub(lp,j); } break; } case GLP_FX: { fprintf(fp, "="); bound = glp_get_row_lb(lp,j); break; } } fprintf(fp," %d;\n",(int)bound); } } } xfree(ndx); xfree(val); if(constant) { xprintf( "lpx_write_pb: adding constant objective function variable\n"); if(normalized) fprintf(fp, "1 x%d = 1;\n", n+1); else fprintf(fp, "1*%s = 1;\n", objconstname); } if(emptylhs) { xprintf( "lpx_write_pb: adding dummy variable for empty left-hand si" "de constraint\n"); if(normalized) fprintf(fp, "1 x%d = 0;\n", n+2); else fprintf(fp, "1*%s = 0;\n", emptylhsname); } } else { xprintf("Problems opening file for writing: %s\n", fname); return(1); } fflush(fp); if (ferror(fp)) { xprintf("lpx_write_pb: can't write to `%s' - %s\n", fname, strerror(errno)); goto fail; } fclose(fp); if(binarize) { /* delete the resultant problem object */ if (lp != NULL) lpx_delete_prob(lp); /* delete MIP presolver workspace */ if (ipp != NULL) ipp_delete_wksp(ipp); /*lp=tlp;*/ } return 0; fail: if (fp != NULL) fclose(fp); return 1; }
int lpx_intopt(LPX *_mip) { IPP *ipp = NULL; LPX *orig = _mip, *prob = NULL; int orig_m, orig_n, i, j, ret, i_stat; /* the problem must be of MIP class */ if (lpx_get_class(orig) != LPX_MIP) { print("lpx_intopt: problem is not of MIP class"); ret = LPX_E_FAULT; goto done; } /* the problem must have at least one row and one column */ orig_m = lpx_get_num_rows(orig); orig_n = lpx_get_num_cols(orig); if (!(orig_m > 0 && orig_n > 0)) { print("lpx_intopt: problem has no rows/columns"); ret = LPX_E_FAULT; goto done; } /* check that each double-bounded row and column has bounds */ for (i = 1; i <= orig_m; i++) { if (lpx_get_row_type(orig, i) == LPX_DB) { if (lpx_get_row_lb(orig, i) >= lpx_get_row_ub(orig, i)) { print("lpx_intopt: row %d has incorrect bounds", i); ret = LPX_E_FAULT; goto done; } } } for (j = 1; j <= orig_n; j++) { if (lpx_get_col_type(orig, j) == LPX_DB) { if (lpx_get_col_lb(orig, j) >= lpx_get_col_ub(orig, j)) { print("lpx_intopt: column %d has incorrect bounds", j); ret = LPX_E_FAULT; goto done; } } } /* bounds of all integer variables must be integral */ for (j = 1; j <= orig_n; j++) { int type; double lb, ub; if (lpx_get_col_kind(orig, j) != LPX_IV) continue; type = lpx_get_col_type(orig, j); if (type == LPX_LO || type == LPX_DB || type == LPX_FX) { lb = lpx_get_col_lb(orig, j); if (lb != floor(lb)) { print("lpx_intopt: integer column %d has non-integer low" "er bound or fixed value %g", j, lb); ret = LPX_E_FAULT; goto done; } } if (type == LPX_UP || type == LPX_DB) { ub = lpx_get_col_ub(orig, j); if (ub != floor(ub)) { print("lpx_intopt: integer column %d has non-integer upp" "er bound %g", j, ub); ret = LPX_E_FAULT; goto done; } } } /* reset the status of MIP solution */ lpx_put_mip_soln(orig, LPX_I_UNDEF, NULL, NULL); /* create MIP presolver workspace */ ipp = ipp_create_wksp(); /* load the original problem into the presolver workspace */ ipp_load_orig(ipp, orig); /* perform basic MIP presolve analysis */ switch (ipp_basic_tech(ipp)) { case 0: /* no infeasibility is detected */ break; case 1: nopfs: /* primal infeasibility is detected */ print("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION"); ret = LPX_E_NOPFS; goto done; case 2: /* dual infeasibility is detected */ nodfs: print("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION"); ret = LPX_E_NODFS; goto done; default: insist(ipp != ipp); } /* reduce column bounds */ switch (ipp_reduce_bnds(ipp)) { case 0: break; case 1: goto nopfs; default: insist(ipp != ipp); } /* perform basic MIP presolve analysis */ switch (ipp_basic_tech(ipp)) { case 0: break; case 1: goto nopfs; case 2: goto nodfs; default: insist(ipp != ipp); } /* replace general integer variables by sum of binary variables, if required */ if (lpx_get_int_parm(orig, LPX_K_BINARIZE)) ipp_binarize(ipp); /* perform coefficient reduction */ ipp_reduction(ipp); /* if the resultant problem is empty, it has an empty solution, which is optimal */ if (ipp->row_ptr == NULL || ipp->col_ptr == NULL) { insist(ipp->row_ptr == NULL); insist(ipp->col_ptr == NULL); print("Objective value = %.10g", ipp->orig_dir == LPX_MIN ? +ipp->c0 : -ipp->c0); print("INTEGER OPTIMAL SOLUTION FOUND BY MIP PRESOLVER"); /* allocate recovered solution segment */ ipp->col_stat = ucalloc(1+ipp->ncols, sizeof(int)); ipp->col_mipx = ucalloc(1+ipp->ncols, sizeof(double)); for (j = 1; j <= ipp->ncols; j++) ipp->col_stat[j] = 0; /* perform MIP postsolve processing */ ipp_postsolve(ipp); /* unload recovered MIP solution and store it in the original problem object */ ipp_unload_sol(ipp, orig, LPX_I_OPT); ret = LPX_E_OK; goto done; } /* build resultant MIP problem object */ prob = ipp_build_prob(ipp); /* display some statistics */ { int m = lpx_get_num_rows(prob); int n = lpx_get_num_cols(prob); int nnz = lpx_get_num_nz(prob); int ni = lpx_get_num_int(prob); int nb = lpx_get_num_bin(prob); char s[50]; print("lpx_intopt: presolved MIP has %d row%s, %d column%s, %d" " non-zero%s", m, m == 1 ? "" : "s", n, n == 1 ? "" : "s", nnz, nnz == 1 ? "" : "s"); if (nb == 0) strcpy(s, "none of"); else if (ni == 1 && nb == 1) strcpy(s, ""); else if (nb == 1) strcpy(s, "one of"); else if (nb == ni) strcpy(s, "all of"); else sprintf(s, "%d of", nb); print("lpx_intopt: %d integer column%s, %s which %s binary", ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); } /* inherit some control parameters and statistics */ lpx_set_int_parm(prob, LPX_K_PRICE, lpx_get_int_parm(orig, LPX_K_PRICE)); lpx_set_real_parm(prob, LPX_K_RELAX, lpx_get_real_parm(orig, LPX_K_RELAX)); lpx_set_real_parm(prob, LPX_K_TOLBND, lpx_get_real_parm(orig, LPX_K_TOLBND)); lpx_set_real_parm(prob, LPX_K_TOLDJ, lpx_get_real_parm(orig, LPX_K_TOLDJ)); lpx_set_real_parm(prob, LPX_K_TOLPIV, lpx_get_real_parm(orig, LPX_K_TOLPIV)); lpx_set_int_parm(prob, LPX_K_ITLIM, lpx_get_int_parm(orig, LPX_K_ITLIM)); lpx_set_int_parm(prob, LPX_K_ITCNT, lpx_get_int_parm(orig, LPX_K_ITCNT)); lpx_set_real_parm(prob, LPX_K_TMLIM, lpx_get_real_parm(orig, LPX_K_TMLIM)); lpx_set_int_parm(prob, LPX_K_BRANCH, lpx_get_int_parm(orig, LPX_K_BRANCH)); lpx_set_int_parm(prob, LPX_K_BTRACK, lpx_get_int_parm(orig, LPX_K_BTRACK)); lpx_set_real_parm(prob, LPX_K_TOLINT, lpx_get_real_parm(orig, LPX_K_TOLINT)); lpx_set_real_parm(prob, LPX_K_TOLOBJ, lpx_get_real_parm(orig, LPX_K_TOLOBJ)); /* build an advanced initial basis */ lpx_adv_basis(prob); /* solve LP relaxation */ print("Solving LP relaxation..."); switch (lpx_simplex(prob)) { case LPX_E_OK: break; case LPX_E_ITLIM: ret = LPX_E_ITLIM; goto done; case LPX_E_TMLIM: ret = LPX_E_TMLIM; goto done; default: print("lpx_intopt: cannot solve LP relaxation"); ret = LPX_E_SING; goto done; } /* analyze status of the basic solution */ switch (lpx_get_status(prob)) { case LPX_OPT: break; case LPX_NOFEAS: ret = LPX_E_NOPFS; goto done; case LPX_UNBND: ret = LPX_E_NODFS; goto done; default: insist(prob != prob); } /* generate cutting planes, if necessary */ if (lpx_get_int_parm(orig, LPX_K_USECUTS)) { ret = generate_cuts(prob); if (ret != LPX_E_OK) goto done; } /* call the branch-and-bound solver */ ret = lpx_integer(prob); /* determine status of MIP solution */ i_stat = lpx_mip_status(prob); if (i_stat == LPX_I_OPT || i_stat == LPX_I_FEAS) { /* load MIP solution of the resultant problem into presolver workspace */ ipp_load_sol(ipp, prob); /* perform MIP postsolve processing */ ipp_postsolve(ipp); /* unload recovered MIP solution and store it in the original problem object */ ipp_unload_sol(ipp, orig, i_stat); } else { /* just set the status of MIP solution */ lpx_put_mip_soln(orig, i_stat, NULL, NULL); } done: /* copy back statistics about spent resources */ if (prob != NULL) { lpx_set_int_parm(orig, LPX_K_ITLIM, lpx_get_int_parm(prob, LPX_K_ITLIM)); lpx_set_int_parm(orig, LPX_K_ITCNT, lpx_get_int_parm(prob, LPX_K_ITCNT)); lpx_set_real_parm(orig, LPX_K_TMLIM, lpx_get_real_parm(prob, LPX_K_TMLIM)); } /* delete the resultant problem object */ if (prob != NULL) lpx_delete_prob(prob); /* delete MIP presolver workspace */ if (ipp != NULL) ipp_delete_wksp(ipp); return ret; }