diff -ur glpk-4.28/include/glpk.h /home/oscarg/glpk-4.28/include/glpk.h --- glpk-4.28/include/glpk.h 2008-03-25 10:00:00.000000000 +0100 +++ /home/oscarg/glpk-4.28/include/glpk.h 2008-07-04 11:05:56.663634163 +0200 @@ -1215,7 +1215,7 @@ /* check if LP basis is available */ #define lpx_write_pb _glp_lpx_write_pb -int lpx_write_pb(LPX *lp, const char *fname, int normalized); +int lpx_write_pb(LPX *lp, const char *fname, int normalized, int binarize); /* write problem data in (normalized) OPB format */ #define lpx_main _glp_lpx_main diff -ur glpk-4.28/src/glplpx19.c /home/oscarg/glpk-4.28/src/glplpx19.c --- glpk-4.28/src/glplpx19.c 2008-03-25 10:00:00.000000000 +0100 +++ /home/oscarg/glpk-4.28/src/glplpx19.c 2008-07-04 11:52:53.005300380 +0200 @@ -26,6 +26,7 @@ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glpapi.h" +#include "glpipp.h" /*---------------------------------------------------------------------- -- lpx_write_pb - write problem data in (normalized) OPB format. @@ -33,7 +34,7 @@ -- *Synopsis* -- -- #include "glplpx.h" --- int lpx_write_pb(LPX *lp, const char *fname, int normalized); +-- int lpx_write_pb(LPX *lp, const char *fname, int normalized, int binarize); -- -- *Description* -- @@ -41,29 +42,45 @@ -- to an output text file whose name is the character string fname. -- If normalized is non-zero the output will be generated in a -- normalized form with sequentially numbered variables, x1, x2 etc. --- +-- If binarize, any integer variable will be repalzec by binary ones, +-- see ipp_binarize +-- -- *Returns* -- -- If the operation was successful, the routine returns zero. Otherwise -- the routine prints an error message and returns non-zero. */ -int lpx_write_pb(LPX *lp, const char *fname, int normalized) +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; - double coeff, *val, bound; - - 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++) + 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; + tlp=lp; + IPP *ipp = NULL; + + 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)) { @@ -81,49 +98,59 @@ } } } - fprintf(fp,"* #variables = %d #constraints = %d\n", n, nonfree); - /* Objective function */ - obj_dir = glp_get_obj_dir(lp); - fprintf(fp,"min: "); - for(i=1;i<=n;i++) + 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)); - - } + fprintf(fp, " %d*%s", (int)coeff, glp_get_col_name(lp,i)); + + } } - fprintf(fp,";\n"); - - if(normalized) /* Name substitution */ + 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++) + + 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; @@ -132,23 +159,36 @@ 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(val[i] != 0.0) { - + if(normalized) { fprintf(fp, "%d x%d ", -(row_type==GLP_UP)?(-(int)val[i]):((int)val[i]), ndx[i]); + (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])); + glp_get_col_name(lp,ndx[i])); } } } @@ -172,7 +212,7 @@ fprintf(fp, "<="); bound = glp_get_row_ub(lp,j); } - + break; } case GLP_FX: @@ -186,25 +226,56 @@ } } } - xfree(ndx); - xfree(val); - - } - 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); - return 0; - fail: if (fp != NULL) fclose(fp); - return 1; + 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 side 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; } /* eof */ diff -ur glpk-4.28/src/glplpx20.c /home/oscarg/glpk-4.28/src/glplpx20.c --- glpk-4.28/src/glplpx20.c 2008-03-25 10:00:00.000000000 +0100 +++ /home/oscarg/glpk-4.28/src/glplpx20.c 2008-07-04 11:06:15.633080723 +0200 @@ -948,7 +948,9 @@ } /* write problem in OPB format (if required) */ if (out_pb != NULL) - { ret = lpx_write_pb(lp, out_pb, 0); + { if(binarize) + xprintf("Unable to write binarized OPB without normalized names.\n"); + ret = lpx_write_pb(lp, out_pb, 0, 0); if (ret != 0) { xprintf("Unable to write problem in OPB format\n"); ret = EXIT_FAILURE; @@ -957,7 +959,7 @@ } /* write problem in normalized OPB format (if required) */ if (out_npb != NULL) - { ret = lpx_write_pb(lp, out_npb, 1); + { ret = lpx_write_pb(lp, out_npb, 1, binarize); if (ret != 0) { xprintf( "Unable to write problem in normalized OPB format\n");