Dear Andrew,
please find included fixes for the following two issues when exporting a
problem as an OPB-file:
* Constant objective function terms were ignored
* Empty LHS were ignored
Also, I've included an experimental version of binarizing integer
variables, which work with the normalized output format. Invoked by the
"--binarize" switch.
With best regards
Oscar Gustafsson
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");
_______________________________________________
Help-glpk mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-glpk