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

Reply via email to