src/glpapi14.c
changeset 2 4c8956a7bdf4
equal deleted inserted replaced
-1:000000000000 0:5859ac4b2878
       
     1 /* glpapi14.c (processing models in GNU MathProg language) */
       
     2 
       
     3 /***********************************************************************
       
     4 *  This code is part of GLPK (GNU Linear Programming Kit).
       
     5 *
       
     6 *  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
       
     7 *  2009, 2010 Andrew Makhorin, Department for Applied Informatics,
       
     8 *  Moscow Aviation Institute, Moscow, Russia. All rights reserved.
       
     9 *  E-mail: <mao@gnu.org>.
       
    10 *
       
    11 *  GLPK is free software: you can redistribute it and/or modify it
       
    12 *  under the terms of the GNU General Public License as published by
       
    13 *  the Free Software Foundation, either version 3 of the License, or
       
    14 *  (at your option) any later version.
       
    15 *
       
    16 *  GLPK is distributed in the hope that it will be useful, but WITHOUT
       
    17 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
       
    18 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
       
    19 *  License for more details.
       
    20 *
       
    21 *  You should have received a copy of the GNU General Public License
       
    22 *  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
       
    23 ***********************************************************************/
       
    24 
       
    25 #define GLP_TRAN_DEFINED
       
    26 typedef struct MPL glp_tran;
       
    27 
       
    28 #include "glpmpl.h"
       
    29 #include "glpapi.h"
       
    30 
       
    31 glp_tran *glp_mpl_alloc_wksp(void)
       
    32 {     /* allocate the MathProg translator workspace */
       
    33       glp_tran *tran;
       
    34       tran = mpl_initialize();
       
    35       return tran;
       
    36 }
       
    37 
       
    38 #if 1 /* 08/XII-2009 */
       
    39 void _glp_mpl_init_rand(glp_tran *tran, int seed)
       
    40 {     if (tran->phase != 0)
       
    41          xerror("glp_mpl_init_rand: invalid call sequence\n");
       
    42       rng_init_rand(tran->rand, seed);
       
    43       return;
       
    44 }
       
    45 #endif
       
    46 
       
    47 int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip)
       
    48 {     /* read and translate model section */
       
    49       int ret;
       
    50       if (tran->phase != 0)
       
    51          xerror("glp_mpl_read_model: invalid call sequence\n");
       
    52       ret = mpl_read_model(tran, (char *)fname, skip);
       
    53       if (ret == 1 || ret == 2)
       
    54          ret = 0;
       
    55       else if (ret == 4)
       
    56          ret = 1;
       
    57       else
       
    58          xassert(ret != ret);
       
    59       return ret;
       
    60 }
       
    61 
       
    62 int glp_mpl_read_data(glp_tran *tran, const char *fname)
       
    63 {     /* read and translate data section */
       
    64       int ret;
       
    65       if (!(tran->phase == 1 || tran->phase == 2))
       
    66          xerror("glp_mpl_read_data: invalid call sequence\n");
       
    67       ret = mpl_read_data(tran, (char *)fname);
       
    68       if (ret == 2)
       
    69          ret = 0;
       
    70       else if (ret == 4)
       
    71          ret = 1;
       
    72       else
       
    73          xassert(ret != ret);
       
    74       return ret;
       
    75 }
       
    76 
       
    77 int glp_mpl_generate(glp_tran *tran, const char *fname)
       
    78 {     /* generate the model */
       
    79       int ret;
       
    80       if (!(tran->phase == 1 || tran->phase == 2))
       
    81          xerror("glp_mpl_generate: invalid call sequence\n");
       
    82       ret = mpl_generate(tran, (char *)fname);
       
    83       if (ret == 3)
       
    84          ret = 0;
       
    85       else if (ret == 4)
       
    86          ret = 1;
       
    87       return ret;
       
    88 }
       
    89 
       
    90 void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob)
       
    91 {     /* build LP/MIP problem instance from the model */
       
    92       int m, n, i, j, t, kind, type, len, *ind;
       
    93       double lb, ub, *val;
       
    94       if (tran->phase != 3)
       
    95          xerror("glp_mpl_build_prob: invalid call sequence\n");
       
    96       /* erase the problem object */
       
    97       glp_erase_prob(prob);
       
    98       /* set problem name */
       
    99       glp_set_prob_name(prob, mpl_get_prob_name(tran));
       
   100       /* build rows (constraints) */
       
   101       m = mpl_get_num_rows(tran);
       
   102       if (m > 0)
       
   103          glp_add_rows(prob, m);
       
   104       for (i = 1; i <= m; i++)
       
   105       {  /* set row name */
       
   106          glp_set_row_name(prob, i, mpl_get_row_name(tran, i));
       
   107          /* set row bounds */
       
   108          type = mpl_get_row_bnds(tran, i, &lb, &ub);
       
   109          switch (type)
       
   110          {  case MPL_FR: type = GLP_FR; break;
       
   111             case MPL_LO: type = GLP_LO; break;
       
   112             case MPL_UP: type = GLP_UP; break;
       
   113             case MPL_DB: type = GLP_DB; break;
       
   114             case MPL_FX: type = GLP_FX; break;
       
   115             default: xassert(type != type);
       
   116          }
       
   117          if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
       
   118          {  type = GLP_FX;
       
   119             if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
       
   120          }
       
   121          glp_set_row_bnds(prob, i, type, lb, ub);
       
   122          /* warn about non-zero constant term */
       
   123          if (mpl_get_row_c0(tran, i) != 0.0)
       
   124             xprintf("glp_mpl_build_prob: row %s; constant term %.12g ig"
       
   125                "nored\n",
       
   126                mpl_get_row_name(tran, i), mpl_get_row_c0(tran, i));
       
   127       }
       
   128       /* build columns (variables) */
       
   129       n = mpl_get_num_cols(tran);
       
   130       if (n > 0)
       
   131          glp_add_cols(prob, n);
       
   132       for (j = 1; j <= n; j++)
       
   133       {  /* set column name */
       
   134          glp_set_col_name(prob, j, mpl_get_col_name(tran, j));
       
   135          /* set column kind */
       
   136          kind = mpl_get_col_kind(tran, j);
       
   137          switch (kind)
       
   138          {  case MPL_NUM:
       
   139                break;
       
   140             case MPL_INT:
       
   141             case MPL_BIN:
       
   142                glp_set_col_kind(prob, j, GLP_IV);
       
   143                break;
       
   144             default:
       
   145                xassert(kind != kind);
       
   146          }
       
   147          /* set column bounds */
       
   148          type = mpl_get_col_bnds(tran, j, &lb, &ub);
       
   149          switch (type)
       
   150          {  case MPL_FR: type = GLP_FR; break;
       
   151             case MPL_LO: type = GLP_LO; break;
       
   152             case MPL_UP: type = GLP_UP; break;
       
   153             case MPL_DB: type = GLP_DB; break;
       
   154             case MPL_FX: type = GLP_FX; break;
       
   155             default: xassert(type != type);
       
   156          }
       
   157          if (kind == MPL_BIN)
       
   158          {  if (type == GLP_FR || type == GLP_UP || lb < 0.0) lb = 0.0;
       
   159             if (type == GLP_FR || type == GLP_LO || ub > 1.0) ub = 1.0;
       
   160             type = GLP_DB;
       
   161          }
       
   162          if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
       
   163          {  type = GLP_FX;
       
   164             if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
       
   165          }
       
   166          glp_set_col_bnds(prob, j, type, lb, ub);
       
   167       }
       
   168       /* load the constraint matrix */
       
   169       ind = xcalloc(1+n, sizeof(int));
       
   170       val = xcalloc(1+n, sizeof(double));
       
   171       for (i = 1; i <= m; i++)
       
   172       {  len = mpl_get_mat_row(tran, i, ind, val);
       
   173          glp_set_mat_row(prob, i, len, ind, val);
       
   174       }
       
   175       /* build objective function (the first objective is used) */
       
   176       for (i = 1; i <= m; i++)
       
   177       {  kind = mpl_get_row_kind(tran, i);
       
   178          if (kind == MPL_MIN || kind == MPL_MAX)
       
   179          {  /* set objective name */
       
   180             glp_set_obj_name(prob, mpl_get_row_name(tran, i));
       
   181             /* set optimization direction */
       
   182             glp_set_obj_dir(prob, kind == MPL_MIN ? GLP_MIN : GLP_MAX);
       
   183             /* set constant term */
       
   184             glp_set_obj_coef(prob, 0, mpl_get_row_c0(tran, i));
       
   185             /* set objective coefficients */
       
   186             len = mpl_get_mat_row(tran, i, ind, val);
       
   187             for (t = 1; t <= len; t++)
       
   188                glp_set_obj_coef(prob, ind[t], val[t]);
       
   189             break;
       
   190          }
       
   191       }
       
   192       /* free working arrays */
       
   193       xfree(ind);
       
   194       xfree(val);
       
   195       return;
       
   196 }
       
   197 
       
   198 int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol)
       
   199 {     /* postsolve the model */
       
   200       int i, j, m, n, stat, ret;
       
   201       double prim, dual;
       
   202       if (!(tran->phase == 3 && !tran->flag_p))
       
   203          xerror("glp_mpl_postsolve: invalid call sequence\n");
       
   204       if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP))
       
   205          xerror("glp_mpl_postsolve: sol = %d; invalid parameter\n",
       
   206             sol);
       
   207       m = mpl_get_num_rows(tran);
       
   208       n = mpl_get_num_cols(tran);
       
   209       if (!(m == glp_get_num_rows(prob) &&
       
   210             n == glp_get_num_cols(prob)))
       
   211          xerror("glp_mpl_postsolve: wrong problem object\n");
       
   212       if (!mpl_has_solve_stmt(tran))
       
   213       {  ret = 0;
       
   214          goto done;
       
   215       }
       
   216       for (i = 1; i <= m; i++)
       
   217       {  if (sol == GLP_SOL)
       
   218          {  stat = glp_get_row_stat(prob, i);
       
   219             prim = glp_get_row_prim(prob, i);
       
   220             dual = glp_get_row_dual(prob, i);
       
   221          }
       
   222          else if (sol == GLP_IPT)
       
   223          {  stat = 0;
       
   224             prim = glp_ipt_row_prim(prob, i);
       
   225             dual = glp_ipt_row_dual(prob, i);
       
   226          }
       
   227          else if (sol == GLP_MIP)
       
   228          {  stat = 0;
       
   229             prim = glp_mip_row_val(prob, i);
       
   230             dual = 0.0;
       
   231          }
       
   232          else
       
   233             xassert(sol != sol);
       
   234          if (fabs(prim) < 1e-9) prim = 0.0;
       
   235          if (fabs(dual) < 1e-9) dual = 0.0;
       
   236          mpl_put_row_soln(tran, i, stat, prim, dual);
       
   237       }
       
   238       for (j = 1; j <= n; j++)
       
   239       {  if (sol == GLP_SOL)
       
   240          {  stat = glp_get_col_stat(prob, j);
       
   241             prim = glp_get_col_prim(prob, j);
       
   242             dual = glp_get_col_dual(prob, j);
       
   243          }
       
   244          else if (sol == GLP_IPT)
       
   245          {  stat = 0;
       
   246             prim = glp_ipt_col_prim(prob, j);
       
   247             dual = glp_ipt_col_dual(prob, j);
       
   248          }
       
   249          else if (sol == GLP_MIP)
       
   250          {  stat = 0;
       
   251             prim = glp_mip_col_val(prob, j);
       
   252             dual = 0.0;
       
   253          }
       
   254          else
       
   255             xassert(sol != sol);
       
   256          if (fabs(prim) < 1e-9) prim = 0.0;
       
   257          if (fabs(dual) < 1e-9) dual = 0.0;
       
   258          mpl_put_col_soln(tran, j, stat, prim, dual);
       
   259       }
       
   260       ret = mpl_postsolve(tran);
       
   261       if (ret == 3)
       
   262          ret = 0;
       
   263       else if (ret == 4)
       
   264          ret = 1;
       
   265 done: return ret;
       
   266 }
       
   267 
       
   268 void glp_mpl_free_wksp(glp_tran *tran)
       
   269 {     /* free the MathProg translator workspace */
       
   270       mpl_terminate(tran);
       
   271       return;
       
   272 }
       
   273 
       
   274 /* eof */